Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add gtValue action #978

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
669 changes: 669 additions & 0 deletions library/src/actions/gtValue/gtValue.test.ts

Large diffs are not rendered by default.

127 changes: 127 additions & 0 deletions library/src/actions/gtValue/gtValue.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
import type {
BaseIssue,
BaseValidation,
ErrorMessage,
} from '../../types/index.ts';
import { _addIssue, _stringify } from '../../utils/index.ts';
import type { ValueInput } from '../types.ts';

/**
* Greater than value issue type.
*/
export interface GtValueIssue<
TInput extends ValueInput,
TRequirement extends TInput,
> extends BaseIssue<TInput> {
/**
* The issue kind.
*/
readonly kind: 'validation';
/**
* The issue type.
*/
readonly type: 'gt_value';
/**
* The expected property.
*/
readonly expected: `>${string}`;
/**
* The greater than value.
*/
readonly requirement: TRequirement;
}

/**
* Greater than value action type.
*/
export interface GtValueAction<
TInput extends ValueInput,
TRequirement extends TInput,
TMessage extends ErrorMessage<GtValueIssue<TInput, TRequirement>> | undefined,
> extends BaseValidation<TInput, TInput, GtValueIssue<TInput, TRequirement>> {
/**
* The action type.
*/
readonly type: 'gt_value';
/**
* The action reference.
*/
readonly reference: typeof gtValue;
/**
* The expected property.
*/
readonly expects: `>${string}`;
/**
* The greater than value.
*/
readonly requirement: TRequirement;
/**
* The error message.
*/
readonly message: TMessage;
}

/**
* Creates a greater than value validation action.
*
* @param requirement The greater than value.
*
* @returns A greater than value action.
*/
export function gtValue<
TInput extends ValueInput,
const TRequirement extends TInput,
>(requirement: TRequirement): GtValueAction<TInput, TRequirement, undefined>;

/**
* Creates a greater than value validation action.
*
* @param requirement The greater than value.
* @param message The error message.
*
* @returns A greater than value action.
*/
export function gtValue<
TInput extends ValueInput,
const TRequirement extends TInput,
const TMessage extends
| ErrorMessage<GtValueIssue<TInput, TRequirement>>
| undefined,
>(
requirement: TRequirement,
message: TMessage
): GtValueAction<TInput, TRequirement, TMessage>;

export function gtValue(
requirement: ValueInput,
message?: ErrorMessage<GtValueIssue<ValueInput, ValueInput>>
): GtValueAction<
ValueInput,
ValueInput,
ErrorMessage<GtValueIssue<ValueInput, ValueInput>> | undefined
> {
return {
kind: 'validation',
type: 'gt_value',
reference: gtValue,
async: false,
expects: `>${
requirement instanceof Date
? requirement.toJSON()
: _stringify(requirement)
}`,
requirement,
message,
'~run'(dataset, config) {
if (dataset.typed && !(dataset.value > this.requirement)) {
_addIssue(this, 'value', dataset, config, {
received:
dataset.value instanceof Date
? dataset.value.toJSON()
: _stringify(dataset.value),
});
}
return dataset;
},
};
}
45 changes: 45 additions & 0 deletions library/src/actions/gtValue/gtValues.test-d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { describe, expectTypeOf, test } from 'vitest';
import type { InferInput, InferIssue, InferOutput } from '../../types/index.ts';
import { gtValue, type GtValueAction, type GtValueIssue } from './gtValue.ts';

describe('gtValue', () => {
describe('should return action object', () => {
test('with undefined message', () => {
type Action = GtValueAction<number, 10, undefined>;
expectTypeOf(gtValue<number, 10>(10)).toEqualTypeOf<Action>();
expectTypeOf(
gtValue<number, 10, undefined>(10, undefined)
).toEqualTypeOf<Action>();
});

test('with string message', () => {
expectTypeOf(gtValue<number, 10, 'message'>(10, 'message')).toEqualTypeOf<
GtValueAction<number, 10, 'message'>
>();
});

test('with function message', () => {
expectTypeOf(
gtValue<number, 10, () => string>(10, () => 'message')
).toEqualTypeOf<GtValueAction<number, 10, () => string>>();
});
});

describe('should infer correct types', () => {
type Action = GtValueAction<number, 10, undefined>;

test('of input', () => {
expectTypeOf<InferInput<Action>>().toEqualTypeOf<number>();
});

test('of output', () => {
expectTypeOf<InferOutput<Action>>().toEqualTypeOf<number>();
});

test('of issue', () => {
expectTypeOf<InferIssue<Action>>().toEqualTypeOf<
GtValueIssue<number, 10>
>();
});
});
});
1 change: 1 addition & 0 deletions library/src/actions/gtValue/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './gtValue.ts';
1 change: 1 addition & 0 deletions library/src/actions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export * from './filterItems/index.ts';
export * from './findItem/index.ts';
export * from './finite/index.ts';
export * from './graphemes/index.ts';
export * from './gtValue/index.ts';
export * from './hash/index.ts';
export * from './hexadecimal/index.ts';
export * from './hexColor/index.ts';
Expand Down
93 changes: 93 additions & 0 deletions website/src/routes/api/(actions)/gtValue/index.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
---
title: gtValue
description: Creates a greater than value validation action.
source: /actions/gtValue/gtValue.ts
contributors:
- EltonLobo07
---

import { ApiList, Property } from '~/components';
import { properties } from './properties';

# gtValue

Creates a greater than value validation action.

```ts
const Action = v.gtValue<TInput, TRequirement, TMessage>(requirement, message);
```

## Generics

- `TInput` <Property {...properties.TInput} />
- `TRequirement` <Property {...properties.TRequirement} />
- `TMessage` <Property {...properties.TMessage} />

## Parameters

- `requirement` <Property {...properties.requirement} />
- `message` <Property {...properties.message} />

### Explanation

With `gtValue` you can validate the value of a string, number, boolean or date. If the input does not match the `requirement`, you can use `message` to customize the error message.

## Returns

- `Action` <Property {...properties.Action} />

## Examples

The following examples show how `gtValue` can be used.

### Number schema

Schema to validate a number with a greater than value.

```ts
const NumberSchema = v.pipe(
v.number(),
v.gtValue(100, 'The number must be greater than 100.')
);
```

### Date schema

Schema to validate a date with a greater than year.

```ts
const DateSchema = v.pipe(
v.date(),
v.gtValue(
new Date('2000-01-01'),
'The date must be greater than 1st January 2000.'
)
);
```

## Related

The following APIs can be combined with `gtValue`.

### Schemas

<ApiList
items={[
'any',
'bigint',
'boolean',
'custom',
'date',
'number',
'string',
'unknown',
]}
/>

### Methods

<ApiList items={['pipe']} />

### Utils

<ApiList items={['isOfKind', 'isOfType']} />
83 changes: 83 additions & 0 deletions website/src/routes/api/(actions)/gtValue/properties.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import type { PropertyProps } from '~/components';

export const properties: Record<string, PropertyProps> = {
TInput: {
modifier: 'extends',
type: {
type: 'custom',
name: 'ValueInput',
href: '../ValueInput/',
},
},
TRequirement: {
modifier: 'extends',
type: {
type: 'custom',
name: 'TInput',
},
},
TMessage: {
modifier: 'extends',
type: {
type: 'union',
options: [
{
type: 'custom',
name: 'ErrorMessage',
href: '../ErrorMessage/',
generics: [
{
type: 'custom',
name: 'GtValueIssue',
href: '../GtValueIssue/',
generics: [
{
type: 'custom',
name: 'TInput',
},
{
type: 'custom',
name: 'TRequirement',
},
],
},
],
},
'undefined',
],
},
},
requirement: {
type: {
type: 'custom',
name: 'TRequirement',
},
},
message: {
type: {
type: 'custom',
name: 'TMessage',
},
},
Action: {
type: {
type: 'custom',
name: 'GtValueAction',
href: '../GtValueAction/',
generics: [
{
type: 'custom',
name: 'TInput',
},
{
type: 'custom',
name: 'TRequirement',
},
{
type: 'custom',
name: 'TMessage',
},
],
},
},
};
1 change: 1 addition & 0 deletions website/src/routes/api/(async)/customAsync/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ The following APIs can be combined with `customAsync`.
'findItem',
'finite',
'graphemes',
'gtValue',
'hash',
'hexadecimal',
'hexColor',
Expand Down
1 change: 1 addition & 0 deletions website/src/routes/api/(async)/fallbackAsync/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ The following APIs can be combined with `fallbackAsync`.
'findItem',
'finite',
'graphemes',
'gtValue',
'hash',
'hexadecimal',
'hexColor',
Expand Down
1 change: 1 addition & 0 deletions website/src/routes/api/(async)/intersectAsync/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ The following APIs can be combined with `intersectAsync`.
'findItem',
'finite',
'graphemes',
'gtValue',
'hash',
'hexColor',
'hexadecimal',
Expand Down
1 change: 1 addition & 0 deletions website/src/routes/api/(async)/lazyAsync/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ The following APIs can be combined with `lazyAsync`.
'findItem',
'finite',
'graphemes',
'gtValue',
'hash',
'hexColor',
'hexadecimal',
Expand Down
Loading
Loading