Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: fabian-hiller/valibot
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v1.0.0-rc.1
Choose a base ref
...
head repository: fabian-hiller/valibot
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v1.0.0-rc.2
Choose a head ref
  • 14 commits
  • 19 files changed
  • 3 contributors

Commits on Feb 12, 2025

  1. improve base64 & its action's API references

    Improvements:
    	- Add a description to the `base64` page
    	- Add a missing link on the `Base64Action` page
    EltonLobo07 committed Feb 12, 2025
    Copy the full SHA
    7b2a890 View commit details

Commits on Feb 14, 2025

  1. Fix Japanese translation for grapheme

    tats-u committed Feb 14, 2025
    Copy the full SHA
    13ffb57 View commit details
  2. docs: Add warning about combining maxGraphemes with length limiters

    tats-u committed Feb 14, 2025
    Copy the full SHA
    1249079 View commit details

Commits on Feb 17, 2025

  1. Update changelog of library

    fabian-hiller committed Feb 17, 2025
    Copy the full SHA
    339a8c0 View commit details
  2. Add support for map and set to readonly action #1059

    fabian-hiller committed Feb 17, 2025
    Copy the full SHA
    3e7879b View commit details
  3. Merge pull request #1054 from EltonLobo07/doc/improve-base64-and-action

    improve `base64` & its action's API references
    fabian-hiller authored Feb 17, 2025

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    bf94242 View commit details
  4. Merge pull request #1055 from tats-u/fix-ja

    i18n: fix Japanese translation for grapheme
    fabian-hiller authored Feb 17, 2025

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    b607118 View commit details
  5. Update maxGraphemes docs with hint for stricter limit

    fabian-hiller committed Feb 17, 2025
    Copy the full SHA
    e5ce164 View commit details
  6. Merge pull request #1056 from tats-u/zalgo

    docs: Add warning about combining maxGraphemes with length limiters
    fabian-hiller authored Feb 17, 2025

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    cf95a05 View commit details

Commits on Feb 19, 2025

  1. Add @Bilboramix to funding contributors list

    fabian-hiller committed Feb 19, 2025
    Copy the full SHA
    683ad43 View commit details
  2. Add Bolt by StackBlitz to partners of Credits component

    fabian-hiller committed Feb 19, 2025
    Copy the full SHA
    979692f View commit details

Commits on Feb 25, 2025

  1. Copy the full SHA
    ff9348a View commit details
  2. Copy the full SHA
    4fa36ce View commit details
  3. Bump version of library to 1.0.0-rc.2

    fabian-hiller committed Feb 25, 2025
    Copy the full SHA
    f25b7c7 View commit details
2 changes: 1 addition & 1 deletion .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
github: [fabian-hiller, EltonLobo07]
github: [fabian-hiller, EltonLobo07, Bilboramix]
6 changes: 4 additions & 2 deletions library/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -11,9 +11,10 @@ All notable changes to the library will be documented in this file.
- Add `args` and `returns` action to transform functions (issue #243)
- Add `rfcEmail` action to validate RFC 5322 email addresses (pull request #912)
- Add `gtValue` and `ltValue` action for greater than and less than validation (pull request #978, #985)
- Add `values` and `notValues` action to validate values (pull request #919)
- Add `values` and `notValues` action for easier multi-value validation (pull request #919)
- Add `slug` action to validate URL slugs (pull request #910)
- Add `entriesFromObjects` util to improve tree shaking (issue #1023)
- Add support for `ReadonlyMap` and `ReadonlySet` to `readonly` action (issue #1059)
- Add `entriesFromObjects` util to improve tree shaking (pull request #1023)
- Add new overload signature to `pipe` and `pipeAync` method to support unlimited pipe items of same input and output type (issue #852)
- Add `@__NO_SIDE_EFFECTS__` notation to improve tree shaking (pull request #995)
- Add `exactOptional` and `exactOptionalAsync` schema (PR #1013)
@@ -32,6 +33,7 @@ All notable changes to the library will be documented in this file.
- Fix instantiation error for `any` in `PathKeys` type (issue #929)
- Fix TypeScript error of `keyof` method for objects with many keys (pull request #988)
- Fix options filtering in `enum_` schema (pull request #941)
- Fix `partialCheck` and `partialCheckAsync` action for typed data with issues

## v0.42.1 (September 20, 2024)

2 changes: 1 addition & 1 deletion library/jsr.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@valibot/valibot",
"version": "1.0.0-rc.1",
"version": "1.0.0-rc.2",
"exports": "./src/index.ts",
"publish": {
"include": ["src/**/*.ts", "README.md"],
2 changes: 1 addition & 1 deletion library/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "valibot",
"description": "The modular and type safe schema library for validating structural data",
"version": "1.0.0-rc.1",
"version": "1.0.0-rc.2",
"license": "MIT",
"author": "Fabian Hiller",
"homepage": "https://valibot.dev",
61 changes: 59 additions & 2 deletions library/src/actions/partialCheck/partialCheck.test.ts
Original file line number Diff line number Diff line change
@@ -10,6 +10,7 @@ import type {
PartialDataset,
SuccessDataset,
} from '../../types/index.ts';
import type { MinLengthIssue } from '../minLength/index.ts';
import { partialCheck, type PartialCheckAction } from './partialCheck.ts';
import type { PartialCheckIssue } from './types.ts';

@@ -221,7 +222,7 @@ describe('partialCheck', () => {
});

describe('should add issue to dataset', () => {
test('if there are no issues', () => {
test('if there are no previous issues', () => {
const input: Input = {
nested: { key: 'foo' },
tuple: [123, { key: 'baz' }, 456],
@@ -247,7 +248,63 @@ describe('partialCheck', () => {
} satisfies PartialDataset<Input, PartialCheckIssue<Selection>>);
});

test('if only unselected paths are untyped', () => {
test('if there are previous issues but the dataset is typed', () => {
const input: Input = {
nested: { key: 'foo' },
tuple: [123, { key: 'baz' }, 456],
other: 'bar',
};
const firstIssue: MinLengthIssue<string, 5> = {
...baseInfo,
kind: 'validation',
type: 'min_length',
input: 'foo',
expected: '>=5',
received: '3',
requirement: 5,
path: [
{
type: 'object',
origin: 'value',
input,
key: 'nested',
value: input.nested,
},
{
type: 'object',
origin: 'value',
input: input.nested,
key: 'key',
value: input.nested.key,
},
],
};
const dataset: PartialDataset<Input, MinLengthIssue<string, 5>> = {
typed: true,
value: input,
issues: [firstIssue],
};
expect(action['~run'](dataset, {})).toStrictEqual({
...dataset,
issues: [
firstIssue,
{
...baseInfo,
kind: 'validation',
type: 'partial_check',
input: input,
expected: null,
received: 'Object',
requirement,
},
],
} satisfies PartialDataset<
Input,
MinLengthIssue<string, 5> | PartialCheckIssue<Selection>
>);
});

test('if there are previous issues but only with unrelated paths', () => {
const input: {
nested: { key: string };
tuple: [number, { key: string }, null];
2 changes: 1 addition & 1 deletion library/src/actions/partialCheck/partialCheck.ts
Original file line number Diff line number Diff line change
@@ -104,7 +104,7 @@ export function partialCheck(
message,
'~run'(dataset, config) {
if (
_isPartiallyTyped(dataset, pathList) &&
(dataset.typed || _isPartiallyTyped(dataset, pathList)) &&
// @ts-expect-error
!this.requirement(dataset.value)
) {
61 changes: 59 additions & 2 deletions library/src/actions/partialCheck/partialCheckAsync.test.ts
Original file line number Diff line number Diff line change
@@ -10,6 +10,7 @@ import type {
PartialDataset,
SuccessDataset,
} from '../../types/index.ts';
import type { MinLengthIssue } from '../minLength/index.ts';
import {
type PartialCheckActionAsync,
partialCheckAsync,
@@ -234,7 +235,7 @@ describe('partialCheckAsync', () => {
});

describe('should add issue to dataset', () => {
test('if there are no issues', async () => {
test('if there are no previous issues', async () => {
const input: Input = {
nested: { key: 'foo' },
tuple: [123, { key: 'baz' }, 456],
@@ -260,7 +261,63 @@ describe('partialCheckAsync', () => {
} satisfies PartialDataset<Input, PartialCheckIssue<Selection>>);
});

test('if only unselected paths are untyped', async () => {
test('if there are previous issues but the dataset is typed', async () => {
const input: Input = {
nested: { key: 'foo' },
tuple: [123, { key: 'baz' }, 456],
other: 'bar',
};
const firstIssue: MinLengthIssue<string, 5> = {
...baseInfo,
kind: 'validation',
type: 'min_length',
input: 'foo',
expected: '>=5',
received: '3',
requirement: 5,
path: [
{
type: 'object',
origin: 'value',
input,
key: 'nested',
value: input.nested,
},
{
type: 'object',
origin: 'value',
input: input.nested,
key: 'key',
value: input.nested.key,
},
],
};
const dataset: PartialDataset<Input, MinLengthIssue<string, 5>> = {
typed: true,
value: input,
issues: [firstIssue],
};
expect(await action['~run'](dataset, {})).toStrictEqual({
...dataset,
issues: [
firstIssue,
{
...baseInfo,
kind: 'validation',
type: 'partial_check',
input: input,
expected: null,
received: 'Object',
requirement,
},
],
} satisfies PartialDataset<
Input,
MinLengthIssue<string, 5> | PartialCheckIssue<Selection>
>);
});

test('if there are previous issues but only with unrelated paths', async () => {
const input: {
nested: { key: string };
tuple: [number, { key: string }, null];
2 changes: 1 addition & 1 deletion library/src/actions/partialCheck/partialCheckAsync.ts
Original file line number Diff line number Diff line change
@@ -105,7 +105,7 @@ export function partialCheckAsync(
message,
async '~run'(dataset, config) {
if (
_isPartiallyTyped(dataset, pathList) &&
(dataset.typed || _isPartiallyTyped(dataset, pathList)) &&
// @ts-expect-error
!(await this.requirement(dataset.value))
) {
39 changes: 32 additions & 7 deletions library/src/actions/readonly/readonly.test-d.ts
Original file line number Diff line number Diff line change
@@ -3,25 +3,50 @@ import type { InferInput, InferIssue, InferOutput } from '../../types/index.ts';
import { readonly, type ReadonlyAction } from './readonly.ts';

describe('readonly', () => {
// eslint-disable-next-line @typescript-eslint/consistent-type-definitions
type Input = { key: string };
type Action = ReadonlyAction<Input>;

test('should return action object', () => {
// eslint-disable-next-line @typescript-eslint/consistent-type-definitions
type Input = { key: string };
type Action = ReadonlyAction<Input>;
expectTypeOf(readonly<Input>()).toEqualTypeOf<Action>();
});

describe('should infer correct types', () => {
// eslint-disable-next-line @typescript-eslint/consistent-type-definitions
type Input1 = { for: string; bar: number };
type Action1 = ReadonlyAction<Input1>;
type Input2 = [string, number];
type Action2 = ReadonlyAction<Input2>;
type Input3 = Map<string, number>;
type Action3 = ReadonlyAction<Input3>;
type Input4 = Set<string>;
type Action4 = ReadonlyAction<Input4>;

test('of input', () => {
expectTypeOf<InferInput<Action>>().toEqualTypeOf<Input>();
expectTypeOf<InferInput<Action1>>().toEqualTypeOf<Input1>();
expectTypeOf<InferInput<Action2>>().toEqualTypeOf<Input2>();
expectTypeOf<InferInput<Action3>>().toEqualTypeOf<Input3>();
expectTypeOf<InferInput<Action4>>().toEqualTypeOf<Input4>();
});

test('of output', () => {
expectTypeOf<InferOutput<Action>>().toEqualTypeOf<Readonly<Input>>();
expectTypeOf<InferOutput<Action1>>().toEqualTypeOf<{
readonly for: string;
readonly bar: number;
}>();
expectTypeOf<InferOutput<Action2>>().toEqualTypeOf<
readonly [string, number]
>();
expectTypeOf<InferOutput<Action3>>().toEqualTypeOf<
ReadonlyMap<string, number>
>();
expectTypeOf<InferOutput<Action4>>().toEqualTypeOf<ReadonlySet<string>>();
});

test('of issue', () => {
expectTypeOf<InferIssue<Action>>().toEqualTypeOf<never>();
expectTypeOf<InferIssue<Action1>>().toEqualTypeOf<never>();
expectTypeOf<InferIssue<Action2>>().toEqualTypeOf<never>();
expectTypeOf<InferIssue<Action3>>().toEqualTypeOf<never>();
expectTypeOf<InferIssue<Action4>>().toEqualTypeOf<never>();
});
});
});
20 changes: 16 additions & 4 deletions library/src/actions/readonly/readonly.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
import type { BaseTransformation } from '../../types/index.ts';
import type { BaseTransformation, SuccessDataset } from '../../types/index.ts';

/**
* Readonly output type.
*/
type ReadonlyOutput<TInput> =
TInput extends Map<infer TKey, infer TValue>
? ReadonlyMap<TKey, TValue>
: TInput extends Set<infer TValue>
? ReadonlySet<TValue>
: Readonly<TInput>;

/**
* Readonly action interface.
*/
export interface ReadonlyAction<TInput>
extends BaseTransformation<TInput, Readonly<TInput>, never> {
extends BaseTransformation<TInput, ReadonlyOutput<TInput>, never> {
/**
* The action type.
*/
@@ -20,15 +30,17 @@ export interface ReadonlyAction<TInput>
*
* @returns A readonly action.
*/
export function readonly<TInput>(): ReadonlyAction<TInput>;

// @__NO_SIDE_EFFECTS__
export function readonly<TInput>(): ReadonlyAction<TInput> {
export function readonly(): ReadonlyAction<unknown> {
return {
kind: 'transformation',
type: 'readonly',
reference: readonly,
async: false,
'~run'(dataset) {
return dataset;
return dataset as SuccessDataset<Readonly<unknown>>;
},
};
}
23 changes: 11 additions & 12 deletions library/src/utils/entriesFromObjects/entriesFromObjects.ts
Original file line number Diff line number Diff line change
@@ -73,21 +73,20 @@ type MergeEntries<
/**
* Recursive merge type.
*/
type RecursiveMerge<TSchemas extends [Schema, ...Schema[]]> = TSchemas extends [
infer TFirstSchema extends Schema,
]
? TFirstSchema['entries']
: TSchemas extends [
infer TFirstSchema extends Schema,
...infer TRestSchemas extends [Schema, ...Schema[]],
]
? MergeEntries<TFirstSchema['entries'], RecursiveMerge<TRestSchemas>>
: never;
type RecursiveMerge<TSchemas extends readonly [Schema, ...Schema[]]> =
TSchemas extends readonly [infer TFirstSchema extends Schema]
? TFirstSchema['entries']
: TSchemas extends readonly [
infer TFirstSchema extends Schema,
...infer TRestSchemas extends readonly [Schema, ...Schema[]],
]
? MergeEntries<TFirstSchema['entries'], RecursiveMerge<TRestSchemas>>
: never;

/**
* Merged entries types.
*/
type MergedEntries<TSchemas extends [Schema, ...Schema[]]> = Prettify<
type MergedEntries<TSchemas extends readonly [Schema, ...Schema[]]> = Prettify<
RecursiveMerge<TSchemas>
>;

@@ -101,7 +100,7 @@ type MergedEntries<TSchemas extends [Schema, ...Schema[]]> = Prettify<
* @beta
*/
export function entriesFromObjects<
const TSchemas extends [Schema, ...Schema[]],
const TSchemas extends readonly [Schema, ...Schema[]],
>(schemas: TSchemas): MergedEntries<TSchemas>;

// @__NO_SIDE_EFFECTS__
8 changes: 4 additions & 4 deletions packages/i18n/src/ja.ts
Original file line number Diff line number Diff line change
@@ -23,7 +23,7 @@ const language: Language = {
everyItem: (issue) => `無効な項目: ${issue.received} を受け取りました`,
excludes: (issue) => `無効な内容: ${issue.expected} を期待しましたが、 ${issue.received} を受け取りました`,
finite: (issue) => `無効な有限数: ${issue.received} を受け取りました`,
graphemes: (issue) => `無効なグラフェム数: ${issue.expected} を期待しましたが、 ${issue.received} を受け取りました`,
graphemes: (issue) => `無効な書記素数: ${issue.expected} を期待しましたが、 ${issue.received} を受け取りました`,
hash: (issue) => `無効なハッシュ値: ${issue.received} を受け取りました`,
hexColor: (issue) => `無効な16進数カラーコード: ${issue.received} を受け取りました`,
hexadecimal: (issue) => `無効な16進数: ${issue.received} を受け取りました`,
@@ -44,14 +44,14 @@ const language: Language = {
mac48: (issue) => `無効な48-bit MACアドレス: ${issue.received} を受け取りました`,
mac64: (issue) => `無効な64-bit MACアドレス: ${issue.received} を受け取りました`,
maxBytes: (issue) => `無効なバイト数: ${issue.expected} を期待しましたが、 ${issue.received} を受け取りました`,
maxGraphemes: (issue) => `無効なグラフェム数: ${issue.expected} を期待しましたが、 ${issue.received} を受け取りました`,
maxGraphemes: (issue) => `無効な書記素数: ${issue.expected} を期待しましたが、 ${issue.received} を受け取りました`,
maxLength: (issue) => `無効な長さ: ${issue.expected} を期待しましたが、 ${issue.received} を受け取りました`,
maxSize: (issue) => `無効なサイズ: ${issue.expected} を期待しましたが、 ${issue.received} を受け取りました`,
maxValue: (issue) => `無効な値: ${issue.expected} を期待しましたが、 ${issue.received} を受け取りました`,
maxWords: (issue) => `無効な単語数: ${issue.expected} を期待しましたが、 ${issue.received} を受け取りました`,
mimeType: (issue) => `無効なMIME type: ${issue.expected} を期待しましたが、 ${issue.received} を受け取りました`,
minBytes: (issue) => `無効なバイト数: ${issue.expected} を期待しましたが、 ${issue.received} を受け取りました`,
minGraphemes: (issue) => `無効なグラフェム数: ${issue.expected} を期待しましたが、 ${issue.received} を受け取りました`,
minGraphemes: (issue) => `無効な書記素数: ${issue.expected} を期待しましたが、 ${issue.received} を受け取りました`,
minLength: (issue) => `無効な長さ: ${issue.expected} を期待しましたが、 ${issue.received} を受け取りました`,
minSize: (issue) => `無効なサイズ: ${issue.expected} を期待しましたが、 ${issue.received} を受け取りました`,
minValue: (issue) => `無効な値: ${issue.expected} を期待しましたが、 ${issue.received} を受け取りました`,
@@ -60,7 +60,7 @@ const language: Language = {
nanoid: (issue) => `無効なNano ID: ${issue.received} を受け取りました`,
nonEmpty: (issue) => `無効な長さ: ${issue.expected} を期待しましたが、 ${issue.received} を受け取りました`,
notBytes: (issue) => `無効なバイト数: ${issue.expected} を期待しましたが、 ${issue.received} を受け取りました`,
notGraphemes: (issue) => `無効なグラフェム数: ${issue.expected} を期待しましたが、 ${issue.received} を受け取りました`,
notGraphemes: (issue) => `無効な書記素数: ${issue.expected} を期待しましたが、 ${issue.received} を受け取りました`,
notLength: (issue) => `無効な長さ: ${issue.expected} を期待しましたが、 ${issue.received} を受け取りました`,
notSize: (issue) => `無効なサイズ: ${issue.expected} を期待しましたが、 ${issue.received} を受け取りました`,
notValue: (issue) => `無効な値: ${issue.expected} を期待しましたが、 ${issue.received} を受け取りました`,
2 changes: 2 additions & 0 deletions website/src/components/Credits.tsx
Original file line number Diff line number Diff line change
@@ -2,6 +2,7 @@ import { component$ } from '@builder.io/qwik';
import { useDocumentHead } from '@builder.io/qwik-city';
import {
AlgoliaLogo,
BoltLogo,
BuilderLogo,
DailyDevLogo,
DigitalOceanLogo,
@@ -60,6 +61,7 @@ export const Credits = component$(() => {
<ul class="mt-4 flex flex-wrap gap-x-6 gap-y-3 md:mt-5 md:gap-x-8 md:gap-y-4 lg:mt-6 lg:gap-x-10 lg:gap-y-5">
{[
{ Logo: PaceLogo, href: 'https://www.pace.edu' },
{ Logo: BoltLogo, href: 'https://bolt.new/' },
{ Logo: BuilderLogo, href: 'https://www.builder.io' },
{ Logo: HdmLogo, href: 'https://www.hdm-stuttgart.de' },
{ Logo: DailyDevLogo, href: 'https://daily.dev/' },
23 changes: 23 additions & 0 deletions website/src/logos/BoltLogo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { component$, type HTMLAttributes } from '@builder.io/qwik';
import clsx from 'clsx';

export const BoltLogo = component$<HTMLAttributes<SVGSVGElement>>(
({ class: className, ...props }) => (
<svg
viewBox="0 0 132 64"
role="img"
aria-label="Bolt logo"
class={clsx('text-[#0a0a0a] dark:text-white', className)}
fill="currentColor"
{...props}
>
<path d="M42.14 38.57c-7.38 0-11.14-4.3-11.14-9.68a12.2 12.2 0 0 1 12.47-12.14c7.39 0 11.14 4.3 11.14 9.68a12.2 12.2 0 0 1-12.47 12.14Zm.3-6.84c2.59 0 4.23-2.33 4.23-4.91 0-2.07-1.34-3.23-3.5-3.23-2.59 0-4.23 2.33-4.23 4.9 0 2.07 1.34 3.24 3.5 3.24Zm20.03 6.32H54.7l6.35-28.7h7.77l-6.35 28.7Z" />
<path
clip-rule="evenodd"
fill-rule="evenodd"
d="M19.23 38.57c-2.38 0-4.7-.86-6.04-2.71l-.48 2.18L4 42.66l.94-4.62 6.35-28.7h7.77L16.8 19.46c1.81-1.98 3.5-2.71 5.66-2.71 4.66 0 7.77 3.05 7.77 8.65 0 5.77-3.59 13.17-11.01 13.17Zm2.98-11.54c0 2.67-1.9 4.7-4.36 4.7a4.62 4.62 0 0 1-3.46-1.42L15.6 25a4.4 4.4 0 0 1 3.15-1.42 3.38 3.38 0 0 1 3.46 3.45Z"
/>
<path d="M76.9 38.57c-4.49 0-7.68-1.64-7.68-5.25 0-.3.04-1.03.17-1.64l1.69-7.7h-3.46l1.51-6.72h3.46l1.25-5.68L82.54 8l-.93 3.6-1.25 5.66h4.23l-1.51 6.72h-4.23l-1.13 5.08c-.08.39-.13.82-.13.99 0 .99.6 1.68 1.95 1.68.38 0 .95-.13 1.07-.22v6.2c-.82.56-2.28.86-3.7.86Zm9.58.47a1.92 1.92 0 0 1-1.89-1.93 2.3 2.3 0 0 1 2.28-2.26c1.06 0 1.9.88 1.9 1.93a2.3 2.3 0 0 1-2.29 2.26Zm13.24-.26H96.2l1.09-4.94c.04-.18.12-.49.12-.72 0-.64-.57-.88-1.14-.88-.76 0-1.28.4-1.65.72l-1.3 5.82h-3.5l2.08-9.4h3.52l-.26 1.07a4.16 4.16 0 0 1 2.97-1.3c1.97 0 3.1 1.07 3.1 2.47 0 .16-.06.59-.1.76l-1.42 6.4Zm7.28.24c-3.04 0-5.15-1.52-5.15-4.28 0-3 2.3-5.59 5.6-5.59 2.35 0 4.42 1.42 4.42 4.28 0 .64-.12 1.38-.22 1.73h-6.32v.02c0 .14.56 1.17 1.93 1.17a4.2 4.2 0 0 0 2.05-.47l1.07 2.28c-.95.6-2.24.86-3.37.86Zm-1.34-6.08h3.1v-.05c0-.28-.33-1.07-1.44-1.07a1.8 1.8 0 0 0-1.66 1.13Zm18.46 5.84h-3.82l-.4-5.25-2.67 5.25h-3.82l-.65-9.4h3.52l.1 5.18 2.8-5.18h3.15l.48 5.18 2.4-5.18h3.73l-4.82 9.4Zm-95.6 15.09V47.9h1.06v2.23h.04a1.45 1.45 0 0 1 .63-.67c.18-.09.4-.13.65-.13a1.72 1.72 0 0 1 1.61 1.04c.17.35.25.77.25 1.26 0 .5-.08.91-.24 1.26-.17.34-.39.6-.67.78-.27.18-.59.28-.94.28a1.3 1.3 0 0 1-1.05-.44 2 2 0 0 1-.24-.35h-.06v.7h-1.04Zm1.04-2.24c0 .29.04.54.12.76a1 1 0 0 0 .36.5c.16.13.35.19.57.19.24 0 .43-.06.59-.19.16-.12.28-.3.36-.51.08-.22.12-.47.12-.75s-.04-.53-.12-.74c-.08-.22-.2-.39-.36-.51a.93.93 0 0 0-.59-.18.93.93 0 0 0-.57.17 1.1 1.1 0 0 0-.36.5 2.2 2.2 0 0 0-.12.76Zm4.6 3.92a2.15 2.15 0 0 1-.69-.12l.25-.82c.15.05.29.07.41.07a.5.5 0 0 0 .32-.12.8.8 0 0 0 .24-.36l.09-.24-1.63-4.57h1.12l1.04 3.38h.04l1.04-3.38h1.13l-1.8 5.02c-.09.24-.2.44-.33.6-.14.18-.31.3-.51.4-.2.09-.44.14-.72.14Zm13.16-3.33a.1.1 0 0 0-.1-.14h-3.48a.1.1 0 0 1-.08-.18l6.56-7.06c.08-.08.22 0 .18.11l-1.67 4.64a.1.1 0 0 0 .1.14h3.48c.1 0 .14.12.08.18l-6.57 7.06c-.08.08-.22 0-.18-.11l1.68-4.64Zm9.72.76 1.46-.84c.27.6.72 1.01 1.56 1.01.8 0 1-.3 1-.59 0-.45-.42-.63-1.53-.93-1.1-.3-2.18-.82-2.18-2.22 0-1.4 1.2-2.21 2.49-2.21 1.21 0 2.17.57 2.7 1.64l-1.42.82c-.26-.52-.6-.84-1.28-.84-.53 0-.8.26-.8.55 0 .34.18.57 1.34.9 1.12.34 2.38.73 2.38 2.27 0 1.4-1.15 2.24-2.75 2.24-1.56 0-2.56-.73-2.97-1.8Zm8.36-2.06v1.85c0 .45.4.49 1.1.45v1.41c-2.08.21-2.68-.4-2.68-1.86v-1.85h-.85v-1.5h.85v-.98l1.58-.47v1.45h1.1v1.5h-1.1Zm7.32-1.49v5.2h-1.6v-.49a2 2 0 0 1-1.57.64c-1.39 0-2.53-1.2-2.53-2.75s1.14-2.75 2.53-2.75a2 2 0 0 1 1.58.63v-.48h1.59Zm-1.6 2.6c0-.78-.52-1.27-1.25-1.27s-1.26.49-1.26 1.27.53 1.27 1.26 1.27 1.26-.49 1.26-1.27Zm2.49 0c0-1.55 1.2-2.75 2.8-2.75 1.04 0 1.95.53 2.4 1.33l-1.39.8a1.09 1.09 0 0 0-1.02-.59c-.69 0-1.2.49-1.2 1.2 0 .73.51 1.22 1.2 1.22.46 0 .85-.22 1.02-.59l1.4.78a2.71 2.71 0 0 1-2.4 1.35c-1.61 0-2.8-1.2-2.8-2.75Zm9.12 2.6-1.7-2.3v2.3h-1.58v-7.29h1.58v4.37l1.6-2.28h1.84l-1.92 2.6 1.98 2.6h-1.8Zm7.93-2.13c0 1.29-1.06 2.13-2.39 2.13h-3.1v-7.29h2.9c1.28 0 2.33.82 2.33 2.09 0 .6-.24 1.08-.65 1.42.56.35.91.9.91 1.65Zm-3.8-3.6v1.3h1.2c.38 0 .65-.28.65-.65a.61.61 0 0 0-.65-.65h-1.2Zm2.11 3.47c0-.4-.27-.7-.7-.7h-1.41v1.4h1.41c.43 0 .7-.3.7-.7Zm2.49-5.34h1.59v7.6h-1.6v-7.6Zm2.59 1a.95.95 0 0 1 1.9 0 .95.95 0 0 1-1.9 0Zm.16 1.4h1.59v5.2h-1.6v-5.2Zm4.76 1.49v1.85c0 .45.4.49 1.1.45v1.41c-2.08.21-2.69-.4-2.69-1.86v-1.85h-.84v-1.5h.84v-.98l1.6-.47v1.45h1.08v1.5h-1.09Zm6.07 2.25v1.46h-4.24V53.6l2-2.7h-1.9v-1.46h4.03v1.04l-2 2.7h2.1Z" />
</svg>
)
);
1 change: 1 addition & 0 deletions website/src/logos/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from './AlgoliaLogo';
export * from './BoltLogo';
export * from './BuilderLogo';
export * from './DailyDevLogo';
export * from './DigitalOceanLogo';
2 changes: 2 additions & 0 deletions website/src/routes/api/(actions)/base64/index.mdx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
---
title: base64
description: Creates a Base64 validation action.
source: /actions/base64/base64.ts
contributors:
- fabian-hiller
- morinokami
- EltonLobo07
---

import { ApiList, Property } from '~/components';
3 changes: 3 additions & 0 deletions website/src/routes/api/(actions)/maxGraphemes/index.mdx
Original file line number Diff line number Diff line change
@@ -6,6 +6,7 @@ contributors:
- fabian-hiller
---

import { Link } from '@builder.io/qwik-city';
import { ApiList, Property } from '~/components';
import { properties } from './properties';

@@ -35,6 +36,8 @@ const Action = v.maxGraphemes<TInput, TRequirement, TMessage>(

With `maxGraphemes` you can validate the graphemes of a string. If the input does not match the `requirement`, you can use `message` to customize the error message.

> Hint: The number of characters per grapheme is not limited. You may want to consider combining `maxGraphemes` with <Link href="../maxLength/">`maxLength`</Link> or <Link href="../maxBytes/">`maxBytes`</Link> to set a stricter limit.
## Returns

- `Action` <Property {...properties.Action} />
1 change: 1 addition & 0 deletions website/src/routes/api/(types)/Base64Action/index.mdx
Original file line number Diff line number Diff line change
@@ -3,6 +3,7 @@ title: Base64Action
description: Base64 action interface.
contributors:
- fabian-hiller
- EltonLobo07
---

import { Property } from '~/components';
1 change: 1 addition & 0 deletions website/src/routes/api/(types)/Base64Action/properties.ts
Original file line number Diff line number Diff line change
@@ -13,6 +13,7 @@ export const properties: Record<string, PropertyProps> = {
{
type: 'custom',
name: 'ErrorMessage',
href: '../ErrorMessage/',
generics: [
{
type: 'custom',