0
# Utility Functions
1
2
General-purpose utility functions for regular expression validation, require path creation, and type indexing operations.
3
4
## Capabilities
5
6
### Regular Expression Validation
7
8
Safe regular expression creation from string patterns with automatic validation.
9
10
```typescript { .api }
11
/**
12
* Attempts to build a RegExp from a string if it's a valid regex pattern
13
* Supports common regex delimiters and flags
14
* @param str - String that may contain a regex pattern
15
* @returns RegExp object if valid pattern, undefined otherwise
16
*/
17
function buildRegexpIfValid(str: string): RegExp | undefined;
18
```
19
20
**Usage Examples:**
21
22
```typescript
23
import { buildRegexpIfValid } from "medusa-core-utils";
24
25
// Valid regex patterns
26
const emailRegex = buildRegexpIfValid("/^[\\w-\\.]+@([\\w-]+\\.)+[\\w-]{2,4}$/");
27
console.log(emailRegex); // RegExp object
28
29
const caseInsensitiveRegex = buildRegexpIfValid("/hello/i");
30
console.log(caseInsensitiveRegex); // RegExp with 'i' flag
31
32
const multilineRegex = buildRegexpIfValid("/^start.*end$/gm");
33
console.log(multilineRegex); // RegExp with 'gm' flags
34
35
// Different delimiters
36
const withTilde = buildRegexpIfValid("~pattern~i");
37
const withAt = buildRegexpIfValid("@pattern@g");
38
const withHash = buildRegexpIfValid("#pattern#");
39
40
// Invalid patterns
41
const invalid1 = buildRegexpIfValid("not a regex");
42
console.log(invalid1); // undefined
43
44
const invalid2 = buildRegexpIfValid("/unclosed pattern");
45
console.log(invalid2); // undefined
46
47
const malformed = buildRegexpIfValid("/[invalid/");
48
console.log(malformed); // undefined
49
50
// Practical usage in validation
51
function createValidator(pattern: string) {
52
const regex = buildRegexpIfValid(pattern);
53
54
if (!regex) {
55
throw new Error(`Invalid regex pattern: ${pattern}`);
56
}
57
58
return (value: string) => regex.test(value);
59
}
60
61
// Use in configuration
62
const validationRules = {
63
email: "/^[\\w-\\.]+@([\\w-]+\\.)+[\\w-]{2,4}$/",
64
phone: "/^\\+?[1-9]\\d{1,14}$/",
65
username: "/^[a-zA-Z0-9_]{3,20}$/"
66
};
67
68
const validators = Object.entries(validationRules).reduce((acc, [key, pattern]) => {
69
const regex = buildRegexpIfValid(pattern);
70
if (regex) {
71
acc[key] = (value: string) => regex.test(value);
72
}
73
return acc;
74
}, {} as Record<string, (value: string) => boolean>);
75
76
// Use in CORS origin parsing
77
function parsePattern(pattern: string): string | RegExp {
78
const regex = buildRegexpIfValid(pattern);
79
return regex || pattern;
80
}
81
```
82
83
### Regular Expression Pattern Support
84
85
The function supports various regex pattern formats and delimiters:
86
87
**Supported Delimiters:**
88
- `/` - Forward slash (most common)
89
- `~` - Tilde
90
- `@` - At symbol
91
- `;` - Semicolon
92
- `%` - Percent
93
- `#` - Hash
94
- `'` - Single quote
95
96
**Supported Flags:**
97
- `g` - Global matching
98
- `i` - Case-insensitive
99
- `m` - Multiline
100
- `s` - Dot matches newlines
101
- `u` - Unicode
102
- `y` - Sticky matching
103
104
**Usage Examples:**
105
106
```typescript
107
import { buildRegexpIfValid } from "medusa-core-utils";
108
109
// Common patterns with different delimiters
110
const patterns = [
111
"/test/g", // Forward slash with global flag
112
"~test~i", // Tilde with case-insensitive flag
113
"@test@m", // At symbol with multiline flag
114
"#test#gi", // Hash with multiple flags
115
"'test'", // Single quote, no flags
116
";test;u" // Semicolon with unicode flag
117
];
118
119
patterns.forEach(pattern => {
120
const regex = buildRegexpIfValid(pattern);
121
console.log(`${pattern} -> ${regex || 'invalid'}`);
122
});
123
124
// Complex patterns
125
const complexPatterns = [
126
"/^\\d{3}-\\d{2}-\\d{4}$/", // SSN format
127
"/^[A-Z]{2}\\d{2}\\s?\\d{4}$/i", // Postal code
128
"/\\b\\w+@\\w+\\.\\w+\\b/g", // Simple email extraction
129
"/(https?:\\/\\/)([\\w.-]+)/gi" // URL extraction
130
];
131
132
complexPatterns.forEach(pattern => {
133
const regex = buildRegexpIfValid(pattern);
134
if (regex) {
135
console.log(`Valid pattern: ${pattern}`);
136
console.log(`Flags: ${regex.flags}`);
137
console.log(`Source: ${regex.source}`);
138
}
139
});
140
141
// Error handling in pattern parsing
142
function safeRegexCreate(pattern: string, fallback?: RegExp): RegExp {
143
const regex = buildRegexpIfValid(pattern);
144
145
if (regex) {
146
return regex;
147
}
148
149
if (fallback) {
150
return fallback;
151
}
152
153
// Return a regex that matches nothing
154
return /(?!)/;
155
}
156
157
// Use in search and replace operations
158
function createSearchReplace(searchPattern: string, replacement: string) {
159
const regex = buildRegexpIfValid(searchPattern);
160
161
if (!regex) {
162
// Fallback to string replacement
163
return (text: string) => text.replace(searchPattern, replacement);
164
}
165
166
return (text: string) => text.replace(regex, replacement);
167
}
168
```
169
170
### Input Validation and Sanitization
171
172
**Usage Examples:**
173
174
```typescript
175
import { buildRegexpIfValid } from "medusa-core-utils";
176
177
// User input validation
178
function validateUserInput(input: string, patterns: string[]): boolean {
179
return patterns.some(pattern => {
180
const regex = buildRegexpIfValid(pattern);
181
return regex ? regex.test(input) : false;
182
});
183
}
184
185
// Configuration-driven validation
186
interface ValidationConfig {
187
field: string;
188
pattern: string;
189
required: boolean;
190
}
191
192
function createValidationEngine(configs: ValidationConfig[]) {
193
const compiledValidators = configs.map(config => {
194
const regex = buildRegexpIfValid(config.pattern);
195
return {
196
...config,
197
validator: regex ? (value: string) => regex.test(value) : null
198
};
199
});
200
201
return (data: Record<string, string>) => {
202
const errors: string[] = [];
203
204
for (const config of compiledValidators) {
205
const value = data[config.field];
206
207
if (config.required && !value) {
208
errors.push(`${config.field} is required`);
209
continue;
210
}
211
212
if (value && config.validator && !config.validator(value)) {
213
errors.push(`${config.field} format is invalid`);
214
}
215
}
216
217
return { isValid: errors.length === 0, errors };
218
};
219
}
220
221
// Usage with configuration
222
const validationConfigs: ValidationConfig[] = [
223
{ field: "email", pattern: "/^[\\w-\\.]+@([\\w-]+\\.)+[\\w-]{2,4}$/", required: true },
224
{ field: "phone", pattern: "/^\\+?[1-9]\\d{1,14}$/", required: false },
225
{ field: "zipCode", pattern: "/^\\d{5}(-\\d{4})?$/", required: true }
226
];
227
228
const validator = createValidationEngine(validationConfigs);
229
230
const userData = {
231
email: "user@example.com",
232
phone: "+1234567890",
233
zipCode: "12345"
234
};
235
236
const result = validator(userData);
237
console.log(result); // { isValid: true, errors: [] }
238
```