-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement String.regex "invalidate" configuration #1035
Changes from 3 commits
fe35fcc
83b1aa7
c5f95af
ea40559
0f578f4
80f06eb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1542,14 +1542,26 @@ const schema = Joi.object({ | |
}); | ||
``` | ||
|
||
#### `string.regex(pattern, [name])` | ||
#### `string.regex(pattern, [name | config])` | ||
|
||
Defines a regular expression rule where: | ||
- `pattern` - a regular expression object the string value must match against. | ||
- `name` - optional name for patterns (useful with multiple patterns). Defaults to 'required'. | ||
- `config` - an optional configuration object with the following supported properties: | ||
- `name` - optional pattern name. Defaults to `required`. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as the original, I have absolutely no idea where that |
||
- `invalidate` - optional boolean flag. Defaults to `false` behavior. If specified as `true`, the provided pattern will be disallowed instead of required. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not a big fan of invalidate, it makes me think of caching. What about invert ? |
||
|
||
```js | ||
const schema = Joi.string().regex(/^[abc]+$/); | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Missing the simpler inlined string. |
||
const namedSchema = Joi.string().regex(/[0-9]/, { name: 'numbers'}); | ||
namedSchema.validate('alpha'); // ValidationError: "value" with value "alpha" fails to match the numbers pattern | ||
|
||
const invalidatedSchema = Joi.string().regex(/[a-z]/, { invalidate: true }); | ||
invalidatedSchema.validate('lowercase'); // ValidationError: "value" with value "lowercase" matches the invalidated pattern: [a-z] | ||
|
||
const invalidatedNamedSchema = Joi.string().regex(/[a-z]/, { name: 'alpha', invalidate: true }); | ||
invalidatedNamedSchema.validate('lowercase'); // ValidationError: "value" with value "lowercase" matches the invalidated alpha pattern | ||
``` | ||
|
||
#### `string.replace(pattern, replacement)` | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -91,19 +91,30 @@ internals.String = class extends Any { | |
}); | ||
} | ||
|
||
regex(pattern, name) { | ||
regex(pattern, config) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I prefer the term options, in readme too. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was going to use "options", but then I have a variable name clash with the test callback defined on line 103. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh, didn't see that one. |
||
|
||
Hoek.assert(pattern instanceof RegExp, 'pattern must be a RegExp'); | ||
|
||
pattern = new RegExp(pattern.source, pattern.ignoreCase ? 'i' : undefined); // Future version should break this and forbid unsupported regex flags | ||
|
||
return this._test('regex', pattern, function (value, state, options) { | ||
const patternIsInvalidated = (typeof config === 'object' && Hoek.reach(config, 'invalidate')); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why use hoek to access it since it's a direct property and you just checked it's an object ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Habit. Updating along with other changes. :) |
||
const testName = patternIsInvalidated ? 'invalidatedRegex' : 'regex'; | ||
|
||
if (pattern.test(value)) { | ||
return this._test(testName, pattern, function (value, state, options) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I changed the test name to distinguish between a normal regex test and an inverted regex test in the {
type: 'string',
invalids: [''],
rules: [
{
name: 'regex',
arg: {
pattern: /[a-z]/,
inverted: true
}
}
]
} There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It will automatically if you do. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
(Running low on time on my lunch break. Going to move forward with |
||
|
||
const patternMatch = pattern.test(value); | ||
|
||
if ((patternMatch && !patternIsInvalidated) || (!patternMatch && patternIsInvalidated)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Clearer with |
||
return value; | ||
} | ||
|
||
return this.createError((name ? 'string.regex.name' : 'string.regex.base'), { name, pattern, value }, state, options); | ||
const name = typeof config === 'string' ? | ||
config : | ||
Hoek.reach(config, 'name'); | ||
const baseRegex = patternIsInvalidated ? 'string.regex.invalidated' : 'string.regex.base'; | ||
const nameRegex = patternIsInvalidated ? 'string.regex.invalidatedName' : 'string.regex.name'; | ||
|
||
return this.createError((name ? nameRegex : baseRegex), { name, pattern, value }, state, options); | ||
}); | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
options
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops XD