From 534e282bb25a3586817e49c21c176c7db0a69c41 Mon Sep 17 00:00:00 2001 From: Aris Kemper Date: Tue, 19 Dec 2023 13:19:13 +0100 Subject: [PATCH 1/2] feat: add octal validation --- library/src/regex.ts | 5 ++ library/src/validations/index.ts | 1 + library/src/validations/octal/index.ts | 1 + library/src/validations/octal/octal.test.ts | 51 +++++++++++++++++++ library/src/validations/octal/octal.ts | 40 +++++++++++++++ .../routes/api/(validations)/octal/index.mdx | 9 ++++ website/src/routes/api/menu.md | 1 + .../(main-concepts)/pipelines/index.mdx | 1 + 8 files changed, 109 insertions(+) create mode 100644 library/src/validations/octal/index.ts create mode 100644 library/src/validations/octal/octal.test.ts create mode 100644 library/src/validations/octal/octal.ts create mode 100644 website/src/routes/api/(validations)/octal/index.mdx diff --git a/library/src/regex.ts b/library/src/regex.ts index 96416c9d5..91020ccc0 100644 --- a/library/src/regex.ts +++ b/library/src/regex.ts @@ -91,3 +91,8 @@ export const ULID_REGEX = /^[\da-hjkmnp-tv-z]{26}$/iu; * [UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier) regex. */ export const UUID_REGEX = /^[\da-f]{8}(?:-[\da-f]{4}){3}-[\da-f]{12}$/iu; + +/** + * [OCTAL](https://en.wikipedia.org/wiki/Octal) regex. + */ +export const OCTAL_REGEX = /^(0o)?[0-7]+$/iu; diff --git a/library/src/validations/index.ts b/library/src/validations/index.ts index 7383f10ab..c3577903b 100644 --- a/library/src/validations/index.ts +++ b/library/src/validations/index.ts @@ -38,6 +38,7 @@ export * from './notBytes/index.ts'; export * from './notLength/index.ts'; export * from './notSize/index.ts'; export * from './notValue/index.ts'; +export * from './octal/index.ts'; export * from './regex/index.ts'; export * from './safeInteger/index.ts'; export * from './size/index.ts'; diff --git a/library/src/validations/octal/index.ts b/library/src/validations/octal/index.ts new file mode 100644 index 000000000..4ddb0dee4 --- /dev/null +++ b/library/src/validations/octal/index.ts @@ -0,0 +1 @@ +export * from './octal.ts'; diff --git a/library/src/validations/octal/octal.test.ts b/library/src/validations/octal/octal.test.ts new file mode 100644 index 000000000..a7fe36557 --- /dev/null +++ b/library/src/validations/octal/octal.test.ts @@ -0,0 +1,51 @@ +import { describe, expect, test } from 'vitest'; +import { octal } from './octal.ts'; + +describe('octal', () => { + test('should pass only valid strings', () => { + const validate = octal(); + const value = '123'; + expect(validate._parse(value).output).toBe(value); + + const value2 = '001'; + expect(validate._parse(value2).output).toBe(value2); + + const value3 = '765'; + expect(validate._parse(value3).output).toBe(value3); + + const value4 = '000'; + expect(validate._parse(value4).output).toBe(value4); + + const value5 = '111'; + expect(validate._parse(value5).output).toBe(value5); + + const value6 = '020'; + expect(validate._parse(value6).output).toBe(value6); + + const value7 = '707'; + expect(validate._parse(value7).output).toBe(value7); + + const value8 = '00012345'; + expect(validate._parse(value8).output).toBe(value8); + + expect(validate._parse('').issues).toBeTruthy(); + expect(validate._parse('8').issues).toBeTruthy(); + expect(validate._parse('9').issues).toBeTruthy(); + expect(validate._parse('789').issues).toBeTruthy(); + expect(validate._parse('1238').issues).toBeTruthy(); + expect(validate._parse('abc').issues).toBeTruthy(); + expect(validate._parse('0123456789').issues).toBeTruthy(); + expect(validate._parse('0078').issues).toBeTruthy(); + expect(validate._parse('056A').issues).toBeTruthy(); + expect(validate._parse('99').issues).toBeTruthy(); + expect(validate._parse('08').issues).toBeTruthy(); + expect(validate._parse('%123').issues).toBeTruthy(); + expect(validate._parse('00o123').issues).toBeTruthy(); + }); + + test('should return custom error message', () => { + const error = 'Value does not match the octal!'; + const validate = octal(error); + expect(validate._parse('test').issues?.[0].message).toBe(error); + }); +}); diff --git a/library/src/validations/octal/octal.ts b/library/src/validations/octal/octal.ts new file mode 100644 index 000000000..98ba934af --- /dev/null +++ b/library/src/validations/octal/octal.ts @@ -0,0 +1,40 @@ +import { OCTAL_REGEX } from '../../regex.ts'; +import type { BaseValidation, ErrorMessage } from '../../types/index.ts'; +import { actionIssue, actionOutput } from '../../utils/index.ts'; + +/** + * Octal validation type. + */ +export type OctalValidation = BaseValidation & { + /** + * The validation type. + */ + type: 'octal'; + /** + * The Octal regex. + */ + requirement: RegExp; +}; + +/** + * Creates a validation function that validates an [OCTAL](https://en.wikipedia.org/wiki/Octal) string. + * + * @param message The error message. + * + * @returns A validation function. + */ +export function octal( + message: ErrorMessage = 'Invalid octal' +): OctalValidation { + return { + type: 'octal', + async: false, + message, + requirement: OCTAL_REGEX, + _parse(input) { + return !this.requirement.test(input) + ? actionIssue(this.type, this.message, input, this.requirement) + : actionOutput(input); + }, + }; +} diff --git a/website/src/routes/api/(validations)/octal/index.mdx b/website/src/routes/api/(validations)/octal/index.mdx new file mode 100644 index 000000000..9a405a7ec --- /dev/null +++ b/website/src/routes/api/(validations)/octal/index.mdx @@ -0,0 +1,9 @@ +--- +title: octal +contributors: + - ariskemper +--- + +# octal + +> The content of this page is not yet ready. Until then just use the [source code](https://github.com/fabian-hiller/valibot/blob/main/library/src/validations/octal/octal.ts). diff --git a/website/src/routes/api/menu.md b/website/src/routes/api/menu.md index 3fb89b00b..4bbc3f351 100644 --- a/website/src/routes/api/menu.md +++ b/website/src/routes/api/menu.md @@ -101,6 +101,7 @@ - [notLength](/api/notLength/) - [notSize](/api/notSize/) - [notValue](/api/notValue/) +- [octal](/api/octal/) - [regex](/api/regex/) - [safeInteger](/api/safeInteger/) - [size](/api/size/) diff --git a/website/src/routes/guides/(main-concepts)/pipelines/index.mdx b/website/src/routes/guides/(main-concepts)/pipelines/index.mdx index 877f2be3f..58dbb7a9a 100644 --- a/website/src/routes/guides/(main-concepts)/pipelines/index.mdx +++ b/website/src/routes/guides/(main-concepts)/pipelines/index.mdx @@ -81,6 +81,7 @@ Validation functions examine the input and, if the input does not meet a certain 'notLength', 'notSize', 'notValue', + 'octal', 'regex', 'safeInteger', 'size', From dcb6e25786f85d81bb3412c59705b17e1e35603b Mon Sep 17 00:00:00 2001 From: Fabian Hiller Date: Sat, 23 Dec 2023 13:44:32 -0500 Subject: [PATCH 2/2] Refactor octal validation and add it to changelog --- library/CHANGELOG.md | 2 +- library/src/regex.ts | 10 +++++----- library/src/validations/octal/octal.test.ts | 10 +++------- library/src/validations/octal/octal.ts | 4 ++-- website/src/routes/api/(schemas)/any/index.mdx | 1 + website/src/routes/api/(schemas)/string/index.mdx | 1 + 6 files changed, 13 insertions(+), 15 deletions(-) diff --git a/library/CHANGELOG.md b/library/CHANGELOG.md index d0fbc1f87..9f2fd43a5 100644 --- a/library/CHANGELOG.md +++ b/library/CHANGELOG.md @@ -4,7 +4,7 @@ All notable changes to the library will be documented in this file. ## vX.X.X (Month DD, YYYY) -- Add `creditCard`, `hash`, `hex` and `hexColor` validation function (pull request #292, #304, #307, #308) +- Add `creditCard`, `hash`, `hex`, `hexColor` and `octal` validation function (pull request #292, #304, #307, #308, #309) ## v0.24.1 (December 11, 2023) diff --git a/library/src/regex.ts b/library/src/regex.ts index a0b55b76e..13db50217 100644 --- a/library/src/regex.ts +++ b/library/src/regex.ts @@ -93,6 +93,11 @@ export const MAC48_REGEX = export const MAC64_REGEX = /^(?:[\da-f]{2}:){7}[\da-f]{2}$|^(?:[\da-f]{2}-){7}[\da-f]{2}$|^(?:[\da-f]{4}\.){3}[\da-f]{4}$|^(?:[\da-f]{4}:){3}[\da-f]{4}$/iu; +/** + * [Octal](https://en.wikipedia.org/wiki/Octal) regex. + */ +export const OCTAL_REGEX = /^(0o)?[0-7]+$/iu; + /** * [ULID](https://github.com/ulid/spec) regex. */ @@ -102,8 +107,3 @@ export const ULID_REGEX = /^[\da-hjkmnp-tv-z]{26}$/iu; * [UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier) regex. */ export const UUID_REGEX = /^[\da-f]{8}(?:-[\da-f]{4}){3}-[\da-f]{12}$/iu; - -/** - * [OCTAL](https://en.wikipedia.org/wiki/Octal) regex. - */ -export const OCTAL_REGEX = /^(0o)?[0-7]+$/iu; diff --git a/library/src/validations/octal/octal.test.ts b/library/src/validations/octal/octal.test.ts index a7fe36557..6365c475e 100644 --- a/library/src/validations/octal/octal.test.ts +++ b/library/src/validations/octal/octal.test.ts @@ -4,29 +4,25 @@ import { octal } from './octal.ts'; describe('octal', () => { test('should pass only valid strings', () => { const validate = octal(); + const value = '123'; expect(validate._parse(value).output).toBe(value); - const value2 = '001'; expect(validate._parse(value2).output).toBe(value2); - const value3 = '765'; expect(validate._parse(value3).output).toBe(value3); - const value4 = '000'; expect(validate._parse(value4).output).toBe(value4); - const value5 = '111'; expect(validate._parse(value5).output).toBe(value5); - const value6 = '020'; expect(validate._parse(value6).output).toBe(value6); - const value7 = '707'; expect(validate._parse(value7).output).toBe(value7); - const value8 = '00012345'; expect(validate._parse(value8).output).toBe(value8); + const value9 = '0o12345'; + expect(validate._parse(value9).output).toBe(value9); expect(validate._parse('').issues).toBeTruthy(); expect(validate._parse('8').issues).toBeTruthy(); diff --git a/library/src/validations/octal/octal.ts b/library/src/validations/octal/octal.ts index 98ba934af..ea8c9805b 100644 --- a/library/src/validations/octal/octal.ts +++ b/library/src/validations/octal/octal.ts @@ -11,13 +11,13 @@ export type OctalValidation = BaseValidation & { */ type: 'octal'; /** - * The Octal regex. + * The octal regex. */ requirement: RegExp; }; /** - * Creates a validation function that validates an [OCTAL](https://en.wikipedia.org/wiki/Octal) string. + * Creates a validation function that validates an [octal](https://en.wikipedia.org/wiki/Octal) string. * * @param message The error message. * diff --git a/website/src/routes/api/(schemas)/any/index.mdx b/website/src/routes/api/(schemas)/any/index.mdx index 770546e30..b3e3906f6 100644 --- a/website/src/routes/api/(schemas)/any/index.mdx +++ b/website/src/routes/api/(schemas)/any/index.mdx @@ -110,6 +110,7 @@ The following APIs can be combined with `any`. 'notLength', 'notSize', 'notValue', + 'octal', 'regex', 'safeInteger', 'size', diff --git a/website/src/routes/api/(schemas)/string/index.mdx b/website/src/routes/api/(schemas)/string/index.mdx index 939fd9889..b36cf62ce 100644 --- a/website/src/routes/api/(schemas)/string/index.mdx +++ b/website/src/routes/api/(schemas)/string/index.mdx @@ -150,6 +150,7 @@ The following APIs can be combined with `string`. 'notBytes', 'notLength', 'notValue', + 'octal', 'regex', 'startsWith', 'ulid',