diff --git a/README.md b/README.md index 8e3b918..7104374 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,7 @@ The package defines these formats: - _ipv4_: IP address v4. - _ipv6_: IP address v6. - _regex_: tests whether a string is a valid regular expression by passing it to RegExp constructor. +- _ulid_: Universally Unique Lexicographically Sortable Identifier according to [GitHub ulid/spec](https://github.com/ulid/spec) - _uuid_: Universally Unique IDentifier according to [RFC4122](http://tools.ietf.org/html/rfc4122). - _json-pointer_: JSON-pointer according to [RFC6901](https://tools.ietf.org/html/rfc6901). - _relative-json-pointer_: relative JSON-pointer according to [this draft](http://tools.ietf.org/html/draft-luff-relative-json-pointer-00). diff --git a/src/formats.ts b/src/formats.ts index d3cde9b..922111b 100644 --- a/src/formats.ts +++ b/src/formats.ts @@ -19,6 +19,7 @@ export type FormatName = | "ipv4" | "ipv6" | "regex" + | "ulid" | "uuid" | "json-pointer" | "json-pointer-uri-fragment" @@ -69,6 +70,8 @@ export const fullFormats: DefinedFormats = { ipv4: /^(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)$/, ipv6: /^((([0-9a-f]{1,4}:){7}([0-9a-f]{1,4}|:))|(([0-9a-f]{1,4}:){6}(:[0-9a-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9a-f]{1,4}:){5}(((:[0-9a-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9a-f]{1,4}:){4}(((:[0-9a-f]{1,4}){1,3})|((:[0-9a-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){3}(((:[0-9a-f]{1,4}){1,4})|((:[0-9a-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){2}(((:[0-9a-f]{1,4}){1,5})|((:[0-9a-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){1}(((:[0-9a-f]{1,4}){1,6})|((:[0-9a-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9a-f]{1,4}){1,7})|((:[0-9a-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))$/i, regex, + // ulid: https://github.com/ulid/spec + ulid: /^[0-7][0-9A-HJKMNP-TV-Z]{25}$/, // uuid: http://tools.ietf.org/html/rfc4122 uuid: /^(?:urn:uuid:)?[0-9a-f]{8}-(?:[0-9a-f]{4}-){3}[0-9a-f]{12}$/i, // JSON-pointer: https://tools.ietf.org/html/rfc6901 diff --git a/tests/extras/format.json b/tests/extras/format.json index 1a72ec4..5d6d480 100644 --- a/tests/extras/format.json +++ b/tests/extras/format.json @@ -600,6 +600,47 @@ } ] }, + { + "description": "validation of ulid strings", + "schema": {"format": "ulid"}, + "tests": [ + { + "description": "a valid ulid", + "data": "01ARZ3NDEKTSV4RRFFQ69G5FAV", + "valid": true + }, + { + "description": "not valid ulid as it is too long", + "data": "01ARZ3NDEKTSV4RRFFQ69G5FAVA", + "valid": false + }, + { + "description": "not valid ulid as it is too short", + "data": "01ARZ3NDEKTSV4RRFFQ69G5FA", + "valid": false + }, + { + "description": "not valid ulid as it has a lower case character", + "data": "01ARZ3NDEKTSV4rRFFQ69G5FAV", + "valid": false + }, + { + "description": "not valid ulid as it has a hyphen", + "data": "01ARZ3NDEKTSV4-RFFQ69G5FAV", + "valid": false + }, + { + "description": "not valid ulid as it starts with an 8", + "data": "81ARZ3NDEKTSV4RRFIQ69G5FAV", + "valid": false + }, + { + "description": "not valid ulid as it has an I", + "data": "01ARZ3NDEKTSV4IRFIQ69G5FAV", + "valid": false + } + ] + }, { "description": "validation of uuid strings", "schema": {"format": "uuid"},