From 9452af2d72d5871fbafb7b199d4b62cccb410326 Mon Sep 17 00:00:00 2001 From: Elton Lobo Date: Tue, 11 Feb 2025 01:26:42 +0530 Subject: [PATCH 1/6] add `base64url` action --- library/src/actions/base64url/base64url.ts | 106 +++++++++++++++++++++ library/src/actions/base64url/index.ts | 1 + library/src/actions/index.ts | 1 + library/src/regex.ts | 6 ++ 4 files changed, 114 insertions(+) create mode 100644 library/src/actions/base64url/base64url.ts create mode 100644 library/src/actions/base64url/index.ts diff --git a/library/src/actions/base64url/base64url.ts b/library/src/actions/base64url/base64url.ts new file mode 100644 index 000000000..72c437de9 --- /dev/null +++ b/library/src/actions/base64url/base64url.ts @@ -0,0 +1,106 @@ +import { BASE64URL_REGEX } from '../../regex.ts'; +import type { + BaseIssue, + BaseValidation, + ErrorMessage, +} from '../../types/index.ts'; +import { _addIssue } from '../../utils/index.ts'; + +/** + * Base64url issue interface. + */ +export interface Base64urlIssue + extends BaseIssue { + /** + * The issue kind. + */ + readonly kind: 'validation'; + /** + * The issue type. + */ + readonly type: 'base64url'; + /** + * The expected property. + */ + readonly expected: null; + /** + * The received property. + */ + readonly received: `"${string}"`; + /** + * The Base64url regex. + */ + readonly requirement: RegExp; +} + +/** + * Base64url action interface. + */ +export interface Base64urlAction< + TInput extends string, + TMessage extends ErrorMessage> | undefined, +> extends BaseValidation> { + /** + * The action type. + */ + readonly type: 'base64url'; + /** + * The action reference. + */ + readonly reference: typeof base64url; + /** + * The expected property. + */ + readonly expects: null; + /** + * The Base64url regex. + */ + readonly requirement: RegExp; + /** + * The error message. + */ + readonly message: TMessage; +} + +/** + * Creates a [base64url](https://datatracker.ietf.org/doc/html/rfc4648#section-5) validation action. + * + * @returns A base64url action. + */ +export function base64url(): Base64urlAction< + TInput, + undefined +>; + +/** + * Creates a [base64url](https://datatracker.ietf.org/doc/html/rfc4648#section-5) validation action. + * + * @param message The error message. + * + * @returns A base64url action. + */ +export function base64url< + TInput extends string, + const TMessage extends ErrorMessage> | undefined, +>(message: TMessage): Base64urlAction; + +// @__NO_SIDE_EFFECTS__ +export function base64url( + message?: ErrorMessage> +): Base64urlAction> | undefined> { + return { + kind: 'validation', + type: 'base64url', + reference: base64url, + async: false, + expects: null, + requirement: BASE64URL_REGEX, + message, + '~run'(dataset, config) { + if (dataset.typed && !this.requirement.test(dataset.value)) { + _addIssue(this, 'Base64url', dataset, config); + } + return dataset; + }, + }; +} diff --git a/library/src/actions/base64url/index.ts b/library/src/actions/base64url/index.ts new file mode 100644 index 000000000..0e5ed6690 --- /dev/null +++ b/library/src/actions/base64url/index.ts @@ -0,0 +1 @@ +export * from './base64url.ts'; diff --git a/library/src/actions/index.ts b/library/src/actions/index.ts index 095dd721e..097eea1be 100644 --- a/library/src/actions/index.ts +++ b/library/src/actions/index.ts @@ -1,6 +1,7 @@ export * from './args/index.ts'; export * from './await/index.ts'; export * from './base64/index.ts'; +export * from './base64url/index.ts'; export * from './bic/index.ts'; export * from './brand/index.ts'; export * from './bytes/index.ts'; diff --git a/library/src/regex.ts b/library/src/regex.ts index 3e161e9cd..d5c870738 100644 --- a/library/src/regex.ts +++ b/library/src/regex.ts @@ -4,6 +4,12 @@ export const BASE64_REGEX: RegExp = /^(?:[\da-z+/]{4})*(?:[\da-z+/]{2}==|[\da-z+/]{3}=)?$/iu; +/** + * [Base64url](https://datatracker.ietf.org/doc/html/rfc4648#section-5) regex. + */ +export const BASE64URL_REGEX: RegExp = + /^(?:[\w-]{4})*(?:[\w-]{2}(?:==)?|[\w-]{3}=?)?$/iu; + /** * [BIC](https://en.wikipedia.org/wiki/ISO_9362) regex. */ From 4332795123ec0fc380a9f39b15f1b736027d97b4 Mon Sep 17 00:00:00 2001 From: Elton Lobo Date: Wed, 12 Feb 2025 01:07:36 +0530 Subject: [PATCH 2/6] add `base64url` action's tests --- library/src/actions/base64url/base64.test.ts | 183 ++++++++++++++++++ .../src/actions/base64url/base64url.test-d.ts | 49 +++++ 2 files changed, 232 insertions(+) create mode 100644 library/src/actions/base64url/base64.test.ts create mode 100644 library/src/actions/base64url/base64url.test-d.ts diff --git a/library/src/actions/base64url/base64.test.ts b/library/src/actions/base64url/base64.test.ts new file mode 100644 index 000000000..94555e5ac --- /dev/null +++ b/library/src/actions/base64url/base64.test.ts @@ -0,0 +1,183 @@ +import { describe, expect, test } from 'vitest'; +import { BASE64URL_REGEX } from '../../regex.ts'; +import type { StringIssue } from '../../schemas/index.ts'; +import { expectActionIssue, expectNoActionIssue } from '../../vitest/index.ts'; +import { + base64url, + type Base64urlAction, + type Base64urlIssue, +} from './base64url.ts'; + +describe('base64url', () => { + describe('should return action object', () => { + const baseAction: Omit, 'message'> = { + kind: 'validation', + type: 'base64url', + reference: base64url, + expects: null, + requirement: BASE64URL_REGEX, + async: false, + '~run': expect.any(Function), + }; + + test('with undefined message', () => { + const action: Base64urlAction = { + ...baseAction, + message: undefined, + }; + expect(base64url()).toStrictEqual(action); + expect(base64url(undefined)).toStrictEqual(action); + }); + + test('with string message', () => { + expect(base64url('message')).toStrictEqual({ + ...baseAction, + message: 'message', + } satisfies Base64urlAction); + }); + + test('with function message', () => { + const message = () => 'message'; + expect(base64url(message)).toStrictEqual({ + ...baseAction, + message, + } satisfies Base64urlAction); + }); + }); + + describe('should return dataset without issues', () => { + const action = base64url(); + + test('for untyped inputs', () => { + const issues: [StringIssue] = [ + { + kind: 'schema', + type: 'string', + input: null, + expected: 'string', + received: 'null', + message: 'message', + }, + ]; + expect( + action['~run']({ typed: false, value: null, issues }, {}) + ).toStrictEqual({ + typed: false, + value: null, + issues, + }); + }); + + test('for empty string', () => { + expectNoActionIssue(action, ['']); + }); + + test('for Base64url strings', () => { + expectNoActionIssue(action, [ + // ---- Necessary valid test vectors from https://datatracker.ietf.org/doc/html/rfc4648#section-10 ---- + // 'f' + 'Zg==', + 'Zg', + // 'fo' + 'Zm8=', + 'Zm8', + // 'foo' + 'Zm9v', + // 'foob' + 'Zm9vYg==', + 'Zm9vYg', + // 'fooba' + 'Zm9vYmE=', + 'Zm9vYmE', + // 'foobar' + 'Zm9vYmFy', + // ---- Other custom tests ---- + // 每每每y + 'w7_Dv8O_eQ==', + 'w7_Dv8O_eQ', + // ~test~123v + 'fnRlc3R-MTIzdg==', + 'fnRlc3R-MTIzdg', + // valibot + 'dmFsaWJvdA==', + 'dmFsaWJvdA', + // 馃尞 + '8J-Mrg==', + '8J-Mrg', + // 1234567890 + 'MTIzNDU2Nzg5MA==', + 'MTIzNDU2Nzg5MA', + // ~`!@#$%^&*()_-+={[}]\|;:"',<.>/? + 'fmAhQCMkJV4mKigpXy0rPXtbfV1cfDs6IicsPC4-Lz8=', + 'fmAhQCMkJV4mKigpXy0rPXtbfV1cfDs6IicsPC4-Lz8', + // Hello, I am Valibot and I would like to help you validate data easily using a schema. + 'SGVsbG8sIEkgYW0gVmFsaWJvdCBhbmQgSSB3b3VsZCBsaWtlIHRvIGhlbHAgeW91IHZhbGlkYXRlIGRhdGEgZWFzaWx5IHVzaW5nIGEgc2NoZW1hLg==', + 'SGVsbG8sIEkgYW0gVmFsaWJvdCBhbmQgSSB3b3VsZCBsaWtlIHRvIGhlbHAgeW91IHZhbGlkYXRlIGRhdGEgZWFzaWx5IHVzaW5nIGEgc2NoZW1hLg', + ]); + }); + }); + + describe('should return dataset with issues', () => { + const action = base64url('message'); + const baseIssue: Omit, 'input' | 'received'> = { + kind: 'validation', + type: 'base64url', + expected: null, + message: 'message', + requirement: BASE64URL_REGEX, + }; + + test('for blank strings', () => { + expectActionIssue(action, baseIssue, [' ', '\n']); + }); + + test('for invalid chars', () => { + expectActionIssue(action, baseIssue, [ + 'foo`', // ` + 'foo~', // ~ + 'foo!', // ! + 'foo@', // @ + 'foo#', // # + 'foo$', // $ + 'foo%', // % + 'foo^', // ^ + 'foo&', // & + 'foo*', // * + 'foo(', // ( + 'foo)', // ) + 'foo+', // + + 'foo[', // [ + 'foo]', // ] + 'foo{', // { + 'foo}', // } + 'foo\\', // \ + 'foo|', // | + 'foo;', // ; + 'foo:', // : + "foo'", // ' + 'foo"', // " + 'foo,', // , + 'foo.', // . + 'foo<', // < + 'foo>', // > + 'foo?', // ? + 'foo/', // / + ]); + }); + + test('for invalid padding', () => { + expectActionIssue(action, baseIssue, [ + 'dmFsaWJvdA=', // = missing + 'dmFsaWJvdA===', // = extra + 'Zm9vYmE==', // = extra + ]); + }); + + test('for invalid length or character position', () => { + expectActionIssue(action, baseIssue, [ + '12345', // contains 5 characters + 'a==A', // `=` is used in between the characters + ]); + }); + }); +}); diff --git a/library/src/actions/base64url/base64url.test-d.ts b/library/src/actions/base64url/base64url.test-d.ts new file mode 100644 index 000000000..8c503a9dd --- /dev/null +++ b/library/src/actions/base64url/base64url.test-d.ts @@ -0,0 +1,49 @@ +import { describe, expectTypeOf, test } from 'vitest'; +import type { InferInput, InferIssue, InferOutput } from '../../types/index.ts'; +import { + base64url, + type Base64urlAction, + type Base64urlIssue, +} from './base64url.ts'; + +describe('base64url', () => { + describe('should return action object', () => { + test('with undefined message', () => { + type Action = Base64urlAction; + expectTypeOf(base64url()).toEqualTypeOf(); + expectTypeOf( + base64url(undefined) + ).toEqualTypeOf(); + }); + + test('with string message', () => { + expectTypeOf(base64url('message')).toEqualTypeOf< + Base64urlAction + >(); + }); + + test('with function message', () => { + expectTypeOf( + base64url string>(() => 'message') + ).toEqualTypeOf string>>(); + }); + }); + + describe('should infer correct types', () => { + type Action = Base64urlAction; + + test('of input', () => { + expectTypeOf>().toEqualTypeOf(); + }); + + test('of output', () => { + expectTypeOf>().toEqualTypeOf(); + }); + + test('of issue', () => { + expectTypeOf>().toEqualTypeOf< + Base64urlIssue + >(); + }); + }); +}); From e551b96633538448ec003bae6c32430a45c8c1a8 Mon Sep 17 00:00:00 2001 From: Elton Lobo Date: Thu, 13 Feb 2025 01:51:01 +0530 Subject: [PATCH 3/6] add `base64url` action's API reference --- .../routes/api/(actions)/base64url/index.mdx | 66 +++++++++++++ .../api/(actions)/base64url/properties.ts | 58 ++++++++++++ .../api/(types)/Base64urlAction/index.mdx | 27 ++++++ .../api/(types)/Base64urlAction/properties.ts | 93 +++++++++++++++++++ .../api/(types)/Base64urlIssue/index.mdx | 26 ++++++ .../api/(types)/Base64urlIssue/properties.ts | 59 ++++++++++++ website/src/routes/api/menu.md | 3 + 7 files changed, 332 insertions(+) create mode 100644 website/src/routes/api/(actions)/base64url/index.mdx create mode 100644 website/src/routes/api/(actions)/base64url/properties.ts create mode 100644 website/src/routes/api/(types)/Base64urlAction/index.mdx create mode 100644 website/src/routes/api/(types)/Base64urlAction/properties.ts create mode 100644 website/src/routes/api/(types)/Base64urlIssue/index.mdx create mode 100644 website/src/routes/api/(types)/Base64urlIssue/properties.ts diff --git a/website/src/routes/api/(actions)/base64url/index.mdx b/website/src/routes/api/(actions)/base64url/index.mdx new file mode 100644 index 000000000..045440c5d --- /dev/null +++ b/website/src/routes/api/(actions)/base64url/index.mdx @@ -0,0 +1,66 @@ +--- +title: base64url +description: Creates a base64url validation action. +source: /actions/base64url/base64url.ts +contributors: + - EltonLobo07 +--- + +import { ApiList, Property } from '~/components'; +import { properties } from './properties'; + +# base64url + +Creates a [base64url](https://datatracker.ietf.org/doc/html/rfc4648#section-5) validation action. + +```ts +const Action = v.base64url(message); +``` + +## Generics + +- `TInput` +- `TMessage` + +## Parameters + +- `message` + +### Explanation + +With `base64url` you can validate the formatting of a string. If the input is not a Base64url string, you can use `message` to customize the error message. + +## Returns + +- `Action` + +## Examples + +The following examples show how `base64url` can be used. + +### Base64url schema + +Schema to validate a Base64url string. + +```ts +const Base64urlSchema = v.pipe( + v.string(), + v.base64url('The data is badly encoded.') +); +``` + +## Related + +The following APIs can be combined with `base64url`. + +### Schemas + + + +### Methods + + + +### Utils + + diff --git a/website/src/routes/api/(actions)/base64url/properties.ts b/website/src/routes/api/(actions)/base64url/properties.ts new file mode 100644 index 000000000..d5731d9f6 --- /dev/null +++ b/website/src/routes/api/(actions)/base64url/properties.ts @@ -0,0 +1,58 @@ +import type { PropertyProps } from '~/components'; + +export const properties: Record = { + TInput: { + modifier: 'extends', + type: 'string', + }, + TMessage: { + modifier: 'extends', + type: { + type: 'union', + options: [ + { + type: 'custom', + name: 'ErrorMessage', + href: '../ErrorMessage/', + generics: [ + { + type: 'custom', + name: 'Base64urlIssue', + href: '../Base64urlIssue/', + generics: [ + { + type: 'custom', + name: 'TInput', + }, + ], + }, + ], + }, + 'undefined', + ], + }, + }, + message: { + type: { + type: 'custom', + name: 'TMessage', + }, + }, + Action: { + type: { + type: 'custom', + name: 'Base64urlAction', + href: '../Base64urlAction/', + generics: [ + { + type: 'custom', + name: 'TInput', + }, + { + type: 'custom', + name: 'TMessage', + }, + ], + }, + }, +}; diff --git a/website/src/routes/api/(types)/Base64urlAction/index.mdx b/website/src/routes/api/(types)/Base64urlAction/index.mdx new file mode 100644 index 000000000..18c08872c --- /dev/null +++ b/website/src/routes/api/(types)/Base64urlAction/index.mdx @@ -0,0 +1,27 @@ +--- +title: Base64urlAction +description: Base64url action interface. +contributors: + - EltonLobo07 +--- + +import { Property } from '~/components'; +import { properties } from './properties'; + +# Base64urlAction + +Base64url action interface. + +## Generics + +- `TInput` +- `TMessage` + +## Definition + +- `Base64urlAction` + - `type` + - `reference` + - `expects` + - `requirement` + - `message` diff --git a/website/src/routes/api/(types)/Base64urlAction/properties.ts b/website/src/routes/api/(types)/Base64urlAction/properties.ts new file mode 100644 index 000000000..0400a4f7b --- /dev/null +++ b/website/src/routes/api/(types)/Base64urlAction/properties.ts @@ -0,0 +1,93 @@ +import type { PropertyProps } from '~/components'; + +export const properties: Record = { + TInput: { + modifier: 'extends', + type: 'string', + }, + TMessage: { + modifier: 'extends', + type: { + type: 'union', + options: [ + { + type: 'custom', + name: 'ErrorMessage', + href: '../ErrorMessage/', + generics: [ + { + type: 'custom', + name: 'Base64urlIssue', + href: '../Base64urlIssue/', + generics: [ + { + type: 'custom', + name: 'TInput', + }, + ], + }, + ], + }, + 'undefined', + ], + }, + }, + BaseValidation: { + modifier: 'extends', + type: { + type: 'custom', + name: 'BaseValidation', + href: '../BaseValidation/', + generics: [ + { + type: 'custom', + name: 'TInput', + }, + { + type: 'custom', + name: 'TInput', + }, + { + type: 'custom', + name: 'Base64urlIssue', + href: '../Base64urlIssue/', + generics: [ + { + type: 'custom', + name: 'TInput', + }, + ], + }, + ], + }, + }, + type: { + type: { + type: 'string', + value: 'base64url', + }, + }, + reference: { + type: { + type: 'custom', + modifier: 'typeof', + name: 'base64url', + href: '../base64url/', + }, + }, + expects: { + type: 'null', + }, + requirement: { + type: { + type: 'custom', + name: 'RegExp', + }, + }, + message: { + type: { + type: 'custom', + name: 'TMessage', + }, + }, +}; diff --git a/website/src/routes/api/(types)/Base64urlIssue/index.mdx b/website/src/routes/api/(types)/Base64urlIssue/index.mdx new file mode 100644 index 000000000..90d38b1e5 --- /dev/null +++ b/website/src/routes/api/(types)/Base64urlIssue/index.mdx @@ -0,0 +1,26 @@ +--- +title: Base64urlIssue +description: Base64url issue interface. +contributors: + - EltonLobo07 +--- + +import { Property } from '~/components'; +import { properties } from './properties'; + +# Base64urlIssue + +Base64url issue interface. + +## Generics + +- `TInput` + +## Definition + +- `Base64urlIssue` + - `kind` + - `type` + - `expected` + - `received` + - `requirement` diff --git a/website/src/routes/api/(types)/Base64urlIssue/properties.ts b/website/src/routes/api/(types)/Base64urlIssue/properties.ts new file mode 100644 index 000000000..25cbac8ce --- /dev/null +++ b/website/src/routes/api/(types)/Base64urlIssue/properties.ts @@ -0,0 +1,59 @@ +import type { PropertyProps } from '~/components'; + +export const properties: Record = { + TInput: { + modifier: 'extends', + type: 'string', + }, + BaseIssue: { + modifier: 'extends', + type: { + type: 'custom', + name: 'BaseIssue', + href: '../BaseIssue/', + generics: [ + { + type: 'custom', + name: 'TInput', + }, + ], + }, + }, + kind: { + type: { + type: 'string', + value: 'validation', + }, + }, + type: { + type: { + type: 'string', + value: 'base64url', + }, + }, + expected: { + type: 'null', + }, + received: { + type: { + type: 'template', + parts: [ + { + type: 'string', + value: '"', + }, + 'string', + { + type: 'string', + value: '"', + }, + ], + }, + }, + requirement: { + type: { + type: 'custom', + name: 'RegExp', + }, + }, +}; diff --git a/website/src/routes/api/menu.md b/website/src/routes/api/menu.md index fa8096268..ce708b4c8 100644 --- a/website/src/routes/api/menu.md +++ b/website/src/routes/api/menu.md @@ -77,6 +77,7 @@ - [args](/api/args/) - [base64](/api/base64/) +- [base64url](/api/base64url/) - [bic](/api/bic/) - [brand](/api/brand/) - [bytes](/api/bytes/) @@ -258,6 +259,8 @@ - [AwaitActionAsync](/api/AwaitActionAsync/) - [Base64Action](/api/Base64Action/) - [Base64Issue](/api/Base64Issue/) +- [Base64urlAction](/api/Base64urlAction/) +- [Base64urlIssue](/api/Base64urlIssue/) - [BaseIssue](/api/BaseIssue/) - [BaseMetadata](/api/BaseMetadata/) - [BaseSchema](/api/BaseSchema/) From 397022dc8d113a92ab5861d9667474fc831c24c9 Mon Sep 17 00:00:00 2001 From: Elton Lobo Date: Tue, 18 Feb 2025 00:46:43 +0530 Subject: [PATCH 4/6] use camel case form of base64url & update its doc comment link --- .../{base64.test.ts => base64Url.test.ts} | 44 +++++++-------- .../src/actions/base64url/base64url.test-d.ts | 28 +++++----- library/src/actions/base64url/base64url.ts | 54 +++++++++---------- library/src/actions/base64url/index.ts | 2 +- library/src/actions/index.ts | 2 +- library/src/regex.ts | 2 +- .../routes/api/(actions)/base64url/index.mdx | 26 ++++----- .../api/(actions)/base64url/properties.ts | 8 +-- .../api/(types)/Base64urlAction/index.mdx | 10 ++-- .../api/(types)/Base64urlAction/properties.ts | 14 ++--- .../api/(types)/Base64urlIssue/index.mdx | 10 ++-- .../api/(types)/Base64urlIssue/properties.ts | 2 +- website/src/routes/api/menu.md | 6 +-- 13 files changed, 104 insertions(+), 104 deletions(-) rename library/src/actions/base64url/{base64.test.ts => base64Url.test.ts} (82%) diff --git a/library/src/actions/base64url/base64.test.ts b/library/src/actions/base64url/base64Url.test.ts similarity index 82% rename from library/src/actions/base64url/base64.test.ts rename to library/src/actions/base64url/base64Url.test.ts index 94555e5ac..686236bf6 100644 --- a/library/src/actions/base64url/base64.test.ts +++ b/library/src/actions/base64url/base64Url.test.ts @@ -1,52 +1,52 @@ import { describe, expect, test } from 'vitest'; -import { BASE64URL_REGEX } from '../../regex.ts'; +import { BASE64_URL_REGEX } from '../../regex.ts'; import type { StringIssue } from '../../schemas/index.ts'; import { expectActionIssue, expectNoActionIssue } from '../../vitest/index.ts'; import { - base64url, - type Base64urlAction, - type Base64urlIssue, -} from './base64url.ts'; + base64Url, + type Base64UrlAction, + type Base64UrlIssue, +} from './base64Url.ts'; -describe('base64url', () => { +describe('base64Url', () => { describe('should return action object', () => { - const baseAction: Omit, 'message'> = { + const baseAction: Omit, 'message'> = { kind: 'validation', - type: 'base64url', - reference: base64url, + type: 'base64_url', + reference: base64Url, expects: null, - requirement: BASE64URL_REGEX, + requirement: BASE64_URL_REGEX, async: false, '~run': expect.any(Function), }; test('with undefined message', () => { - const action: Base64urlAction = { + const action: Base64UrlAction = { ...baseAction, message: undefined, }; - expect(base64url()).toStrictEqual(action); - expect(base64url(undefined)).toStrictEqual(action); + expect(base64Url()).toStrictEqual(action); + expect(base64Url(undefined)).toStrictEqual(action); }); test('with string message', () => { - expect(base64url('message')).toStrictEqual({ + expect(base64Url('message')).toStrictEqual({ ...baseAction, message: 'message', - } satisfies Base64urlAction); + } satisfies Base64UrlAction); }); test('with function message', () => { const message = () => 'message'; - expect(base64url(message)).toStrictEqual({ + expect(base64Url(message)).toStrictEqual({ ...baseAction, message, - } satisfies Base64urlAction); + } satisfies Base64UrlAction); }); }); describe('should return dataset without issues', () => { - const action = base64url(); + const action = base64Url(); test('for untyped inputs', () => { const issues: [StringIssue] = [ @@ -118,13 +118,13 @@ describe('base64url', () => { }); describe('should return dataset with issues', () => { - const action = base64url('message'); - const baseIssue: Omit, 'input' | 'received'> = { + const action = base64Url('message'); + const baseIssue: Omit, 'input' | 'received'> = { kind: 'validation', - type: 'base64url', + type: 'base64_url', expected: null, message: 'message', - requirement: BASE64URL_REGEX, + requirement: BASE64_URL_REGEX, }; test('for blank strings', () => { diff --git a/library/src/actions/base64url/base64url.test-d.ts b/library/src/actions/base64url/base64url.test-d.ts index 8c503a9dd..bf03ecce2 100644 --- a/library/src/actions/base64url/base64url.test-d.ts +++ b/library/src/actions/base64url/base64url.test-d.ts @@ -1,36 +1,36 @@ import { describe, expectTypeOf, test } from 'vitest'; import type { InferInput, InferIssue, InferOutput } from '../../types/index.ts'; import { - base64url, - type Base64urlAction, - type Base64urlIssue, -} from './base64url.ts'; + base64Url, + type Base64UrlAction, + type Base64UrlIssue, +} from './base64Url.ts'; -describe('base64url', () => { +describe('base64Url', () => { describe('should return action object', () => { test('with undefined message', () => { - type Action = Base64urlAction; - expectTypeOf(base64url()).toEqualTypeOf(); + type Action = Base64UrlAction; + expectTypeOf(base64Url()).toEqualTypeOf(); expectTypeOf( - base64url(undefined) + base64Url(undefined) ).toEqualTypeOf(); }); test('with string message', () => { - expectTypeOf(base64url('message')).toEqualTypeOf< - Base64urlAction + expectTypeOf(base64Url('message')).toEqualTypeOf< + Base64UrlAction >(); }); test('with function message', () => { expectTypeOf( - base64url string>(() => 'message') - ).toEqualTypeOf string>>(); + base64Url string>(() => 'message') + ).toEqualTypeOf string>>(); }); }); describe('should infer correct types', () => { - type Action = Base64urlAction; + type Action = Base64UrlAction; test('of input', () => { expectTypeOf>().toEqualTypeOf(); @@ -42,7 +42,7 @@ describe('base64url', () => { test('of issue', () => { expectTypeOf>().toEqualTypeOf< - Base64urlIssue + Base64UrlIssue >(); }); }); diff --git a/library/src/actions/base64url/base64url.ts b/library/src/actions/base64url/base64url.ts index 72c437de9..b9e1aa924 100644 --- a/library/src/actions/base64url/base64url.ts +++ b/library/src/actions/base64url/base64url.ts @@ -1,4 +1,4 @@ -import { BASE64URL_REGEX } from '../../regex.ts'; +import { BASE64_URL_REGEX } from '../../regex.ts'; import type { BaseIssue, BaseValidation, @@ -7,9 +7,9 @@ import type { import { _addIssue } from '../../utils/index.ts'; /** - * Base64url issue interface. + * Base64Url issue interface. */ -export interface Base64urlIssue +export interface Base64UrlIssue extends BaseIssue { /** * The issue kind. @@ -18,7 +18,7 @@ export interface Base64urlIssue /** * The issue type. */ - readonly type: 'base64url'; + readonly type: 'base64_url'; /** * The expected property. */ @@ -28,32 +28,32 @@ export interface Base64urlIssue */ readonly received: `"${string}"`; /** - * The Base64url regex. + * The base64 url regex. */ readonly requirement: RegExp; } /** - * Base64url action interface. + * Base64Url action interface. */ -export interface Base64urlAction< +export interface Base64UrlAction< TInput extends string, - TMessage extends ErrorMessage> | undefined, -> extends BaseValidation> { + TMessage extends ErrorMessage> | undefined, +> extends BaseValidation> { /** * The action type. */ - readonly type: 'base64url'; + readonly type: 'base64_url'; /** * The action reference. */ - readonly reference: typeof base64url; + readonly reference: typeof base64Url; /** * The expected property. */ readonly expects: null; /** - * The Base64url regex. + * The base64 url regex. */ readonly requirement: RegExp; /** @@ -63,42 +63,42 @@ export interface Base64urlAction< } /** - * Creates a [base64url](https://datatracker.ietf.org/doc/html/rfc4648#section-5) validation action. + * Creates a [base64 url](https://en.wikipedia.org/wiki/Base64#URL_applications) validation action. * - * @returns A base64url action. + * @returns A base64 url action. */ -export function base64url(): Base64urlAction< +export function base64Url(): Base64UrlAction< TInput, undefined >; /** - * Creates a [base64url](https://datatracker.ietf.org/doc/html/rfc4648#section-5) validation action. + * Creates a [base64 url](https://en.wikipedia.org/wiki/Base64#URL_applications) validation action. * * @param message The error message. * - * @returns A base64url action. + * @returns A base64 url action. */ -export function base64url< +export function base64Url< TInput extends string, - const TMessage extends ErrorMessage> | undefined, ->(message: TMessage): Base64urlAction; + const TMessage extends ErrorMessage> | undefined, +>(message: TMessage): Base64UrlAction; // @__NO_SIDE_EFFECTS__ -export function base64url( - message?: ErrorMessage> -): Base64urlAction> | undefined> { +export function base64Url( + message?: ErrorMessage> +): Base64UrlAction> | undefined> { return { kind: 'validation', - type: 'base64url', - reference: base64url, + type: 'base64_url', + reference: base64Url, async: false, expects: null, - requirement: BASE64URL_REGEX, + requirement: BASE64_URL_REGEX, message, '~run'(dataset, config) { if (dataset.typed && !this.requirement.test(dataset.value)) { - _addIssue(this, 'Base64url', dataset, config); + _addIssue(this, 'Base64Url', dataset, config); } return dataset; }, diff --git a/library/src/actions/base64url/index.ts b/library/src/actions/base64url/index.ts index 0e5ed6690..3dc880965 100644 --- a/library/src/actions/base64url/index.ts +++ b/library/src/actions/base64url/index.ts @@ -1 +1 @@ -export * from './base64url.ts'; +export * from './base64Url.ts'; diff --git a/library/src/actions/index.ts b/library/src/actions/index.ts index 097eea1be..a515a4643 100644 --- a/library/src/actions/index.ts +++ b/library/src/actions/index.ts @@ -1,7 +1,7 @@ export * from './args/index.ts'; export * from './await/index.ts'; export * from './base64/index.ts'; -export * from './base64url/index.ts'; +export * from './base64Url/index.ts'; export * from './bic/index.ts'; export * from './brand/index.ts'; export * from './bytes/index.ts'; diff --git a/library/src/regex.ts b/library/src/regex.ts index d5c870738..ea97fa7ab 100644 --- a/library/src/regex.ts +++ b/library/src/regex.ts @@ -7,7 +7,7 @@ export const BASE64_REGEX: RegExp = /** * [Base64url](https://datatracker.ietf.org/doc/html/rfc4648#section-5) regex. */ -export const BASE64URL_REGEX: RegExp = +export const BASE64_URL_REGEX: RegExp = /^(?:[\w-]{4})*(?:[\w-]{2}(?:==)?|[\w-]{3}=?)?$/iu; /** diff --git a/website/src/routes/api/(actions)/base64url/index.mdx b/website/src/routes/api/(actions)/base64url/index.mdx index 045440c5d..7af232865 100644 --- a/website/src/routes/api/(actions)/base64url/index.mdx +++ b/website/src/routes/api/(actions)/base64url/index.mdx @@ -1,7 +1,7 @@ --- -title: base64url -description: Creates a base64url validation action. -source: /actions/base64url/base64url.ts +title: base64Url +description: Creates a base64 url validation action. +source: /actions/base64Url/base64Url.ts contributors: - EltonLobo07 --- @@ -9,12 +9,12 @@ contributors: import { ApiList, Property } from '~/components'; import { properties } from './properties'; -# base64url +# base64Url -Creates a [base64url](https://datatracker.ietf.org/doc/html/rfc4648#section-5) validation action. +Creates a [base64 url](https://en.wikipedia.org/wiki/Base64#URL_applications) validation action. ```ts -const Action = v.base64url(message); +const Action = v.base64Url(message); ``` ## Generics @@ -28,7 +28,7 @@ const Action = v.base64url(message); ### Explanation -With `base64url` you can validate the formatting of a string. If the input is not a Base64url string, you can use `message` to customize the error message. +With `base64Url` you can validate the formatting of a string. If the input is not a base64 url string, you can use `message` to customize the error message. ## Returns @@ -36,22 +36,22 @@ With `base64url` you can validate the formatting of a string. If the input is no ## Examples -The following examples show how `base64url` can be used. +The following examples show how `base64Url` can be used. -### Base64url schema +### Base64Url schema -Schema to validate a Base64url string. +Schema to validate a base64 url string. ```ts -const Base64urlSchema = v.pipe( +const Base64UrlSchema = v.pipe( v.string(), - v.base64url('The data is badly encoded.') + v.base64Url('The data is badly encoded.') ); ``` ## Related -The following APIs can be combined with `base64url`. +The following APIs can be combined with `base64Url`. ### Schemas diff --git a/website/src/routes/api/(actions)/base64url/properties.ts b/website/src/routes/api/(actions)/base64url/properties.ts index d5731d9f6..05fc18bfb 100644 --- a/website/src/routes/api/(actions)/base64url/properties.ts +++ b/website/src/routes/api/(actions)/base64url/properties.ts @@ -17,8 +17,8 @@ export const properties: Record = { generics: [ { type: 'custom', - name: 'Base64urlIssue', - href: '../Base64urlIssue/', + name: 'Base64UrlIssue', + href: '../Base64UrlIssue/', generics: [ { type: 'custom', @@ -41,8 +41,8 @@ export const properties: Record = { Action: { type: { type: 'custom', - name: 'Base64urlAction', - href: '../Base64urlAction/', + name: 'Base64UrlAction', + href: '../Base64UrlAction/', generics: [ { type: 'custom', diff --git a/website/src/routes/api/(types)/Base64urlAction/index.mdx b/website/src/routes/api/(types)/Base64urlAction/index.mdx index 18c08872c..9fb52f253 100644 --- a/website/src/routes/api/(types)/Base64urlAction/index.mdx +++ b/website/src/routes/api/(types)/Base64urlAction/index.mdx @@ -1,6 +1,6 @@ --- -title: Base64urlAction -description: Base64url action interface. +title: Base64UrlAction +description: Base64Url action interface. contributors: - EltonLobo07 --- @@ -8,9 +8,9 @@ contributors: import { Property } from '~/components'; import { properties } from './properties'; -# Base64urlAction +# Base64UrlAction -Base64url action interface. +Base64Url action interface. ## Generics @@ -19,7 +19,7 @@ Base64url action interface. ## Definition -- `Base64urlAction` +- `Base64UrlAction` - `type` - `reference` - `expects` diff --git a/website/src/routes/api/(types)/Base64urlAction/properties.ts b/website/src/routes/api/(types)/Base64urlAction/properties.ts index 0400a4f7b..0d52f7f58 100644 --- a/website/src/routes/api/(types)/Base64urlAction/properties.ts +++ b/website/src/routes/api/(types)/Base64urlAction/properties.ts @@ -17,8 +17,8 @@ export const properties: Record = { generics: [ { type: 'custom', - name: 'Base64urlIssue', - href: '../Base64urlIssue/', + name: 'Base64UrlIssue', + href: '../Base64UrlIssue/', generics: [ { type: 'custom', @@ -49,8 +49,8 @@ export const properties: Record = { }, { type: 'custom', - name: 'Base64urlIssue', - href: '../Base64urlIssue/', + name: 'Base64UrlIssue', + href: '../Base64UrlIssue/', generics: [ { type: 'custom', @@ -64,15 +64,15 @@ export const properties: Record = { type: { type: { type: 'string', - value: 'base64url', + value: 'base64_url', }, }, reference: { type: { type: 'custom', modifier: 'typeof', - name: 'base64url', - href: '../base64url/', + name: 'base64Url', + href: '../base64Url/', }, }, expects: { diff --git a/website/src/routes/api/(types)/Base64urlIssue/index.mdx b/website/src/routes/api/(types)/Base64urlIssue/index.mdx index 90d38b1e5..55afe840e 100644 --- a/website/src/routes/api/(types)/Base64urlIssue/index.mdx +++ b/website/src/routes/api/(types)/Base64urlIssue/index.mdx @@ -1,6 +1,6 @@ --- -title: Base64urlIssue -description: Base64url issue interface. +title: Base64UrlIssue +description: Base64Url issue interface. contributors: - EltonLobo07 --- @@ -8,9 +8,9 @@ contributors: import { Property } from '~/components'; import { properties } from './properties'; -# Base64urlIssue +# Base64UrlIssue -Base64url issue interface. +Base64Url issue interface. ## Generics @@ -18,7 +18,7 @@ Base64url issue interface. ## Definition -- `Base64urlIssue` +- `Base64UrlIssue` - `kind` - `type` - `expected` diff --git a/website/src/routes/api/(types)/Base64urlIssue/properties.ts b/website/src/routes/api/(types)/Base64urlIssue/properties.ts index 25cbac8ce..2e6be084a 100644 --- a/website/src/routes/api/(types)/Base64urlIssue/properties.ts +++ b/website/src/routes/api/(types)/Base64urlIssue/properties.ts @@ -28,7 +28,7 @@ export const properties: Record = { type: { type: { type: 'string', - value: 'base64url', + value: 'base64_url', }, }, expected: { diff --git a/website/src/routes/api/menu.md b/website/src/routes/api/menu.md index ce708b4c8..30b4c961e 100644 --- a/website/src/routes/api/menu.md +++ b/website/src/routes/api/menu.md @@ -77,7 +77,7 @@ - [args](/api/args/) - [base64](/api/base64/) -- [base64url](/api/base64url/) +- [base64Url](/api/base64Url/) - [bic](/api/bic/) - [brand](/api/brand/) - [bytes](/api/bytes/) @@ -259,8 +259,8 @@ - [AwaitActionAsync](/api/AwaitActionAsync/) - [Base64Action](/api/Base64Action/) - [Base64Issue](/api/Base64Issue/) -- [Base64urlAction](/api/Base64urlAction/) -- [Base64urlIssue](/api/Base64urlIssue/) +- [Base64UrlAction](/api/Base64UrlAction/) +- [Base64UrlIssue](/api/Base64UrlIssue/) - [BaseIssue](/api/BaseIssue/) - [BaseMetadata](/api/BaseMetadata/) - [BaseSchema](/api/BaseSchema/) From 22b568dfa78528c9538049fec44c21852e0b6d13 Mon Sep 17 00:00:00 2001 From: Elton Lobo Date: Tue, 18 Feb 2025 01:00:44 +0530 Subject: [PATCH 5/6] rename base64url related folders to base64Url form --- .../base64Url.test-d.ts} | 0 .../src/actions/base64Url/base64Url.test.ts | 183 ++++++++++++++++++ .../base64url.ts => base64Url/base64Url.ts} | 0 library/src/actions/base64Url/index.ts | 1 + .../routes/api/(actions)/base64Url/index.mdx | 66 +++++++ .../api/(actions)/base64Url/properties.ts | 58 ++++++ .../api/(types)/Base64UrlAction/index.mdx | 27 +++ .../api/(types)/Base64UrlAction/properties.ts | 93 +++++++++ .../api/(types)/Base64UrlIssue/index.mdx | 26 +++ .../api/(types)/Base64UrlIssue/properties.ts | 59 ++++++ 10 files changed, 513 insertions(+) rename library/src/actions/{base64url/base64url.test-d.ts => base64Url/base64Url.test-d.ts} (100%) create mode 100644 library/src/actions/base64Url/base64Url.test.ts rename library/src/actions/{base64url/base64url.ts => base64Url/base64Url.ts} (100%) create mode 100644 library/src/actions/base64Url/index.ts create mode 100644 website/src/routes/api/(actions)/base64Url/index.mdx create mode 100644 website/src/routes/api/(actions)/base64Url/properties.ts create mode 100644 website/src/routes/api/(types)/Base64UrlAction/index.mdx create mode 100644 website/src/routes/api/(types)/Base64UrlAction/properties.ts create mode 100644 website/src/routes/api/(types)/Base64UrlIssue/index.mdx create mode 100644 website/src/routes/api/(types)/Base64UrlIssue/properties.ts diff --git a/library/src/actions/base64url/base64url.test-d.ts b/library/src/actions/base64Url/base64Url.test-d.ts similarity index 100% rename from library/src/actions/base64url/base64url.test-d.ts rename to library/src/actions/base64Url/base64Url.test-d.ts diff --git a/library/src/actions/base64Url/base64Url.test.ts b/library/src/actions/base64Url/base64Url.test.ts new file mode 100644 index 000000000..686236bf6 --- /dev/null +++ b/library/src/actions/base64Url/base64Url.test.ts @@ -0,0 +1,183 @@ +import { describe, expect, test } from 'vitest'; +import { BASE64_URL_REGEX } from '../../regex.ts'; +import type { StringIssue } from '../../schemas/index.ts'; +import { expectActionIssue, expectNoActionIssue } from '../../vitest/index.ts'; +import { + base64Url, + type Base64UrlAction, + type Base64UrlIssue, +} from './base64Url.ts'; + +describe('base64Url', () => { + describe('should return action object', () => { + const baseAction: Omit, 'message'> = { + kind: 'validation', + type: 'base64_url', + reference: base64Url, + expects: null, + requirement: BASE64_URL_REGEX, + async: false, + '~run': expect.any(Function), + }; + + test('with undefined message', () => { + const action: Base64UrlAction = { + ...baseAction, + message: undefined, + }; + expect(base64Url()).toStrictEqual(action); + expect(base64Url(undefined)).toStrictEqual(action); + }); + + test('with string message', () => { + expect(base64Url('message')).toStrictEqual({ + ...baseAction, + message: 'message', + } satisfies Base64UrlAction); + }); + + test('with function message', () => { + const message = () => 'message'; + expect(base64Url(message)).toStrictEqual({ + ...baseAction, + message, + } satisfies Base64UrlAction); + }); + }); + + describe('should return dataset without issues', () => { + const action = base64Url(); + + test('for untyped inputs', () => { + const issues: [StringIssue] = [ + { + kind: 'schema', + type: 'string', + input: null, + expected: 'string', + received: 'null', + message: 'message', + }, + ]; + expect( + action['~run']({ typed: false, value: null, issues }, {}) + ).toStrictEqual({ + typed: false, + value: null, + issues, + }); + }); + + test('for empty string', () => { + expectNoActionIssue(action, ['']); + }); + + test('for Base64url strings', () => { + expectNoActionIssue(action, [ + // ---- Necessary valid test vectors from https://datatracker.ietf.org/doc/html/rfc4648#section-10 ---- + // 'f' + 'Zg==', + 'Zg', + // 'fo' + 'Zm8=', + 'Zm8', + // 'foo' + 'Zm9v', + // 'foob' + 'Zm9vYg==', + 'Zm9vYg', + // 'fooba' + 'Zm9vYmE=', + 'Zm9vYmE', + // 'foobar' + 'Zm9vYmFy', + // ---- Other custom tests ---- + // 每每每y + 'w7_Dv8O_eQ==', + 'w7_Dv8O_eQ', + // ~test~123v + 'fnRlc3R-MTIzdg==', + 'fnRlc3R-MTIzdg', + // valibot + 'dmFsaWJvdA==', + 'dmFsaWJvdA', + // 馃尞 + '8J-Mrg==', + '8J-Mrg', + // 1234567890 + 'MTIzNDU2Nzg5MA==', + 'MTIzNDU2Nzg5MA', + // ~`!@#$%^&*()_-+={[}]\|;:"',<.>/? + 'fmAhQCMkJV4mKigpXy0rPXtbfV1cfDs6IicsPC4-Lz8=', + 'fmAhQCMkJV4mKigpXy0rPXtbfV1cfDs6IicsPC4-Lz8', + // Hello, I am Valibot and I would like to help you validate data easily using a schema. + 'SGVsbG8sIEkgYW0gVmFsaWJvdCBhbmQgSSB3b3VsZCBsaWtlIHRvIGhlbHAgeW91IHZhbGlkYXRlIGRhdGEgZWFzaWx5IHVzaW5nIGEgc2NoZW1hLg==', + 'SGVsbG8sIEkgYW0gVmFsaWJvdCBhbmQgSSB3b3VsZCBsaWtlIHRvIGhlbHAgeW91IHZhbGlkYXRlIGRhdGEgZWFzaWx5IHVzaW5nIGEgc2NoZW1hLg', + ]); + }); + }); + + describe('should return dataset with issues', () => { + const action = base64Url('message'); + const baseIssue: Omit, 'input' | 'received'> = { + kind: 'validation', + type: 'base64_url', + expected: null, + message: 'message', + requirement: BASE64_URL_REGEX, + }; + + test('for blank strings', () => { + expectActionIssue(action, baseIssue, [' ', '\n']); + }); + + test('for invalid chars', () => { + expectActionIssue(action, baseIssue, [ + 'foo`', // ` + 'foo~', // ~ + 'foo!', // ! + 'foo@', // @ + 'foo#', // # + 'foo$', // $ + 'foo%', // % + 'foo^', // ^ + 'foo&', // & + 'foo*', // * + 'foo(', // ( + 'foo)', // ) + 'foo+', // + + 'foo[', // [ + 'foo]', // ] + 'foo{', // { + 'foo}', // } + 'foo\\', // \ + 'foo|', // | + 'foo;', // ; + 'foo:', // : + "foo'", // ' + 'foo"', // " + 'foo,', // , + 'foo.', // . + 'foo<', // < + 'foo>', // > + 'foo?', // ? + 'foo/', // / + ]); + }); + + test('for invalid padding', () => { + expectActionIssue(action, baseIssue, [ + 'dmFsaWJvdA=', // = missing + 'dmFsaWJvdA===', // = extra + 'Zm9vYmE==', // = extra + ]); + }); + + test('for invalid length or character position', () => { + expectActionIssue(action, baseIssue, [ + '12345', // contains 5 characters + 'a==A', // `=` is used in between the characters + ]); + }); + }); +}); diff --git a/library/src/actions/base64url/base64url.ts b/library/src/actions/base64Url/base64Url.ts similarity index 100% rename from library/src/actions/base64url/base64url.ts rename to library/src/actions/base64Url/base64Url.ts diff --git a/library/src/actions/base64Url/index.ts b/library/src/actions/base64Url/index.ts new file mode 100644 index 000000000..3dc880965 --- /dev/null +++ b/library/src/actions/base64Url/index.ts @@ -0,0 +1 @@ +export * from './base64Url.ts'; diff --git a/website/src/routes/api/(actions)/base64Url/index.mdx b/website/src/routes/api/(actions)/base64Url/index.mdx new file mode 100644 index 000000000..7af232865 --- /dev/null +++ b/website/src/routes/api/(actions)/base64Url/index.mdx @@ -0,0 +1,66 @@ +--- +title: base64Url +description: Creates a base64 url validation action. +source: /actions/base64Url/base64Url.ts +contributors: + - EltonLobo07 +--- + +import { ApiList, Property } from '~/components'; +import { properties } from './properties'; + +# base64Url + +Creates a [base64 url](https://en.wikipedia.org/wiki/Base64#URL_applications) validation action. + +```ts +const Action = v.base64Url(message); +``` + +## Generics + +- `TInput` +- `TMessage` + +## Parameters + +- `message` + +### Explanation + +With `base64Url` you can validate the formatting of a string. If the input is not a base64 url string, you can use `message` to customize the error message. + +## Returns + +- `Action` + +## Examples + +The following examples show how `base64Url` can be used. + +### Base64Url schema + +Schema to validate a base64 url string. + +```ts +const Base64UrlSchema = v.pipe( + v.string(), + v.base64Url('The data is badly encoded.') +); +``` + +## Related + +The following APIs can be combined with `base64Url`. + +### Schemas + + + +### Methods + + + +### Utils + + diff --git a/website/src/routes/api/(actions)/base64Url/properties.ts b/website/src/routes/api/(actions)/base64Url/properties.ts new file mode 100644 index 000000000..05fc18bfb --- /dev/null +++ b/website/src/routes/api/(actions)/base64Url/properties.ts @@ -0,0 +1,58 @@ +import type { PropertyProps } from '~/components'; + +export const properties: Record = { + TInput: { + modifier: 'extends', + type: 'string', + }, + TMessage: { + modifier: 'extends', + type: { + type: 'union', + options: [ + { + type: 'custom', + name: 'ErrorMessage', + href: '../ErrorMessage/', + generics: [ + { + type: 'custom', + name: 'Base64UrlIssue', + href: '../Base64UrlIssue/', + generics: [ + { + type: 'custom', + name: 'TInput', + }, + ], + }, + ], + }, + 'undefined', + ], + }, + }, + message: { + type: { + type: 'custom', + name: 'TMessage', + }, + }, + Action: { + type: { + type: 'custom', + name: 'Base64UrlAction', + href: '../Base64UrlAction/', + generics: [ + { + type: 'custom', + name: 'TInput', + }, + { + type: 'custom', + name: 'TMessage', + }, + ], + }, + }, +}; diff --git a/website/src/routes/api/(types)/Base64UrlAction/index.mdx b/website/src/routes/api/(types)/Base64UrlAction/index.mdx new file mode 100644 index 000000000..9fb52f253 --- /dev/null +++ b/website/src/routes/api/(types)/Base64UrlAction/index.mdx @@ -0,0 +1,27 @@ +--- +title: Base64UrlAction +description: Base64Url action interface. +contributors: + - EltonLobo07 +--- + +import { Property } from '~/components'; +import { properties } from './properties'; + +# Base64UrlAction + +Base64Url action interface. + +## Generics + +- `TInput` +- `TMessage` + +## Definition + +- `Base64UrlAction` + - `type` + - `reference` + - `expects` + - `requirement` + - `message` diff --git a/website/src/routes/api/(types)/Base64UrlAction/properties.ts b/website/src/routes/api/(types)/Base64UrlAction/properties.ts new file mode 100644 index 000000000..0d52f7f58 --- /dev/null +++ b/website/src/routes/api/(types)/Base64UrlAction/properties.ts @@ -0,0 +1,93 @@ +import type { PropertyProps } from '~/components'; + +export const properties: Record = { + TInput: { + modifier: 'extends', + type: 'string', + }, + TMessage: { + modifier: 'extends', + type: { + type: 'union', + options: [ + { + type: 'custom', + name: 'ErrorMessage', + href: '../ErrorMessage/', + generics: [ + { + type: 'custom', + name: 'Base64UrlIssue', + href: '../Base64UrlIssue/', + generics: [ + { + type: 'custom', + name: 'TInput', + }, + ], + }, + ], + }, + 'undefined', + ], + }, + }, + BaseValidation: { + modifier: 'extends', + type: { + type: 'custom', + name: 'BaseValidation', + href: '../BaseValidation/', + generics: [ + { + type: 'custom', + name: 'TInput', + }, + { + type: 'custom', + name: 'TInput', + }, + { + type: 'custom', + name: 'Base64UrlIssue', + href: '../Base64UrlIssue/', + generics: [ + { + type: 'custom', + name: 'TInput', + }, + ], + }, + ], + }, + }, + type: { + type: { + type: 'string', + value: 'base64_url', + }, + }, + reference: { + type: { + type: 'custom', + modifier: 'typeof', + name: 'base64Url', + href: '../base64Url/', + }, + }, + expects: { + type: 'null', + }, + requirement: { + type: { + type: 'custom', + name: 'RegExp', + }, + }, + message: { + type: { + type: 'custom', + name: 'TMessage', + }, + }, +}; diff --git a/website/src/routes/api/(types)/Base64UrlIssue/index.mdx b/website/src/routes/api/(types)/Base64UrlIssue/index.mdx new file mode 100644 index 000000000..55afe840e --- /dev/null +++ b/website/src/routes/api/(types)/Base64UrlIssue/index.mdx @@ -0,0 +1,26 @@ +--- +title: Base64UrlIssue +description: Base64Url issue interface. +contributors: + - EltonLobo07 +--- + +import { Property } from '~/components'; +import { properties } from './properties'; + +# Base64UrlIssue + +Base64Url issue interface. + +## Generics + +- `TInput` + +## Definition + +- `Base64UrlIssue` + - `kind` + - `type` + - `expected` + - `received` + - `requirement` diff --git a/website/src/routes/api/(types)/Base64UrlIssue/properties.ts b/website/src/routes/api/(types)/Base64UrlIssue/properties.ts new file mode 100644 index 000000000..2e6be084a --- /dev/null +++ b/website/src/routes/api/(types)/Base64UrlIssue/properties.ts @@ -0,0 +1,59 @@ +import type { PropertyProps } from '~/components'; + +export const properties: Record = { + TInput: { + modifier: 'extends', + type: 'string', + }, + BaseIssue: { + modifier: 'extends', + type: { + type: 'custom', + name: 'BaseIssue', + href: '../BaseIssue/', + generics: [ + { + type: 'custom', + name: 'TInput', + }, + ], + }, + }, + kind: { + type: { + type: 'string', + value: 'validation', + }, + }, + type: { + type: { + type: 'string', + value: 'base64_url', + }, + }, + expected: { + type: 'null', + }, + received: { + type: { + type: 'template', + parts: [ + { + type: 'string', + value: '"', + }, + 'string', + { + type: 'string', + value: '"', + }, + ], + }, + }, + requirement: { + type: { + type: 'custom', + name: 'RegExp', + }, + }, +}; From 54661037f8a3655d7e44cedead9c69b6f267fc95 Mon Sep 17 00:00:00 2001 From: Elton Lobo Date: Tue, 18 Feb 2025 01:39:23 +0530 Subject: [PATCH 6/6] remove old base64url folders --- .../src/actions/base64url/base64Url.test.ts | 183 ------------------ library/src/actions/base64url/index.ts | 1 - .../routes/api/(actions)/base64url/index.mdx | 66 ------- .../api/(actions)/base64url/properties.ts | 58 ------ .../api/(types)/Base64urlAction/index.mdx | 27 --- .../api/(types)/Base64urlAction/properties.ts | 93 --------- .../api/(types)/Base64urlIssue/index.mdx | 26 --- .../api/(types)/Base64urlIssue/properties.ts | 59 ------ 8 files changed, 513 deletions(-) delete mode 100644 library/src/actions/base64url/base64Url.test.ts delete mode 100644 library/src/actions/base64url/index.ts delete mode 100644 website/src/routes/api/(actions)/base64url/index.mdx delete mode 100644 website/src/routes/api/(actions)/base64url/properties.ts delete mode 100644 website/src/routes/api/(types)/Base64urlAction/index.mdx delete mode 100644 website/src/routes/api/(types)/Base64urlAction/properties.ts delete mode 100644 website/src/routes/api/(types)/Base64urlIssue/index.mdx delete mode 100644 website/src/routes/api/(types)/Base64urlIssue/properties.ts diff --git a/library/src/actions/base64url/base64Url.test.ts b/library/src/actions/base64url/base64Url.test.ts deleted file mode 100644 index 686236bf6..000000000 --- a/library/src/actions/base64url/base64Url.test.ts +++ /dev/null @@ -1,183 +0,0 @@ -import { describe, expect, test } from 'vitest'; -import { BASE64_URL_REGEX } from '../../regex.ts'; -import type { StringIssue } from '../../schemas/index.ts'; -import { expectActionIssue, expectNoActionIssue } from '../../vitest/index.ts'; -import { - base64Url, - type Base64UrlAction, - type Base64UrlIssue, -} from './base64Url.ts'; - -describe('base64Url', () => { - describe('should return action object', () => { - const baseAction: Omit, 'message'> = { - kind: 'validation', - type: 'base64_url', - reference: base64Url, - expects: null, - requirement: BASE64_URL_REGEX, - async: false, - '~run': expect.any(Function), - }; - - test('with undefined message', () => { - const action: Base64UrlAction = { - ...baseAction, - message: undefined, - }; - expect(base64Url()).toStrictEqual(action); - expect(base64Url(undefined)).toStrictEqual(action); - }); - - test('with string message', () => { - expect(base64Url('message')).toStrictEqual({ - ...baseAction, - message: 'message', - } satisfies Base64UrlAction); - }); - - test('with function message', () => { - const message = () => 'message'; - expect(base64Url(message)).toStrictEqual({ - ...baseAction, - message, - } satisfies Base64UrlAction); - }); - }); - - describe('should return dataset without issues', () => { - const action = base64Url(); - - test('for untyped inputs', () => { - const issues: [StringIssue] = [ - { - kind: 'schema', - type: 'string', - input: null, - expected: 'string', - received: 'null', - message: 'message', - }, - ]; - expect( - action['~run']({ typed: false, value: null, issues }, {}) - ).toStrictEqual({ - typed: false, - value: null, - issues, - }); - }); - - test('for empty string', () => { - expectNoActionIssue(action, ['']); - }); - - test('for Base64url strings', () => { - expectNoActionIssue(action, [ - // ---- Necessary valid test vectors from https://datatracker.ietf.org/doc/html/rfc4648#section-10 ---- - // 'f' - 'Zg==', - 'Zg', - // 'fo' - 'Zm8=', - 'Zm8', - // 'foo' - 'Zm9v', - // 'foob' - 'Zm9vYg==', - 'Zm9vYg', - // 'fooba' - 'Zm9vYmE=', - 'Zm9vYmE', - // 'foobar' - 'Zm9vYmFy', - // ---- Other custom tests ---- - // 每每每y - 'w7_Dv8O_eQ==', - 'w7_Dv8O_eQ', - // ~test~123v - 'fnRlc3R-MTIzdg==', - 'fnRlc3R-MTIzdg', - // valibot - 'dmFsaWJvdA==', - 'dmFsaWJvdA', - // 馃尞 - '8J-Mrg==', - '8J-Mrg', - // 1234567890 - 'MTIzNDU2Nzg5MA==', - 'MTIzNDU2Nzg5MA', - // ~`!@#$%^&*()_-+={[}]\|;:"',<.>/? - 'fmAhQCMkJV4mKigpXy0rPXtbfV1cfDs6IicsPC4-Lz8=', - 'fmAhQCMkJV4mKigpXy0rPXtbfV1cfDs6IicsPC4-Lz8', - // Hello, I am Valibot and I would like to help you validate data easily using a schema. - 'SGVsbG8sIEkgYW0gVmFsaWJvdCBhbmQgSSB3b3VsZCBsaWtlIHRvIGhlbHAgeW91IHZhbGlkYXRlIGRhdGEgZWFzaWx5IHVzaW5nIGEgc2NoZW1hLg==', - 'SGVsbG8sIEkgYW0gVmFsaWJvdCBhbmQgSSB3b3VsZCBsaWtlIHRvIGhlbHAgeW91IHZhbGlkYXRlIGRhdGEgZWFzaWx5IHVzaW5nIGEgc2NoZW1hLg', - ]); - }); - }); - - describe('should return dataset with issues', () => { - const action = base64Url('message'); - const baseIssue: Omit, 'input' | 'received'> = { - kind: 'validation', - type: 'base64_url', - expected: null, - message: 'message', - requirement: BASE64_URL_REGEX, - }; - - test('for blank strings', () => { - expectActionIssue(action, baseIssue, [' ', '\n']); - }); - - test('for invalid chars', () => { - expectActionIssue(action, baseIssue, [ - 'foo`', // ` - 'foo~', // ~ - 'foo!', // ! - 'foo@', // @ - 'foo#', // # - 'foo$', // $ - 'foo%', // % - 'foo^', // ^ - 'foo&', // & - 'foo*', // * - 'foo(', // ( - 'foo)', // ) - 'foo+', // + - 'foo[', // [ - 'foo]', // ] - 'foo{', // { - 'foo}', // } - 'foo\\', // \ - 'foo|', // | - 'foo;', // ; - 'foo:', // : - "foo'", // ' - 'foo"', // " - 'foo,', // , - 'foo.', // . - 'foo<', // < - 'foo>', // > - 'foo?', // ? - 'foo/', // / - ]); - }); - - test('for invalid padding', () => { - expectActionIssue(action, baseIssue, [ - 'dmFsaWJvdA=', // = missing - 'dmFsaWJvdA===', // = extra - 'Zm9vYmE==', // = extra - ]); - }); - - test('for invalid length or character position', () => { - expectActionIssue(action, baseIssue, [ - '12345', // contains 5 characters - 'a==A', // `=` is used in between the characters - ]); - }); - }); -}); diff --git a/library/src/actions/base64url/index.ts b/library/src/actions/base64url/index.ts deleted file mode 100644 index 3dc880965..000000000 --- a/library/src/actions/base64url/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './base64Url.ts'; diff --git a/website/src/routes/api/(actions)/base64url/index.mdx b/website/src/routes/api/(actions)/base64url/index.mdx deleted file mode 100644 index 7af232865..000000000 --- a/website/src/routes/api/(actions)/base64url/index.mdx +++ /dev/null @@ -1,66 +0,0 @@ ---- -title: base64Url -description: Creates a base64 url validation action. -source: /actions/base64Url/base64Url.ts -contributors: - - EltonLobo07 ---- - -import { ApiList, Property } from '~/components'; -import { properties } from './properties'; - -# base64Url - -Creates a [base64 url](https://en.wikipedia.org/wiki/Base64#URL_applications) validation action. - -```ts -const Action = v.base64Url(message); -``` - -## Generics - -- `TInput` -- `TMessage` - -## Parameters - -- `message` - -### Explanation - -With `base64Url` you can validate the formatting of a string. If the input is not a base64 url string, you can use `message` to customize the error message. - -## Returns - -- `Action` - -## Examples - -The following examples show how `base64Url` can be used. - -### Base64Url schema - -Schema to validate a base64 url string. - -```ts -const Base64UrlSchema = v.pipe( - v.string(), - v.base64Url('The data is badly encoded.') -); -``` - -## Related - -The following APIs can be combined with `base64Url`. - -### Schemas - - - -### Methods - - - -### Utils - - diff --git a/website/src/routes/api/(actions)/base64url/properties.ts b/website/src/routes/api/(actions)/base64url/properties.ts deleted file mode 100644 index 05fc18bfb..000000000 --- a/website/src/routes/api/(actions)/base64url/properties.ts +++ /dev/null @@ -1,58 +0,0 @@ -import type { PropertyProps } from '~/components'; - -export const properties: Record = { - TInput: { - modifier: 'extends', - type: 'string', - }, - TMessage: { - modifier: 'extends', - type: { - type: 'union', - options: [ - { - type: 'custom', - name: 'ErrorMessage', - href: '../ErrorMessage/', - generics: [ - { - type: 'custom', - name: 'Base64UrlIssue', - href: '../Base64UrlIssue/', - generics: [ - { - type: 'custom', - name: 'TInput', - }, - ], - }, - ], - }, - 'undefined', - ], - }, - }, - message: { - type: { - type: 'custom', - name: 'TMessage', - }, - }, - Action: { - type: { - type: 'custom', - name: 'Base64UrlAction', - href: '../Base64UrlAction/', - generics: [ - { - type: 'custom', - name: 'TInput', - }, - { - type: 'custom', - name: 'TMessage', - }, - ], - }, - }, -}; diff --git a/website/src/routes/api/(types)/Base64urlAction/index.mdx b/website/src/routes/api/(types)/Base64urlAction/index.mdx deleted file mode 100644 index 9fb52f253..000000000 --- a/website/src/routes/api/(types)/Base64urlAction/index.mdx +++ /dev/null @@ -1,27 +0,0 @@ ---- -title: Base64UrlAction -description: Base64Url action interface. -contributors: - - EltonLobo07 ---- - -import { Property } from '~/components'; -import { properties } from './properties'; - -# Base64UrlAction - -Base64Url action interface. - -## Generics - -- `TInput` -- `TMessage` - -## Definition - -- `Base64UrlAction` - - `type` - - `reference` - - `expects` - - `requirement` - - `message` diff --git a/website/src/routes/api/(types)/Base64urlAction/properties.ts b/website/src/routes/api/(types)/Base64urlAction/properties.ts deleted file mode 100644 index 0d52f7f58..000000000 --- a/website/src/routes/api/(types)/Base64urlAction/properties.ts +++ /dev/null @@ -1,93 +0,0 @@ -import type { PropertyProps } from '~/components'; - -export const properties: Record = { - TInput: { - modifier: 'extends', - type: 'string', - }, - TMessage: { - modifier: 'extends', - type: { - type: 'union', - options: [ - { - type: 'custom', - name: 'ErrorMessage', - href: '../ErrorMessage/', - generics: [ - { - type: 'custom', - name: 'Base64UrlIssue', - href: '../Base64UrlIssue/', - generics: [ - { - type: 'custom', - name: 'TInput', - }, - ], - }, - ], - }, - 'undefined', - ], - }, - }, - BaseValidation: { - modifier: 'extends', - type: { - type: 'custom', - name: 'BaseValidation', - href: '../BaseValidation/', - generics: [ - { - type: 'custom', - name: 'TInput', - }, - { - type: 'custom', - name: 'TInput', - }, - { - type: 'custom', - name: 'Base64UrlIssue', - href: '../Base64UrlIssue/', - generics: [ - { - type: 'custom', - name: 'TInput', - }, - ], - }, - ], - }, - }, - type: { - type: { - type: 'string', - value: 'base64_url', - }, - }, - reference: { - type: { - type: 'custom', - modifier: 'typeof', - name: 'base64Url', - href: '../base64Url/', - }, - }, - expects: { - type: 'null', - }, - requirement: { - type: { - type: 'custom', - name: 'RegExp', - }, - }, - message: { - type: { - type: 'custom', - name: 'TMessage', - }, - }, -}; diff --git a/website/src/routes/api/(types)/Base64urlIssue/index.mdx b/website/src/routes/api/(types)/Base64urlIssue/index.mdx deleted file mode 100644 index 55afe840e..000000000 --- a/website/src/routes/api/(types)/Base64urlIssue/index.mdx +++ /dev/null @@ -1,26 +0,0 @@ ---- -title: Base64UrlIssue -description: Base64Url issue interface. -contributors: - - EltonLobo07 ---- - -import { Property } from '~/components'; -import { properties } from './properties'; - -# Base64UrlIssue - -Base64Url issue interface. - -## Generics - -- `TInput` - -## Definition - -- `Base64UrlIssue` - - `kind` - - `type` - - `expected` - - `received` - - `requirement` diff --git a/website/src/routes/api/(types)/Base64urlIssue/properties.ts b/website/src/routes/api/(types)/Base64urlIssue/properties.ts deleted file mode 100644 index 2e6be084a..000000000 --- a/website/src/routes/api/(types)/Base64urlIssue/properties.ts +++ /dev/null @@ -1,59 +0,0 @@ -import type { PropertyProps } from '~/components'; - -export const properties: Record = { - TInput: { - modifier: 'extends', - type: 'string', - }, - BaseIssue: { - modifier: 'extends', - type: { - type: 'custom', - name: 'BaseIssue', - href: '../BaseIssue/', - generics: [ - { - type: 'custom', - name: 'TInput', - }, - ], - }, - }, - kind: { - type: { - type: 'string', - value: 'validation', - }, - }, - type: { - type: { - type: 'string', - value: 'base64_url', - }, - }, - expected: { - type: 'null', - }, - received: { - type: { - type: 'template', - parts: [ - { - type: 'string', - value: '"', - }, - 'string', - { - type: 'string', - value: '"', - }, - ], - }, - }, - requirement: { - type: { - type: 'custom', - name: 'RegExp', - }, - }, -};