Skip to content
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
5 changes: 5 additions & 0 deletions library/src/actions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,14 @@ export * from './sortItems/index.ts';
export * from './startsWith/index.ts';
export * from './stringifyJson/index.ts';
export * from './title/index.ts';
export * from './toBigint/index.ts';
export * from './toBoolean/index.ts';
export * from './toDate/index.ts';
export * from './toLowerCase/index.ts';
export * from './toMaxValue/index.ts';
export * from './toMinValue/index.ts';
export * from './toNumber/index.ts';
export * from './toString/index.ts';
export * from './toUpperCase/index.ts';
export * from './transform/index.ts';
export * from './trim/index.ts';
Expand Down
1 change: 1 addition & 0 deletions library/src/actions/toBigint/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './toBigint.ts';
39 changes: 39 additions & 0 deletions library/src/actions/toBigint/toBigint.test-d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { describe, expectTypeOf, test } from 'vitest';
import type { InferInput, InferIssue, InferOutput } from '../../types/index.ts';
import {
toBigint,
type ToBigintAction,
type ToBigintIssue,
} from './toBigint.ts';

describe('toBigint', () => {
describe('should return action object', () => {
test('without message', () => {
expectTypeOf(toBigint<bigint>()).toEqualTypeOf<
ToBigintAction<bigint, undefined>
>();
});

test('with message', () => {
expectTypeOf(toBigint<bigint, 'message'>('message')).toEqualTypeOf<
ToBigintAction<bigint, 'message'>
>();
});
});

describe('should infer correct types', () => {
type Action = ToBigintAction<'123', undefined>;

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

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

test('of issue', () => {
expectTypeOf<InferIssue<Action>>().toEqualTypeOf<ToBigintIssue<'123'>>();
});
});
});
98 changes: 98 additions & 0 deletions library/src/actions/toBigint/toBigint.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import { describe, expect, test } from 'vitest';
import {
toBigint,
type ToBigintAction,
type ToBigintIssue,
} from './toBigint.ts';

describe('toBigint', () => {
describe('should return action object', () => {
test('without message', () => {
expect(toBigint()).toStrictEqual({
kind: 'transformation',
type: 'to_bigint',
reference: toBigint,
async: false,
message: undefined,
'~run': expect.any(Function),
} satisfies ToBigintAction<bigint, undefined>);
});

test('with message', () => {
expect(toBigint('message')).toStrictEqual({
kind: 'transformation',
type: 'to_bigint',
reference: toBigint,
async: false,
message: 'message',
'~run': expect.any(Function),
} satisfies ToBigintAction<bigint, string>);
});
});

describe('should transform to bigint', () => {
const action = toBigint();

test('for string', () => {
expect(action['~run']({ typed: true, value: '123' }, {})).toStrictEqual({
typed: true,
value: 123n,
});
});

test('for number', () => {
expect(action['~run']({ typed: true, value: 123 }, {})).toStrictEqual({
typed: true,
value: 123n,
});
});

test('for bigint', () => {
expect(action['~run']({ typed: true, value: 123n }, {})).toStrictEqual({
typed: true,
value: 123n,
});
});

test('for boolean', () => {
expect(action['~run']({ typed: true, value: true }, {})).toStrictEqual({
typed: true,
value: 1n,
});
});
});
describe('should return dataset with issues', () => {
const action = toBigint();
const baseIssue: Omit<
ToBigintIssue<number>,
'input' | 'received' | 'message'
> = {
kind: 'transformation',
type: 'to_bigint',
expected: null,
};

test('for invalid inputs', () => {
const value = Symbol();
// @ts-expect-error
expect(action['~run']({ typed: true, value }, {})).toStrictEqual({
typed: false,
value,
issues: [
{
...baseIssue,
input: value,
received: 'symbol',
message: 'Invalid bigint: Received symbol',
requirement: undefined,
path: undefined,
issues: undefined,
lang: undefined,
abortEarly: undefined,
abortPipeEarly: undefined,
},
],
});
});
});
});
97 changes: 97 additions & 0 deletions library/src/actions/toBigint/toBigint.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import type {
BaseIssue,
BaseTransformation,
ErrorMessage,
OutputDataset,
} from '../../types/index.ts';
import { _addIssue } from '../../utils/index.ts';

type BigIntInput = Parameters<typeof BigInt>[0];

/**
* To bigint issue interface.
*/
export interface ToBigintIssue<TInput extends BigIntInput>
extends BaseIssue<TInput> {
/**
* The issue kind.
*/
readonly kind: 'transformation';
/**
* The issue type.
*/
readonly type: 'to_bigint';
/**
* The expected property.
*/
readonly expected: null;
}

/**
* To bigint action interface.
*/
export interface ToBigintAction<
TInput extends BigIntInput,
TMessage extends ErrorMessage<ToBigintIssue<TInput>> | undefined,
> extends BaseTransformation<TInput, bigint, ToBigintIssue<TInput>> {
/**
* The action type.
*/
readonly type: 'to_bigint';
/**
* The action reference.
*/
readonly reference: typeof toBigint;
/**
* The error message.
*/
readonly message: TMessage;
}

/**
* Creates a to bigint transformation action.
*
* @returns A to bigint action.
*/
export function toBigint<TInput extends BigIntInput>(): ToBigintAction<
TInput,
undefined
>;

/**
* Creates a to bigint transformation action.
*
* @param message The error message.
*
* @returns A to bigint action.
*/
export function toBigint<
TInput extends BigIntInput,
const TMessage extends ErrorMessage<ToBigintIssue<TInput>> | undefined,
>(message: TMessage): ToBigintAction<TInput, TMessage>;

// @__NO_SIDE_EFFECTS__
export function toBigint(
message?: ErrorMessage<ToBigintIssue<BigIntInput>>
): ToBigintAction<
BigIntInput,
ErrorMessage<ToBigintIssue<BigIntInput>> | undefined
> {
return {
kind: 'transformation',
type: 'to_bigint',
reference: toBigint,
async: false,
message,
'~run'(dataset, config) {
try {
dataset.value = BigInt(dataset.value);
} catch {
_addIssue(this, 'bigint', dataset, config);
// @ts-expect-error
dataset.typed = false;
}
return dataset as OutputDataset<bigint, ToBigintIssue<BigIntInput>>;
},
};
}
1 change: 1 addition & 0 deletions library/src/actions/toBoolean/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './toBoolean.ts';
25 changes: 25 additions & 0 deletions library/src/actions/toBoolean/toBoolean.test-d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { describe, expectTypeOf, test } from 'vitest';
import type { InferInput, InferIssue, InferOutput } from '../../types/index.ts';
import { toBoolean, type ToBooleanAction } from './toBoolean.ts';

describe('toBoolean', () => {
test('should return action object', () => {
expectTypeOf(toBoolean<'foo'>()).toEqualTypeOf<ToBooleanAction<'foo'>>();
});

describe('should infer correct types', () => {
type Action = ToBooleanAction<'foo'>;

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

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

test('of issue', () => {
expectTypeOf<InferIssue<Action>>().toEqualTypeOf<never>();
});
});
});
71 changes: 71 additions & 0 deletions library/src/actions/toBoolean/toBoolean.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { describe, expect, test } from 'vitest';
import { toBoolean, type ToBooleanAction } from './toBoolean.ts';

describe('toBoolean', () => {
test('should return action object', () => {
expect(toBoolean()).toStrictEqual({
kind: 'transformation',
type: 'to_boolean',
reference: toBoolean,
async: false,
'~run': expect.any(Function),
} satisfies ToBooleanAction<unknown>);
});

describe('should transform to boolean', () => {
const action = toBoolean();

test('for string', () => {
expect(action['~run']({ typed: true, value: 'foo' }, {})).toStrictEqual({
typed: true,
value: true,
});
});

test('for number', () => {
expect(action['~run']({ typed: true, value: 1 }, {})).toStrictEqual({
typed: true,
value: true,
});
});

test('for bigint', () => {
expect(action['~run']({ typed: true, value: 1n }, {})).toStrictEqual({
typed: true,
value: true,
});
});

test('for boolean', () => {
expect(action['~run']({ typed: true, value: true }, {})).toStrictEqual({
typed: true,
value: true,
});
});

test('for null', () => {
expect(action['~run']({ typed: true, value: null }, {})).toStrictEqual({
typed: true,
value: false,
});
});

test('for undefined', () => {
expect(
action['~run']({ typed: true, value: undefined }, {})
).toStrictEqual({
typed: true,
value: false,
});
});

test('for symbol', () => {
expect(
action['~run']({ typed: true, value: Symbol('foo') }, {})
).toStrictEqual({
typed: true,
value: true,
});
});
});
});
36 changes: 36 additions & 0 deletions library/src/actions/toBoolean/toBoolean.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import type { BaseTransformation, SuccessDataset } from '../../types/index.ts';

/**
* To boolean action interface.
*/
export interface ToBooleanAction<TInput>
extends BaseTransformation<TInput, boolean, never> {
/**
* The action type.
*/
readonly type: 'to_boolean';
/**
* The action reference.
*/
readonly reference: typeof toBoolean;
}

/**
* Creates a to boolean transformation action.
*
* @returns A to boolean action.
*/
// @__NO_SIDE_EFFECTS__
export function toBoolean<TInput>(): ToBooleanAction<TInput> {
return {
kind: 'transformation',
type: 'to_boolean',
reference: toBoolean,
async: false,
'~run'(dataset) {
// @ts-expect-error
dataset.value = Boolean(dataset.value);
return dataset as SuccessDataset<boolean>;
},
};
}
1 change: 1 addition & 0 deletions library/src/actions/toDate/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './toDate.ts';
Loading