-
Notifications
You must be signed in to change notification settings - Fork 13
DEVXP-2541: feat(next): add support for format
#128
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
Merged
Merged
Changes from all commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
d8beb8f
chore: fix lint script and add proper type check
dragidavid d2e7ffe
chore: separate json-schema-test-suite related items from validation
dragidavid a111e13
fix: add extension
dragidavid 8598d9b
fix: ts errors
dragidavid 9e727ce
feat(next): add support for `format`
dragidavid 75ad153
chore: re-run external tests
dragidavid 17d5ec2
chore: add `check` script to the build file
dragidavid 2107ad4
fix: ts issue
dragidavid d44e258
fix: ts problems
dragidavid e3c098d
fix: ts errors -> back to js
dragidavid 9b52dd4
fix: newline
dragidavid dcd14d1
chore: always add new line
dragidavid 56f8b59
chore: type the constants file
dragidavid a8201a9
simplify build file
dragidavid File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,14 @@ | ||
import antfu from '@antfu/eslint-config' | ||
|
||
export default antfu({}) | ||
export default antfu({ | ||
ignores: [ | ||
// Build output | ||
'dist', | ||
|
||
// Dependencies | ||
'node_modules', | ||
|
||
// External test suite | ||
'json-schema-test-suite', | ||
], | ||
}) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
import type { ValidationError } from '../form' | ||
import type { SchemaValidationErrorType } from './schema' | ||
|
||
/** | ||
* Format validation error type | ||
* @description | ||
* According to JSON Schema 2020-12, format validation is an annotation by default. | ||
* It should only be treated as an assertion when explicitly configured. | ||
*/ | ||
export type FormatValidationErrorType = 'format' | ||
|
||
/** | ||
* Supported format names as defined in JSON Schema 2020-12 | ||
*/ | ||
export type SupportedFormat = | ||
dragidavid marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| 'date-time' | ||
| 'date' | ||
| 'time' | ||
| 'duration' | ||
| 'email' | ||
| 'idn-email' | ||
| 'hostname' | ||
| 'idn-hostname' | ||
| 'ipv4' | ||
| 'ipv6' | ||
| 'uri' | ||
| 'uri-reference' | ||
| 'iri' | ||
| 'iri-reference' | ||
| 'uuid' | ||
|
||
// Cache compiled RegExp objects for performance | ||
dragidavid marked this conversation as resolved.
Show resolved
Hide resolved
|
||
const REGEX = { | ||
dateTime: /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})$/, | ||
date: /^\d{4}-\d{2}-\d{2}$/, | ||
time: /^\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})?$/, | ||
duration: /^P(?:\d+Y)?(?:\d+M)?(?:\d+D)?(?:T(?:\d+H)?(?:\d+M)?(?:\d+S)?)?$/, | ||
// RFC 5322 compliant email regex | ||
email: /^[\w.!#$%&'*+/=?^`{|}~-]+@[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*$/i, | ||
// RFC 1123 compliant hostname regex | ||
hostname: /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*$/i, | ||
ipv4: /^(?:(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})$/, | ||
ipv6: /^(?:(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|(?:[0-9a-fA-F]{1,4}:){1,7}:|(?:[0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|(?:[0-9a-fA-F]{1,4}:){1,5}(?::[0-9a-fA-F]{1,4}){1,2}|(?:[0-9a-fA-F]{1,4}:){1,4}(?::[0-9a-fA-F]{1,4}){1,3}|(?:[0-9a-fA-F]{1,4}:){1,3}(?::[0-9a-fA-F]{1,4}){1,4}|(?:[0-9a-fA-F]{1,4}:){1,2}(?::[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:(?::[0-9a-fA-F]{1,4}){1,6}|:(?:(?::[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(?::[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]+|::(?:ffff(?::0{1,4})?:)?(?:(?:25[0-5]|(?:2[0-4]|1?\d)?\d)\.){3}(?:25[0-5]|(?:2[0-4]|1?\d)?\d)|(?:[0-9a-fA-F]{1,4}:){1,4}:(?:(?:25[0-5]|(?:2[0-4]|1?\d)?\d)\.){3}(?:25[0-5]|(?:2[0-4]|1?\d)?\d))$/, | ||
dragidavid marked this conversation as resolved.
Show resolved
Hide resolved
|
||
uuid: /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i, | ||
} | ||
|
||
/** | ||
* Built-in format validators | ||
* @description | ||
* According to JSON Schema 2020-12, implementations SHOULD implement validation | ||
* for these formats, but MAY choose to implement validation as a no-op. | ||
*/ | ||
const formatValidators: Record<SupportedFormat, (value: string) => boolean> = { | ||
'date-time': value => REGEX.dateTime.test(value), | ||
'date': value => REGEX.date.test(value), | ||
'time': value => REGEX.time.test(value), | ||
'duration': value => REGEX.duration.test(value), | ||
'email': value => REGEX.email.test(value), | ||
'idn-email': value => REGEX.email.test(value), // TODO: Add proper IDN support | ||
'hostname': value => REGEX.hostname.test(value), | ||
'idn-hostname': value => REGEX.hostname.test(value), // TODO: Add proper IDN support | ||
'ipv4': value => REGEX.ipv4.test(value), | ||
'ipv6': value => REGEX.ipv6.test(value), | ||
'uri': (value) => { | ||
try { | ||
dragidavid marked this conversation as resolved.
Show resolved
Hide resolved
|
||
void new URL(value) | ||
return true | ||
} | ||
catch { | ||
return false | ||
} | ||
}, | ||
'uri-reference': (value) => { | ||
try { | ||
void new URL(value, 'http://example.com') | ||
return true | ||
} | ||
catch { | ||
return false | ||
} | ||
}, | ||
'iri': (value) => { | ||
try { | ||
void new URL(value) | ||
return true | ||
} | ||
catch { | ||
return false | ||
} | ||
}, | ||
'iri-reference': (value) => { | ||
try { | ||
void new URL(value, 'http://example.com') | ||
return true | ||
} | ||
catch { | ||
return false | ||
} | ||
}, | ||
'uuid': value => REGEX.uuid.test(value), | ||
dragidavid marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
/** | ||
* Validate a string value against a format | ||
* @param value - The string value to validate | ||
* @param format - The format to validate against | ||
* @returns An array of validation errors | ||
* @description | ||
* According to JSON Schema 2020-12: | ||
* - Format validation is an annotation by default | ||
* - Format validation only applies to strings | ||
* - Unknown formats should be ignored | ||
* - Implementations SHOULD implement validation for standard formats | ||
* - Implementations MAY treat format as a no-op | ||
* @example | ||
* ```ts | ||
* const errors = validateFormat('not-an-email', 'email') | ||
dragidavid marked this conversation as resolved.
Show resolved
Hide resolved
|
||
* console.log(errors) // [{ path: [], validation: 'format', message: 'must be a valid email format' }] | ||
* ``` | ||
*/ | ||
export function validateFormat(value: string, format: string): ValidationError[] { | ||
const errors: ValidationError[] = [] | ||
|
||
// Format validation only applies to strings | ||
if (typeof value !== 'string') { | ||
return errors | ||
} | ||
|
||
const validator = formatValidators[format as SupportedFormat] | ||
dragidavid marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if (validator && !validator(value)) { | ||
errors.push({ | ||
path: [], | ||
validation: 'format' as SchemaValidationErrorType, | ||
message: `must be a valid ${format} format`, | ||
}) | ||
} | ||
|
||
return errors | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export declare const JSON_SCHEMA_SUITE_FAILED_TESTS_FILE_NAME: string |
File renamed without changes.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.