@riotprompt/riotprompt 0.0.21 → 1.0.1-dev.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 (69) hide show
  1. package/CHANGELOG.md +74 -0
  2. package/MIGRATION.md +235 -0
  3. package/README.md +2 -0
  4. package/SECURITY.md +132 -0
  5. package/dist/builder.js +6 -0
  6. package/dist/builder.js.map +1 -1
  7. package/dist/cli.js +481 -22
  8. package/dist/context-manager.js +1 -1
  9. package/dist/conversation-logger.d.ts +17 -1
  10. package/dist/conversation-logger.js +21 -17
  11. package/dist/conversation-logger.js.map +1 -1
  12. package/dist/conversation.js +1 -1
  13. package/dist/error-handling.d.ts +52 -0
  14. package/dist/error-handling.js +132 -0
  15. package/dist/error-handling.js.map +1 -0
  16. package/dist/formatter.js +1 -1
  17. package/dist/iteration-strategy.js +1 -1
  18. package/dist/loader.js +60 -12
  19. package/dist/loader.js.map +1 -1
  20. package/dist/logger.d.ts +52 -0
  21. package/dist/logger.js +114 -14
  22. package/dist/logger.js.map +1 -1
  23. package/dist/logging-config.d.ts +84 -0
  24. package/dist/logging-config.js +116 -0
  25. package/dist/logging-config.js.map +1 -0
  26. package/dist/message-builder.js +1 -1
  27. package/dist/model-config.js +1 -1
  28. package/dist/override.js +10 -4
  29. package/dist/override.js.map +1 -1
  30. package/dist/recipes.js +6 -0
  31. package/dist/recipes.js.map +1 -1
  32. package/dist/reflection.js +1 -1
  33. package/dist/riotprompt.d.ts +9 -0
  34. package/dist/riotprompt.js +8 -0
  35. package/dist/riotprompt.js.map +1 -1
  36. package/dist/security/audit-logger.d.ts +61 -0
  37. package/dist/security/audit-logger.js +281 -0
  38. package/dist/security/audit-logger.js.map +1 -0
  39. package/dist/security/cli-security.d.ts +143 -0
  40. package/dist/security/cli-security.js +302 -0
  41. package/dist/security/cli-security.js.map +1 -0
  42. package/dist/security/defaults.d.ts +31 -0
  43. package/dist/security/defaults.js +72 -0
  44. package/dist/security/defaults.js.map +1 -0
  45. package/dist/security/events.d.ts +8 -0
  46. package/dist/security/index.d.ts +27 -0
  47. package/dist/security/index.js +22 -0
  48. package/dist/security/index.js.map +1 -0
  49. package/dist/security/path-guard.d.ts +161 -0
  50. package/dist/security/path-guard.js +327 -0
  51. package/dist/security/path-guard.js.map +1 -0
  52. package/dist/security/rate-limiter.d.ts +117 -0
  53. package/dist/security/rate-limiter.js +165 -0
  54. package/dist/security/rate-limiter.js.map +1 -0
  55. package/dist/security/serialization-schemas.d.ts +183 -0
  56. package/dist/security/serialization-schemas.js +174 -0
  57. package/dist/security/serialization-schemas.js.map +1 -0
  58. package/dist/security/timeout-guard.d.ts +123 -0
  59. package/dist/security/timeout-guard.js +223 -0
  60. package/dist/security/timeout-guard.js.map +1 -0
  61. package/dist/security/types.d.ts +86 -0
  62. package/dist/security/types.js +80 -0
  63. package/dist/security/types.js.map +1 -0
  64. package/dist/token-budget.js +1 -1
  65. package/dist/tools.js +1 -1
  66. package/guide/index.md +2 -0
  67. package/guide/integration.md +1109 -0
  68. package/guide/security.md +237 -0
  69. package/package.json +18 -11
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Security module for RiotPrompt
3
+ *
4
+ * Provides security configuration, types, and utilities for:
5
+ * - Path validation and traversal prevention
6
+ * - Tool execution sandboxing
7
+ * - Secret redaction
8
+ * - Secure logging
9
+ * - Request timeouts
10
+ *
11
+ * @packageDocumentation
12
+ */
13
+ export { PathSecurityConfigSchema, ToolSecurityConfigSchema, SecretSecurityConfigSchema, LogSecurityConfigSchema, TimeoutConfigSchema, SecurityConfigSchema, } from './types';
14
+ export type { PathSecurityConfig, ToolSecurityConfig, SecretSecurityConfig, LogSecurityConfig, TimeoutConfig, SecurityConfig, } from './types';
15
+ export { SECURE_DEFAULTS, PERMISSIVE_DEFAULTS, mergeSecurityConfig, } from './defaults';
16
+ export type { SecurityEventType, SecurityEvent, } from './events';
17
+ export { SecurityAuditLogger, getAuditLogger, configureAuditLogger, resetAuditLogger, } from './audit-logger';
18
+ export type { AuditLoggerConfig, } from './audit-logger';
19
+ export { PathGuard, getPathGuard, configurePathGuard, resetPathGuard, sanitizeGlobPattern, isGlobSafe, validateGlobPattern, } from './path-guard';
20
+ export type { PathValidationResult, GlobValidationResult, } from './path-guard';
21
+ export { CLIValidator, getCLIValidator, configureCLIValidator, resetCLIValidator, createRiotPromptValidator, DEFAULT_CLI_SECURITY, } from './cli-security';
22
+ export type { CLISecurityConfig, StringValidationResult, } from './cli-security';
23
+ export { TimeoutGuard, TimeoutError, isTimeoutError, getTimeoutGuard, configureTimeoutGuard, resetTimeoutGuard, } from './timeout-guard';
24
+ export { SCHEMA_VERSION, SERIALIZATION_LIMITS, ToolCallSchema, ConversationMessageSchema, ConversationMetadataSchema, SerializedConversationSchema, SerializedPromptSchema, LoggedConversationSchema, validateConversation, validateLoggedConversation, safeJsonParse, } from './serialization-schemas';
25
+ export type { SerializedConversation, SerializedPrompt, LoggedConversation as SerializedLoggedConversation, } from './serialization-schemas';
26
+ export { NoOpRateLimiter, MemoryRateLimiter, createRateLimiter, createNoOpRateLimiter, getRateLimiter, configureRateLimiter, resetRateLimiter, } from './rate-limiter';
27
+ export type { RateLimiter, RateLimiterConfig, } from './rate-limiter';
@@ -0,0 +1,22 @@
1
+ export { LogSecurityConfigSchema, PathSecurityConfigSchema, SecretSecurityConfigSchema, SecurityConfigSchema, TimeoutConfigSchema, ToolSecurityConfigSchema } from './types.js';
2
+ export { PERMISSIVE_DEFAULTS, SECURE_DEFAULTS, mergeSecurityConfig } from './defaults.js';
3
+ export { SecurityAuditLogger, configureAuditLogger, getAuditLogger, resetAuditLogger } from './audit-logger.js';
4
+ export { PathGuard, configurePathGuard, getPathGuard, isGlobSafe, resetPathGuard, sanitizeGlobPattern, validateGlobPattern } from './path-guard.js';
5
+ export { CLIValidator, DEFAULT_CLI_SECURITY, configureCLIValidator, createRiotPromptValidator, getCLIValidator, resetCLIValidator } from './cli-security.js';
6
+ export { TimeoutError, TimeoutGuard, configureTimeoutGuard, getTimeoutGuard, isTimeoutError, resetTimeoutGuard } from './timeout-guard.js';
7
+ export { ConversationMessageSchema, ConversationMetadataSchema, LoggedConversationSchema, SCHEMA_VERSION, SERIALIZATION_LIMITS, SerializedConversationSchema, SerializedPromptSchema, ToolCallSchema, safeJsonParse, validateConversation, validateLoggedConversation } from './serialization-schemas.js';
8
+ export { MemoryRateLimiter, NoOpRateLimiter, configureRateLimiter, createNoOpRateLimiter, createRateLimiter, getRateLimiter, resetRateLimiter } from './rate-limiter.js';
9
+
10
+ /**
11
+ * Security module for RiotPrompt
12
+ *
13
+ * Provides security configuration, types, and utilities for:
14
+ * - Path validation and traversal prevention
15
+ * - Tool execution sandboxing
16
+ * - Secret redaction
17
+ * - Secure logging
18
+ * - Request timeouts
19
+ *
20
+ * @packageDocumentation
21
+ */ // Types and schemas
22
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../../src/security/index.ts"],"sourcesContent":["/**\n * Security module for RiotPrompt\n * \n * Provides security configuration, types, and utilities for:\n * - Path validation and traversal prevention\n * - Tool execution sandboxing\n * - Secret redaction\n * - Secure logging\n * - Request timeouts\n * \n * @packageDocumentation\n */\n\n// Types and schemas\nexport {\n PathSecurityConfigSchema,\n ToolSecurityConfigSchema,\n SecretSecurityConfigSchema,\n LogSecurityConfigSchema,\n TimeoutConfigSchema,\n SecurityConfigSchema,\n} from './types';\n\nexport type {\n PathSecurityConfig,\n ToolSecurityConfig,\n SecretSecurityConfig,\n LogSecurityConfig,\n TimeoutConfig,\n SecurityConfig,\n} from './types';\n\n// Default configurations\nexport {\n SECURE_DEFAULTS,\n PERMISSIVE_DEFAULTS,\n mergeSecurityConfig,\n} from './defaults';\n\n// Security events\nexport type {\n SecurityEventType,\n SecurityEvent,\n} from './events';\n\n// Audit logging\nexport {\n SecurityAuditLogger,\n getAuditLogger,\n configureAuditLogger,\n resetAuditLogger,\n} from './audit-logger';\n\nexport type {\n AuditLoggerConfig,\n} from './audit-logger';\n\n// Path security\nexport {\n PathGuard,\n getPathGuard,\n configurePathGuard,\n resetPathGuard,\n // Glob pattern utilities\n sanitizeGlobPattern,\n isGlobSafe,\n validateGlobPattern,\n} from './path-guard';\n\nexport type {\n PathValidationResult,\n GlobValidationResult,\n} from './path-guard';\n\n// CLI security\nexport {\n CLIValidator,\n getCLIValidator,\n configureCLIValidator,\n resetCLIValidator,\n createRiotPromptValidator,\n DEFAULT_CLI_SECURITY,\n} from './cli-security';\n\nexport type {\n CLISecurityConfig,\n StringValidationResult,\n} from './cli-security';\n\n// Timeout protection\nexport {\n TimeoutGuard,\n TimeoutError,\n isTimeoutError,\n getTimeoutGuard,\n configureTimeoutGuard,\n resetTimeoutGuard,\n} from './timeout-guard';\n\n// Serialization security\nexport {\n SCHEMA_VERSION,\n SERIALIZATION_LIMITS,\n ToolCallSchema,\n ConversationMessageSchema,\n ConversationMetadataSchema,\n SerializedConversationSchema,\n SerializedPromptSchema,\n LoggedConversationSchema,\n validateConversation,\n validateLoggedConversation,\n safeJsonParse,\n} from './serialization-schemas';\n\nexport type {\n SerializedConversation,\n SerializedPrompt,\n LoggedConversation as SerializedLoggedConversation,\n} from './serialization-schemas';\n\n// Rate limiting\nexport {\n NoOpRateLimiter,\n MemoryRateLimiter,\n createRateLimiter,\n createNoOpRateLimiter,\n getRateLimiter,\n configureRateLimiter,\n resetRateLimiter,\n} from './rate-limiter';\n\nexport type {\n RateLimiter,\n RateLimiterConfig,\n} from './rate-limiter';\n"],"names":[],"mappings":";;;;;;;;;AAAA;;;;;;;;;;;AAWC"}
@@ -0,0 +1,161 @@
1
+ import { PathSecurityConfig } from './types';
2
+ import { SecurityAuditLogger } from './audit-logger';
3
+ export type { PathSecurityConfig };
4
+ /**
5
+ * Result of path validation
6
+ */
7
+ export interface PathValidationResult {
8
+ valid: boolean;
9
+ normalizedPath?: string;
10
+ error?: string;
11
+ violation?: string;
12
+ }
13
+ /**
14
+ * PathGuard provides security validation for file paths.
15
+ *
16
+ * Features:
17
+ * - Directory traversal prevention
18
+ * - Base path restriction
19
+ * - Pattern-based blocking
20
+ * - Null byte detection
21
+ * - Audit logging
22
+ *
23
+ * @example
24
+ * ```typescript
25
+ * const guard = new PathGuard({ basePaths: ['/app/data'] });
26
+ *
27
+ * const result = guard.validate('../../../etc/passwd');
28
+ * // { valid: false, error: 'Path contains forbidden pattern' }
29
+ *
30
+ * const safePath = guard.validateOrThrow('subdir/file.txt');
31
+ * // '/app/data/subdir/file.txt'
32
+ * ```
33
+ */
34
+ export declare class PathGuard {
35
+ private config;
36
+ private auditLogger;
37
+ private basePaths;
38
+ constructor(config?: Partial<PathSecurityConfig>, auditLogger?: SecurityAuditLogger);
39
+ /**
40
+ * Validate and normalize a file path
41
+ *
42
+ * @param inputPath - The path to validate
43
+ * @param operation - The operation being performed (for audit logging)
44
+ * @returns Validation result with normalized path if valid
45
+ */
46
+ validate(inputPath: string, _operation?: string): PathValidationResult;
47
+ /**
48
+ * Validate and return the path, throwing on failure
49
+ *
50
+ * @param inputPath - The path to validate
51
+ * @param operation - The operation being performed
52
+ * @returns The normalized path
53
+ * @throws Error if validation fails
54
+ */
55
+ validateOrThrow(inputPath: string, operation?: string): string;
56
+ /**
57
+ * Add a base path at runtime
58
+ *
59
+ * @param basePath - The base path to add
60
+ */
61
+ addBasePath(basePath: string): void;
62
+ /**
63
+ * Remove a base path
64
+ *
65
+ * @param basePath - The base path to remove
66
+ */
67
+ removeBasePath(basePath: string): void;
68
+ /**
69
+ * Check if a path is within allowed directories
70
+ *
71
+ * @param testPath - The path to check
72
+ * @returns True if the path is within allowed directories
73
+ */
74
+ isWithinAllowed(testPath: string): boolean;
75
+ /**
76
+ * Get the first base path (for relative resolution)
77
+ *
78
+ * @returns The first base path or undefined
79
+ */
80
+ getBasePath(): string | undefined;
81
+ /**
82
+ * Get all configured base paths
83
+ *
84
+ * @returns Array of base paths
85
+ */
86
+ getBasePaths(): string[];
87
+ /**
88
+ * Check if path validation is enabled
89
+ *
90
+ * @returns True if enabled
91
+ */
92
+ isEnabled(): boolean;
93
+ /**
94
+ * Enable or disable path validation
95
+ *
96
+ * @param enabled - Whether to enable validation
97
+ */
98
+ setEnabled(enabled: boolean): void;
99
+ }
100
+ /**
101
+ * Get the global PathGuard instance
102
+ *
103
+ * @returns The global PathGuard
104
+ */
105
+ export declare function getPathGuard(): PathGuard;
106
+ /**
107
+ * Configure the global PathGuard
108
+ *
109
+ * @param config - Configuration options
110
+ */
111
+ export declare function configurePathGuard(config: Partial<PathSecurityConfig>): void;
112
+ /**
113
+ * Reset the global PathGuard to default
114
+ */
115
+ export declare function resetPathGuard(): void;
116
+ /**
117
+ * Sanitize a glob pattern by removing potentially dangerous sequences
118
+ *
119
+ * @param pattern - The glob pattern to sanitize
120
+ * @returns Sanitized glob pattern
121
+ *
122
+ * @example
123
+ * ```typescript
124
+ * sanitizeGlobPattern('../../../etc/*') // Returns 'etc/*'
125
+ * sanitizeGlobPattern('/absolute/path/*') // Returns 'absolute/path/*'
126
+ * sanitizeGlobPattern('~/secrets/*') // Returns 'secrets/*'
127
+ * ```
128
+ */
129
+ export declare function sanitizeGlobPattern(pattern: string): string;
130
+ /**
131
+ * Check if a glob pattern is safe to use
132
+ *
133
+ * @param pattern - The glob pattern to check
134
+ * @returns true if safe, false if potentially dangerous
135
+ *
136
+ * @example
137
+ * ```typescript
138
+ * isGlobSafe('src/**\/*.ts') // true
139
+ * isGlobSafe('../../../etc/passwd') // false
140
+ * isGlobSafe('/etc/*') // false
141
+ * ```
142
+ */
143
+ export declare function isGlobSafe(pattern: string): boolean;
144
+ /**
145
+ * Result of glob pattern validation
146
+ */
147
+ export interface GlobValidationResult {
148
+ safe: boolean;
149
+ sanitized?: string;
150
+ warnings: string[];
151
+ }
152
+ /**
153
+ * Validate and optionally sanitize a glob pattern
154
+ *
155
+ * @param pattern - The glob pattern to validate
156
+ * @param options - Validation options
157
+ * @returns Validation result with sanitized pattern if requested
158
+ */
159
+ export declare function validateGlobPattern(pattern: string, options?: {
160
+ sanitize?: boolean;
161
+ }): GlobValidationResult;
@@ -0,0 +1,327 @@
1
+ import path__default from 'path';
2
+ import { getAuditLogger } from './audit-logger.js';
3
+
4
+ function _define_property(obj, key, value) {
5
+ if (key in obj) {
6
+ Object.defineProperty(obj, key, {
7
+ value: value,
8
+ enumerable: true,
9
+ configurable: true,
10
+ writable: true
11
+ });
12
+ } else {
13
+ obj[key] = value;
14
+ }
15
+ return obj;
16
+ }
17
+ /**
18
+ * PathGuard provides security validation for file paths.
19
+ *
20
+ * Features:
21
+ * - Directory traversal prevention
22
+ * - Base path restriction
23
+ * - Pattern-based blocking
24
+ * - Null byte detection
25
+ * - Audit logging
26
+ *
27
+ * @example
28
+ * ```typescript
29
+ * const guard = new PathGuard({ basePaths: ['/app/data'] });
30
+ *
31
+ * const result = guard.validate('../../../etc/passwd');
32
+ * // { valid: false, error: 'Path contains forbidden pattern' }
33
+ *
34
+ * const safePath = guard.validateOrThrow('subdir/file.txt');
35
+ * // '/app/data/subdir/file.txt'
36
+ * ```
37
+ */ class PathGuard {
38
+ /**
39
+ * Validate and normalize a file path
40
+ *
41
+ * @param inputPath - The path to validate
42
+ * @param operation - The operation being performed (for audit logging)
43
+ * @returns Validation result with normalized path if valid
44
+ */ validate(inputPath, _operation = 'access') {
45
+ if (!this.config.enabled) {
46
+ return {
47
+ valid: true,
48
+ normalizedPath: inputPath
49
+ };
50
+ }
51
+ // Check for null bytes (path truncation attack)
52
+ if (inputPath.includes('\0')) {
53
+ this.auditLogger.pathTraversalBlocked(inputPath, 'Null byte detected');
54
+ return {
55
+ valid: false,
56
+ error: 'Path contains invalid characters',
57
+ violation: 'null_byte'
58
+ };
59
+ }
60
+ // Check for denied patterns
61
+ for (const pattern of this.config.denyPatterns){
62
+ try {
63
+ const regex = new RegExp(pattern, 'i');
64
+ if (regex.test(inputPath)) {
65
+ this.auditLogger.pathTraversalBlocked(inputPath, `Matched deny pattern: ${pattern}`);
66
+ return {
67
+ valid: false,
68
+ error: 'Path contains forbidden pattern',
69
+ violation: pattern
70
+ };
71
+ }
72
+ } catch {
73
+ // Invalid regex pattern, skip
74
+ }
75
+ }
76
+ // Check absolute path handling
77
+ const isAbsolute = path__default.isAbsolute(inputPath);
78
+ if (isAbsolute && !this.config.allowAbsolute) {
79
+ this.auditLogger.pathTraversalBlocked(inputPath, 'Absolute paths not allowed');
80
+ return {
81
+ valid: false,
82
+ error: 'Absolute paths are not allowed',
83
+ violation: 'absolute_path'
84
+ };
85
+ }
86
+ // Normalize the path
87
+ let normalizedPath;
88
+ try {
89
+ if (isAbsolute) {
90
+ normalizedPath = path__default.normalize(inputPath);
91
+ } else if (this.basePaths.length > 0) {
92
+ // Resolve relative to first base path
93
+ normalizedPath = path__default.resolve(this.basePaths[0], inputPath);
94
+ } else {
95
+ normalizedPath = path__default.resolve(inputPath);
96
+ }
97
+ } catch {
98
+ return {
99
+ valid: false,
100
+ error: 'Invalid path format'
101
+ };
102
+ }
103
+ // Verify path is within allowed base paths
104
+ if (this.basePaths.length > 0) {
105
+ const isWithinBase = this.basePaths.some((basePath)=>normalizedPath.startsWith(basePath + path__default.sep) || normalizedPath === basePath);
106
+ if (!isWithinBase) {
107
+ this.auditLogger.pathTraversalBlocked(inputPath, 'Path escapes allowed directories');
108
+ return {
109
+ valid: false,
110
+ error: 'Path is outside allowed directories',
111
+ violation: 'directory_escape'
112
+ };
113
+ }
114
+ }
115
+ // Check for path traversal after normalization
116
+ // Only check if the path is NOT within any allowed base path
117
+ // (the isWithinBase check above already handles this for absolute paths)
118
+ return {
119
+ valid: true,
120
+ normalizedPath
121
+ };
122
+ }
123
+ /**
124
+ * Validate and return the path, throwing on failure
125
+ *
126
+ * @param inputPath - The path to validate
127
+ * @param operation - The operation being performed
128
+ * @returns The normalized path
129
+ * @throws Error if validation fails
130
+ */ validateOrThrow(inputPath, operation = 'access') {
131
+ const result = this.validate(inputPath, operation);
132
+ if (!result.valid) {
133
+ throw new Error(`Path validation failed: ${result.error}`);
134
+ }
135
+ return result.normalizedPath;
136
+ }
137
+ /**
138
+ * Add a base path at runtime
139
+ *
140
+ * @param basePath - The base path to add
141
+ */ addBasePath(basePath) {
142
+ const normalized = path__default.resolve(basePath);
143
+ if (!this.basePaths.includes(normalized)) {
144
+ this.basePaths.push(normalized);
145
+ }
146
+ }
147
+ /**
148
+ * Remove a base path
149
+ *
150
+ * @param basePath - The base path to remove
151
+ */ removeBasePath(basePath) {
152
+ const normalized = path__default.resolve(basePath);
153
+ const index = this.basePaths.indexOf(normalized);
154
+ if (index !== -1) {
155
+ this.basePaths.splice(index, 1);
156
+ }
157
+ }
158
+ /**
159
+ * Check if a path is within allowed directories
160
+ *
161
+ * @param testPath - The path to check
162
+ * @returns True if the path is within allowed directories
163
+ */ isWithinAllowed(testPath) {
164
+ if (this.basePaths.length === 0) return true;
165
+ const normalizedTest = path__default.resolve(testPath);
166
+ return this.basePaths.some((basePath)=>normalizedTest.startsWith(basePath + path__default.sep) || normalizedTest === basePath);
167
+ }
168
+ /**
169
+ * Get the first base path (for relative resolution)
170
+ *
171
+ * @returns The first base path or undefined
172
+ */ getBasePath() {
173
+ return this.basePaths[0];
174
+ }
175
+ /**
176
+ * Get all configured base paths
177
+ *
178
+ * @returns Array of base paths
179
+ */ getBasePaths() {
180
+ return [
181
+ ...this.basePaths
182
+ ];
183
+ }
184
+ /**
185
+ * Check if path validation is enabled
186
+ *
187
+ * @returns True if enabled
188
+ */ isEnabled() {
189
+ return this.config.enabled;
190
+ }
191
+ /**
192
+ * Enable or disable path validation
193
+ *
194
+ * @param enabled - Whether to enable validation
195
+ */ setEnabled(enabled) {
196
+ this.config.enabled = enabled;
197
+ }
198
+ constructor(config = {}, auditLogger){
199
+ _define_property(this, "config", void 0);
200
+ _define_property(this, "auditLogger", void 0);
201
+ _define_property(this, "basePaths", void 0);
202
+ this.config = {
203
+ enabled: true,
204
+ basePaths: [],
205
+ allowAbsolute: false,
206
+ allowSymlinks: false,
207
+ denyPatterns: [
208
+ '\\.\\.',
209
+ '~',
210
+ '\\$\\{',
211
+ '\\$\\('
212
+ ],
213
+ ...config
214
+ };
215
+ // Normalize base paths
216
+ this.basePaths = this.config.basePaths.map((p)=>path__default.resolve(p));
217
+ this.auditLogger = auditLogger || getAuditLogger();
218
+ }
219
+ }
220
+ // Global instance
221
+ let globalPathGuard = null;
222
+ /**
223
+ * Get the global PathGuard instance
224
+ *
225
+ * @returns The global PathGuard
226
+ */ function getPathGuard() {
227
+ if (!globalPathGuard) {
228
+ globalPathGuard = new PathGuard();
229
+ }
230
+ return globalPathGuard;
231
+ }
232
+ /**
233
+ * Configure the global PathGuard
234
+ *
235
+ * @param config - Configuration options
236
+ */ function configurePathGuard(config) {
237
+ globalPathGuard = new PathGuard(config);
238
+ }
239
+ /**
240
+ * Reset the global PathGuard to default
241
+ */ function resetPathGuard() {
242
+ globalPathGuard = null;
243
+ }
244
+ // ===== GLOB PATTERN SANITIZATION =====
245
+ /**
246
+ * Dangerous patterns that should not appear in glob patterns
247
+ */ const DANGEROUS_GLOB_PATTERNS = [
248
+ /\.\.\//,
249
+ /\.\.\\/,
250
+ /^\//,
251
+ /^[a-zA-Z]:/,
252
+ /^~/,
253
+ /\$\{/,
254
+ /\$\(/,
255
+ /`/
256
+ ];
257
+ /**
258
+ * Sanitize a glob pattern by removing potentially dangerous sequences
259
+ *
260
+ * @param pattern - The glob pattern to sanitize
261
+ * @returns Sanitized glob pattern
262
+ *
263
+ * @example
264
+ * ```typescript
265
+ * sanitizeGlobPattern('../../../etc/*') // Returns 'etc/*'
266
+ * sanitizeGlobPattern('/absolute/path/*') // Returns 'absolute/path/*'
267
+ * sanitizeGlobPattern('~/secrets/*') // Returns 'secrets/*'
268
+ * ```
269
+ */ function sanitizeGlobPattern(pattern) {
270
+ let safe = pattern// Remove parent directory references
271
+ .replace(/\.\.\//g, '').replace(/\.\.\\/g, '')// Remove absolute path starters
272
+ .replace(/^\/+/, '').replace(/^[a-zA-Z]:[\\/]?/, '')// Remove home directory references
273
+ .replace(/^~[\\/]?/, '')// Remove variable expansion
274
+ .replace(/\$\{[^}]*\}/g, '')// Remove command substitution
275
+ .replace(/\$\([^)]*\)/g, '').replace(/`[^`]*`/g, '');
276
+ // Remove any remaining dangerous characters at the start
277
+ while(safe.startsWith('/') || safe.startsWith('\\')){
278
+ safe = safe.substring(1);
279
+ }
280
+ return safe;
281
+ }
282
+ /**
283
+ * Check if a glob pattern is safe to use
284
+ *
285
+ * @param pattern - The glob pattern to check
286
+ * @returns true if safe, false if potentially dangerous
287
+ *
288
+ * @example
289
+ * ```typescript
290
+ * isGlobSafe('src/**\/*.ts') // true
291
+ * isGlobSafe('../../../etc/passwd') // false
292
+ * isGlobSafe('/etc/*') // false
293
+ * ```
294
+ */ function isGlobSafe(pattern) {
295
+ return !DANGEROUS_GLOB_PATTERNS.some((re)=>re.test(pattern));
296
+ }
297
+ /**
298
+ * Validate and optionally sanitize a glob pattern
299
+ *
300
+ * @param pattern - The glob pattern to validate
301
+ * @param options - Validation options
302
+ * @returns Validation result with sanitized pattern if requested
303
+ */ function validateGlobPattern(pattern, options = {}) {
304
+ const warnings = [];
305
+ // Check for dangerous patterns
306
+ for (const dangerousPattern of DANGEROUS_GLOB_PATTERNS){
307
+ if (dangerousPattern.test(pattern)) {
308
+ warnings.push(`Pattern contains potentially dangerous sequence: ${dangerousPattern.source}`);
309
+ }
310
+ }
311
+ const safe = warnings.length === 0;
312
+ if (options.sanitize && !safe) {
313
+ return {
314
+ safe: false,
315
+ sanitized: sanitizeGlobPattern(pattern),
316
+ warnings
317
+ };
318
+ }
319
+ return {
320
+ safe,
321
+ sanitized: safe ? pattern : undefined,
322
+ warnings
323
+ };
324
+ }
325
+
326
+ export { PathGuard, configurePathGuard, getPathGuard, isGlobSafe, resetPathGuard, sanitizeGlobPattern, validateGlobPattern };
327
+ //# sourceMappingURL=path-guard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path-guard.js","sources":["../../src/security/path-guard.ts"],"sourcesContent":["/**\n * RiotPrompt - Path Security Guard\n *\n * Implements path validation to prevent directory traversal attacks\n * in file operations.\n */\n\nimport path from 'path';\nimport { PathSecurityConfig } from './types';\nimport { getAuditLogger, SecurityAuditLogger } from './audit-logger';\n\n// Re-export PathSecurityConfig for external use\nexport type { PathSecurityConfig };\n\n/**\n * Result of path validation\n */\nexport interface PathValidationResult {\n valid: boolean;\n normalizedPath?: string;\n error?: string;\n violation?: string;\n}\n\n/**\n * PathGuard provides security validation for file paths.\n *\n * Features:\n * - Directory traversal prevention\n * - Base path restriction\n * - Pattern-based blocking\n * - Null byte detection\n * - Audit logging\n *\n * @example\n * ```typescript\n * const guard = new PathGuard({ basePaths: ['/app/data'] });\n *\n * const result = guard.validate('../../../etc/passwd');\n * // { valid: false, error: 'Path contains forbidden pattern' }\n *\n * const safePath = guard.validateOrThrow('subdir/file.txt');\n * // '/app/data/subdir/file.txt'\n * ```\n */\nexport class PathGuard {\n private config: PathSecurityConfig;\n private auditLogger: SecurityAuditLogger;\n private basePaths: string[];\n\n constructor(config: Partial<PathSecurityConfig> = {}, auditLogger?: SecurityAuditLogger) {\n this.config = {\n enabled: true,\n basePaths: [],\n allowAbsolute: false,\n allowSymlinks: false,\n denyPatterns: [\n '\\\\.\\\\.', // Parent directory\n '~', // Home directory expansion\n '\\\\$\\\\{', // Variable expansion\n '\\\\$\\\\(', // Command substitution\n ],\n ...config,\n };\n\n // Normalize base paths\n this.basePaths = this.config.basePaths.map(p => path.resolve(p));\n this.auditLogger = auditLogger || getAuditLogger();\n }\n\n /**\n * Validate and normalize a file path\n *\n * @param inputPath - The path to validate\n * @param operation - The operation being performed (for audit logging)\n * @returns Validation result with normalized path if valid\n */\n validate(inputPath: string, _operation: string = 'access'): PathValidationResult {\n if (!this.config.enabled) {\n return { valid: true, normalizedPath: inputPath };\n }\n\n // Check for null bytes (path truncation attack)\n if (inputPath.includes('\\0')) {\n this.auditLogger.pathTraversalBlocked(inputPath, 'Null byte detected');\n return {\n valid: false,\n error: 'Path contains invalid characters',\n violation: 'null_byte',\n };\n }\n\n // Check for denied patterns\n for (const pattern of this.config.denyPatterns) {\n try {\n const regex = new RegExp(pattern, 'i');\n if (regex.test(inputPath)) {\n this.auditLogger.pathTraversalBlocked(inputPath, `Matched deny pattern: ${pattern}`);\n return {\n valid: false,\n error: 'Path contains forbidden pattern',\n violation: pattern,\n };\n }\n } catch {\n // Invalid regex pattern, skip\n }\n }\n\n // Check absolute path handling\n const isAbsolute = path.isAbsolute(inputPath);\n if (isAbsolute && !this.config.allowAbsolute) {\n this.auditLogger.pathTraversalBlocked(inputPath, 'Absolute paths not allowed');\n return {\n valid: false,\n error: 'Absolute paths are not allowed',\n violation: 'absolute_path',\n };\n }\n\n // Normalize the path\n let normalizedPath: string;\n try {\n if (isAbsolute) {\n normalizedPath = path.normalize(inputPath);\n } else if (this.basePaths.length > 0) {\n // Resolve relative to first base path\n normalizedPath = path.resolve(this.basePaths[0], inputPath);\n } else {\n normalizedPath = path.resolve(inputPath);\n }\n } catch {\n return {\n valid: false,\n error: 'Invalid path format',\n };\n }\n\n // Verify path is within allowed base paths\n if (this.basePaths.length > 0) {\n const isWithinBase = this.basePaths.some(basePath =>\n normalizedPath.startsWith(basePath + path.sep) || normalizedPath === basePath\n );\n\n if (!isWithinBase) {\n this.auditLogger.pathTraversalBlocked(inputPath, 'Path escapes allowed directories');\n return {\n valid: false,\n error: 'Path is outside allowed directories',\n violation: 'directory_escape',\n };\n }\n }\n\n // Check for path traversal after normalization\n // Only check if the path is NOT within any allowed base path\n // (the isWithinBase check above already handles this for absolute paths)\n\n return {\n valid: true,\n normalizedPath,\n };\n }\n\n /**\n * Validate and return the path, throwing on failure\n *\n * @param inputPath - The path to validate\n * @param operation - The operation being performed\n * @returns The normalized path\n * @throws Error if validation fails\n */\n validateOrThrow(inputPath: string, operation: string = 'access'): string {\n const result = this.validate(inputPath, operation);\n if (!result.valid) {\n throw new Error(`Path validation failed: ${result.error}`);\n }\n return result.normalizedPath!;\n }\n\n /**\n * Add a base path at runtime\n *\n * @param basePath - The base path to add\n */\n addBasePath(basePath: string): void {\n const normalized = path.resolve(basePath);\n if (!this.basePaths.includes(normalized)) {\n this.basePaths.push(normalized);\n }\n }\n\n /**\n * Remove a base path\n *\n * @param basePath - The base path to remove\n */\n removeBasePath(basePath: string): void {\n const normalized = path.resolve(basePath);\n const index = this.basePaths.indexOf(normalized);\n if (index !== -1) {\n this.basePaths.splice(index, 1);\n }\n }\n\n /**\n * Check if a path is within allowed directories\n *\n * @param testPath - The path to check\n * @returns True if the path is within allowed directories\n */\n isWithinAllowed(testPath: string): boolean {\n if (this.basePaths.length === 0) return true;\n\n const normalizedTest = path.resolve(testPath);\n return this.basePaths.some(basePath =>\n normalizedTest.startsWith(basePath + path.sep) || normalizedTest === basePath\n );\n }\n\n /**\n * Get the first base path (for relative resolution)\n *\n * @returns The first base path or undefined\n */\n getBasePath(): string | undefined {\n return this.basePaths[0];\n }\n\n /**\n * Get all configured base paths\n *\n * @returns Array of base paths\n */\n getBasePaths(): string[] {\n return [...this.basePaths];\n }\n\n /**\n * Check if path validation is enabled\n *\n * @returns True if enabled\n */\n isEnabled(): boolean {\n return this.config.enabled;\n }\n\n /**\n * Enable or disable path validation\n *\n * @param enabled - Whether to enable validation\n */\n setEnabled(enabled: boolean): void {\n this.config.enabled = enabled;\n }\n}\n\n// Global instance\nlet globalPathGuard: PathGuard | null = null;\n\n/**\n * Get the global PathGuard instance\n *\n * @returns The global PathGuard\n */\nexport function getPathGuard(): PathGuard {\n if (!globalPathGuard) {\n globalPathGuard = new PathGuard();\n }\n return globalPathGuard;\n}\n\n/**\n * Configure the global PathGuard\n *\n * @param config - Configuration options\n */\nexport function configurePathGuard(config: Partial<PathSecurityConfig>): void {\n globalPathGuard = new PathGuard(config);\n}\n\n/**\n * Reset the global PathGuard to default\n */\nexport function resetPathGuard(): void {\n globalPathGuard = null;\n}\n\n// ===== GLOB PATTERN SANITIZATION =====\n\n/**\n * Dangerous patterns that should not appear in glob patterns\n */\nconst DANGEROUS_GLOB_PATTERNS = [\n /\\.\\.\\//, // Parent directory traversal\n /\\.\\.\\\\/, // Windows parent directory\n /^\\//, // Absolute path (Unix)\n /^[a-zA-Z]:/, // Absolute path (Windows)\n /^~/, // Home directory\n /\\$\\{/, // Variable expansion\n /\\$\\(/, // Command substitution\n /`/, // Backtick command substitution\n];\n\n/**\n * Sanitize a glob pattern by removing potentially dangerous sequences\n * \n * @param pattern - The glob pattern to sanitize\n * @returns Sanitized glob pattern\n * \n * @example\n * ```typescript\n * sanitizeGlobPattern('../../../etc/*') // Returns 'etc/*'\n * sanitizeGlobPattern('/absolute/path/*') // Returns 'absolute/path/*'\n * sanitizeGlobPattern('~/secrets/*') // Returns 'secrets/*'\n * ```\n */\nexport function sanitizeGlobPattern(pattern: string): string {\n let safe = pattern\n // Remove parent directory references\n .replace(/\\.\\.\\//g, '')\n .replace(/\\.\\.\\\\/g, '')\n // Remove absolute path starters\n .replace(/^\\/+/, '')\n .replace(/^[a-zA-Z]:[\\\\/]?/, '')\n // Remove home directory references\n .replace(/^~[\\\\/]?/, '')\n // Remove variable expansion\n .replace(/\\$\\{[^}]*\\}/g, '')\n // Remove command substitution\n .replace(/\\$\\([^)]*\\)/g, '')\n .replace(/`[^`]*`/g, '');\n\n // Remove any remaining dangerous characters at the start\n while (safe.startsWith('/') || safe.startsWith('\\\\')) {\n safe = safe.substring(1);\n }\n\n return safe;\n}\n\n/**\n * Check if a glob pattern is safe to use\n * \n * @param pattern - The glob pattern to check\n * @returns true if safe, false if potentially dangerous\n * \n * @example\n * ```typescript\n * isGlobSafe('src/**\\/*.ts') // true\n * isGlobSafe('../../../etc/passwd') // false\n * isGlobSafe('/etc/*') // false\n * ```\n */\nexport function isGlobSafe(pattern: string): boolean {\n return !DANGEROUS_GLOB_PATTERNS.some(re => re.test(pattern));\n}\n\n/**\n * Result of glob pattern validation\n */\nexport interface GlobValidationResult {\n safe: boolean;\n sanitized?: string;\n warnings: string[];\n}\n\n/**\n * Validate and optionally sanitize a glob pattern\n * \n * @param pattern - The glob pattern to validate\n * @param options - Validation options\n * @returns Validation result with sanitized pattern if requested\n */\nexport function validateGlobPattern(\n pattern: string,\n options: { sanitize?: boolean } = {}\n): GlobValidationResult {\n const warnings: string[] = [];\n\n // Check for dangerous patterns\n for (const dangerousPattern of DANGEROUS_GLOB_PATTERNS) {\n if (dangerousPattern.test(pattern)) {\n warnings.push(`Pattern contains potentially dangerous sequence: ${dangerousPattern.source}`);\n }\n }\n\n const safe = warnings.length === 0;\n\n if (options.sanitize && !safe) {\n return {\n safe: false,\n sanitized: sanitizeGlobPattern(pattern),\n warnings,\n };\n }\n\n return {\n safe,\n sanitized: safe ? pattern : undefined,\n warnings,\n };\n}\n\n"],"names":["PathGuard","validate","inputPath","_operation","config","enabled","valid","normalizedPath","includes","auditLogger","pathTraversalBlocked","error","violation","pattern","denyPatterns","regex","RegExp","test","isAbsolute","path","allowAbsolute","normalize","basePaths","length","resolve","isWithinBase","some","basePath","startsWith","sep","validateOrThrow","operation","result","Error","addBasePath","normalized","push","removeBasePath","index","indexOf","splice","isWithinAllowed","testPath","normalizedTest","getBasePath","getBasePaths","isEnabled","setEnabled","allowSymlinks","map","p","getAuditLogger","globalPathGuard","getPathGuard","configurePathGuard","resetPathGuard","DANGEROUS_GLOB_PATTERNS","sanitizeGlobPattern","safe","replace","substring","isGlobSafe","re","validateGlobPattern","options","warnings","dangerousPattern","source","sanitize","sanitized","undefined"],"mappings":";;;;;;;;;;;;;;;;AAwBA;;;;;;;;;;;;;;;;;;;;AAoBC,IACM,MAAMA,SAAAA,CAAAA;AAyBT;;;;;;AAMC,QACDC,QAAAA,CAASC,SAAiB,EAAEC,UAAAA,GAAqB,QAAQ,EAAwB;AAC7E,QAAA,IAAI,CAAC,IAAI,CAACC,MAAM,CAACC,OAAO,EAAE;YACtB,OAAO;gBAAEC,KAAAA,EAAO,IAAA;gBAAMC,cAAAA,EAAgBL;AAAU,aAAA;AACpD,QAAA;;QAGA,IAAIA,SAAAA,CAAUM,QAAQ,CAAC,IAAA,CAAA,EAAO;AAC1B,YAAA,IAAI,CAACC,WAAW,CAACC,oBAAoB,CAACR,SAAAA,EAAW,oBAAA,CAAA;YACjD,OAAO;gBACHI,KAAAA,EAAO,KAAA;gBACPK,KAAAA,EAAO,kCAAA;gBACPC,SAAAA,EAAW;AACf,aAAA;AACJ,QAAA;;AAGA,QAAA,KAAK,MAAMC,OAAAA,IAAW,IAAI,CAACT,MAAM,CAACU,YAAY,CAAE;YAC5C,IAAI;gBACA,MAAMC,KAAAA,GAAQ,IAAIC,MAAAA,CAAOH,OAAAA,EAAS,GAAA,CAAA;gBAClC,IAAIE,KAAAA,CAAME,IAAI,CAACf,SAAAA,CAAAA,EAAY;oBACvB,IAAI,CAACO,WAAW,CAACC,oBAAoB,CAACR,SAAAA,EAAW,CAAC,sBAAsB,EAAEW,OAAAA,CAAAA,CAAS,CAAA;oBACnF,OAAO;wBACHP,KAAAA,EAAO,KAAA;wBACPK,KAAAA,EAAO,iCAAA;wBACPC,SAAAA,EAAWC;AACf,qBAAA;AACJ,gBAAA;AACJ,YAAA,CAAA,CAAE,OAAM;;AAER,YAAA;AACJ,QAAA;;QAGA,MAAMK,UAAAA,GAAaC,aAAAA,CAAKD,UAAU,CAAChB,SAAAA,CAAAA;AACnC,QAAA,IAAIgB,cAAc,CAAC,IAAI,CAACd,MAAM,CAACgB,aAAa,EAAE;AAC1C,YAAA,IAAI,CAACX,WAAW,CAACC,oBAAoB,CAACR,SAAAA,EAAW,4BAAA,CAAA;YACjD,OAAO;gBACHI,KAAAA,EAAO,KAAA;gBACPK,KAAAA,EAAO,gCAAA;gBACPC,SAAAA,EAAW;AACf,aAAA;AACJ,QAAA;;QAGA,IAAIL,cAAAA;QACJ,IAAI;AACA,YAAA,IAAIW,UAAAA,EAAY;gBACZX,cAAAA,GAAiBY,aAAAA,CAAKE,SAAS,CAACnB,SAAAA,CAAAA;AACpC,YAAA,CAAA,MAAO,IAAI,IAAI,CAACoB,SAAS,CAACC,MAAM,GAAG,CAAA,EAAG;;gBAElChB,cAAAA,GAAiBY,aAAAA,CAAKK,OAAO,CAAC,IAAI,CAACF,SAAS,CAAC,EAAE,EAAEpB,SAAAA,CAAAA;YACrD,CAAA,MAAO;gBACHK,cAAAA,GAAiBY,aAAAA,CAAKK,OAAO,CAACtB,SAAAA,CAAAA;AAClC,YAAA;AACJ,QAAA,CAAA,CAAE,OAAM;YACJ,OAAO;gBACHI,KAAAA,EAAO,KAAA;gBACPK,KAAAA,EAAO;AACX,aAAA;AACJ,QAAA;;AAGA,QAAA,IAAI,IAAI,CAACW,SAAS,CAACC,MAAM,GAAG,CAAA,EAAG;AAC3B,YAAA,MAAME,eAAe,IAAI,CAACH,SAAS,CAACI,IAAI,CAACC,CAAAA,QAAAA,GACrCpB,cAAAA,CAAeqB,UAAU,CAACD,QAAAA,GAAWR,aAAAA,CAAKU,GAAG,KAAKtB,cAAAA,KAAmBoB,QAAAA,CAAAA;AAGzE,YAAA,IAAI,CAACF,YAAAA,EAAc;AACf,gBAAA,IAAI,CAAChB,WAAW,CAACC,oBAAoB,CAACR,SAAAA,EAAW,kCAAA,CAAA;gBACjD,OAAO;oBACHI,KAAAA,EAAO,KAAA;oBACPK,KAAAA,EAAO,qCAAA;oBACPC,SAAAA,EAAW;AACf,iBAAA;AACJ,YAAA;AACJ,QAAA;;;;QAMA,OAAO;YACHN,KAAAA,EAAO,IAAA;AACPC,YAAAA;AACJ,SAAA;AACJ,IAAA;AAEA;;;;;;;AAOC,QACDuB,eAAAA,CAAgB5B,SAAiB,EAAE6B,SAAAA,GAAoB,QAAQ,EAAU;AACrE,QAAA,MAAMC,MAAAA,GAAS,IAAI,CAAC/B,QAAQ,CAACC,SAAAA,EAAW6B,SAAAA,CAAAA;QACxC,IAAI,CAACC,MAAAA,CAAO1B,KAAK,EAAE;AACf,YAAA,MAAM,IAAI2B,KAAAA,CAAM,CAAC,wBAAwB,EAAED,MAAAA,CAAOrB,KAAK,CAAA,CAAE,CAAA;AAC7D,QAAA;AACA,QAAA,OAAOqB,OAAOzB,cAAc;AAChC,IAAA;AAEA;;;;QAKA2B,WAAAA,CAAYP,QAAgB,EAAQ;QAChC,MAAMQ,UAAAA,GAAahB,aAAAA,CAAKK,OAAO,CAACG,QAAAA,CAAAA;AAChC,QAAA,IAAI,CAAC,IAAI,CAACL,SAAS,CAACd,QAAQ,CAAC2B,UAAAA,CAAAA,EAAa;AACtC,YAAA,IAAI,CAACb,SAAS,CAACc,IAAI,CAACD,UAAAA,CAAAA;AACxB,QAAA;AACJ,IAAA;AAEA;;;;QAKAE,cAAAA,CAAeV,QAAgB,EAAQ;QACnC,MAAMQ,UAAAA,GAAahB,aAAAA,CAAKK,OAAO,CAACG,QAAAA,CAAAA;AAChC,QAAA,MAAMW,QAAQ,IAAI,CAAChB,SAAS,CAACiB,OAAO,CAACJ,UAAAA,CAAAA;QACrC,IAAIG,KAAAA,KAAU,EAAC,EAAG;AACd,YAAA,IAAI,CAAChB,SAAS,CAACkB,MAAM,CAACF,KAAAA,EAAO,CAAA,CAAA;AACjC,QAAA;AACJ,IAAA;AAEA;;;;;QAMAG,eAAAA,CAAgBC,QAAgB,EAAW;AACvC,QAAA,IAAI,IAAI,CAACpB,SAAS,CAACC,MAAM,KAAK,GAAG,OAAO,IAAA;QAExC,MAAMoB,cAAAA,GAAiBxB,aAAAA,CAAKK,OAAO,CAACkB,QAAAA,CAAAA;AACpC,QAAA,OAAO,IAAI,CAACpB,SAAS,CAACI,IAAI,CAACC,CAAAA,QAAAA,GACvBgB,cAAAA,CAAef,UAAU,CAACD,QAAAA,GAAWR,aAAAA,CAAKU,GAAG,KAAKc,cAAAA,KAAmBhB,QAAAA,CAAAA;AAE7E,IAAA;AAEA;;;;AAIC,QACDiB,WAAAA,GAAkC;AAC9B,QAAA,OAAO,IAAI,CAACtB,SAAS,CAAC,CAAA,CAAE;AAC5B,IAAA;AAEA;;;;AAIC,QACDuB,YAAAA,GAAyB;QACrB,OAAO;AAAI,YAAA,GAAA,IAAI,CAACvB;AAAU,SAAA;AAC9B,IAAA;AAEA;;;;AAIC,QACDwB,SAAAA,GAAqB;AACjB,QAAA,OAAO,IAAI,CAAC1C,MAAM,CAACC,OAAO;AAC9B,IAAA;AAEA;;;;QAKA0C,UAAAA,CAAW1C,OAAgB,EAAQ;AAC/B,QAAA,IAAI,CAACD,MAAM,CAACC,OAAO,GAAGA,OAAAA;AAC1B,IAAA;AA5MA,IAAA,WAAA,CAAYD,MAAAA,GAAsC,EAAE,EAAEK,WAAiC,CAAE;AAJzF,QAAA,gBAAA,CAAA,IAAA,EAAQL,UAAR,MAAA,CAAA;AACA,QAAA,gBAAA,CAAA,IAAA,EAAQK,eAAR,MAAA,CAAA;AACA,QAAA,gBAAA,CAAA,IAAA,EAAQa,aAAR,MAAA,CAAA;QAGI,IAAI,CAAClB,MAAM,GAAG;YACVC,OAAAA,EAAS,IAAA;AACTiB,YAAAA,SAAAA,EAAW,EAAE;YACbF,aAAAA,EAAe,KAAA;YACf4B,aAAAA,EAAe,KAAA;YACflC,YAAAA,EAAc;AACV,gBAAA,QAAA;AACA,gBAAA,GAAA;AACA,gBAAA,QAAA;AACA,gBAAA;AACH,aAAA;AACD,YAAA,GAAGV;AACP,SAAA;;AAGA,QAAA,IAAI,CAACkB,SAAS,GAAG,IAAI,CAAClB,MAAM,CAACkB,SAAS,CAAC2B,GAAG,CAACC,CAAAA,CAAAA,GAAK/B,aAAAA,CAAKK,OAAO,CAAC0B,CAAAA,CAAAA,CAAAA;QAC7D,IAAI,CAACzC,WAAW,GAAGA,WAAAA,IAAe0C,cAAAA,EAAAA;AACtC,IAAA;AA2LJ;AAEA;AACA,IAAIC,eAAAA,GAAoC,IAAA;AAExC;;;;AAIC,IACM,SAASC,YAAAA,GAAAA;AACZ,IAAA,IAAI,CAACD,eAAAA,EAAiB;AAClBA,QAAAA,eAAAA,GAAkB,IAAIpD,SAAAA,EAAAA;AAC1B,IAAA;IACA,OAAOoD,eAAAA;AACX;AAEA;;;;IAKO,SAASE,kBAAAA,CAAmBlD,MAAmC,EAAA;AAClEgD,IAAAA,eAAAA,GAAkB,IAAIpD,SAAAA,CAAUI,MAAAA,CAAAA;AACpC;AAEA;;AAEC,IACM,SAASmD,cAAAA,GAAAA;IACZH,eAAAA,GAAkB,IAAA;AACtB;AAEA;AAEA;;AAEC,IACD,MAAMI,uBAAAA,GAA0B;AAC5B,IAAA,QAAA;AACA,IAAA,QAAA;AACA,IAAA,KAAA;AACA,IAAA,YAAA;AACA,IAAA,IAAA;AACA,IAAA,MAAA;AACA,IAAA,MAAA;AACA,IAAA;AACH,CAAA;AAED;;;;;;;;;;;;IAaO,SAASC,mBAAAA,CAAoB5C,OAAe,EAAA;IAC/C,IAAI6C,IAAAA,GAAO7C,OACP;AACC8C,KAAAA,OAAO,CAAC,SAAA,EAAW,EAAA,CAAA,CACnBA,OAAO,CAAC,SAAA,EAAW,GACpB;AACCA,KAAAA,OAAO,CAAC,MAAA,EAAQ,EAAA,CAAA,CAChBA,OAAO,CAAC,kBAAA,EAAoB,GAC7B;KACCA,OAAO,CAAC,UAAA,EAAY,EAAA,CACrB;KACCA,OAAO,CAAC,cAAA,EAAgB,EAAA,CACzB;AACCA,KAAAA,OAAO,CAAC,cAAA,EAAgB,EAAA,CAAA,CACxBA,OAAO,CAAC,UAAA,EAAY,EAAA,CAAA;;AAGzB,IAAA,MAAOD,KAAK9B,UAAU,CAAC,QAAQ8B,IAAAA,CAAK9B,UAAU,CAAC,IAAA,CAAA,CAAO;QAClD8B,IAAAA,GAAOA,IAAAA,CAAKE,SAAS,CAAC,CAAA,CAAA;AAC1B,IAAA;IAEA,OAAOF,IAAAA;AACX;AAEA;;;;;;;;;;;;IAaO,SAASG,UAAAA,CAAWhD,OAAe,EAAA;IACtC,OAAO,CAAC2C,wBAAwB9B,IAAI,CAACoC,CAAAA,EAAAA,GAAMA,EAAAA,CAAG7C,IAAI,CAACJ,OAAAA,CAAAA,CAAAA;AACvD;AAWA;;;;;;AAMC,IACM,SAASkD,mBAAAA,CACZlD,OAAe,EACfmD,OAAAA,GAAkC,EAAE,EAAA;AAEpC,IAAA,MAAMC,WAAqB,EAAE;;IAG7B,KAAK,MAAMC,oBAAoBV,uBAAAA,CAAyB;QACpD,IAAIU,gBAAAA,CAAiBjD,IAAI,CAACJ,OAAAA,CAAAA,EAAU;AAChCoD,YAAAA,QAAAA,CAAS7B,IAAI,CAAC,CAAC,iDAAiD,EAAE8B,gBAAAA,CAAiBC,MAAM,CAAA,CAAE,CAAA;AAC/F,QAAA;AACJ,IAAA;IAEA,MAAMT,IAAAA,GAAOO,QAAAA,CAAS1C,MAAM,KAAK,CAAA;AAEjC,IAAA,IAAIyC,OAAAA,CAAQI,QAAQ,IAAI,CAACV,IAAAA,EAAM;QAC3B,OAAO;YACHA,IAAAA,EAAM,KAAA;AACNW,YAAAA,SAAAA,EAAWZ,mBAAAA,CAAoB5C,OAAAA,CAAAA;AAC/BoD,YAAAA;AACJ,SAAA;AACJ,IAAA;IAEA,OAAO;AACHP,QAAAA,IAAAA;AACAW,QAAAA,SAAAA,EAAWX,OAAO7C,OAAAA,GAAUyD,SAAAA;AAC5BL,QAAAA;AACJ,KAAA;AACJ;;;;"}