Skip to content

Commit

Permalink
Migrate from TSDX to tsup for build and bundling
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexJPotter committed May 3, 2023
1 parent 11a5220 commit 6f0be72
Show file tree
Hide file tree
Showing 5 changed files with 811 additions and 131 deletions.
228 changes: 111 additions & 117 deletions docs/overview.md
@@ -1,117 +1,111 @@
---
id: overview
title: Overview
---

Front-end validation is a must-have for any project that involves forms, but the requirements vary hugely. You might have a simple sign-up form with a few text fields, or a complex configuration page with collections and deeply nested fields.

There are plenty of libraries out there which help you to solve the problem of front-end validation, but all the ones I've tried have felt lacking in one aspect or another - whether that's TypeScript support, their capacity to handle complex requirements, or the ability to define your own reusable validation logic.

So I wrote fluentvalidation-ts, a tiny library that is:

- Designed for TypeScript
- Simple yet powerful
- Fully extensible

Whatever your validation needs, fluentvalidation-ts can handle them.

## Motivation

In addition to the features mentioned above, one of the main motivators for writing fluentvalidation-ts was compatibility with [Formik](https://jaredpalmer.com/formik/). The errors object returned by fluentvalidation-ts has been designed to "just work" with Formik, so you can start using the two together with minimal effort. If you're not familiar with Formik, it's a fantastic library for writing forms in [React](https://reactjs.org/).

### Why not Yup?

If you're using TypeScript, chances are you've defined a type that describes your form model. Intuitively, you then want to define a validator which is tied to that type. This is exactly how fluentvalidation-ts works. If you need to make changes to the shape of your form model, you just update the base type. Those changes might cause your validator to break, but the compiler will let you know.

With [Yup](https://github.com/jquense/yup#typescript-support) you define your validation schema first, then infer the type of your form model from that. This gives you slightly less control over the typing of your form model, and forces you to modify your validation schema in order to make changes to it. Because Yup is written in JavaScript, you also have to install the TypeScript type definitions separately and keep them up to date.

There's no doubt that Yup is a great library, but it's painful to use with TypeScript.

## Influences

If you've ever worked on a .NET API, you might have heard of a library called [FluentValidation](https://fluentvalidation.net/). It has a really nice API for building up validation rules, and that made me wonder whether I could achieve something similar in TypeScript. While fluentvalidation-ts is not a direct port, it will still feel very familiar to anyone who's used FluentValidation before.

## Installation

You can install fluentvalidation-ts with NPM/Yarn, or include it directly via a `<script>` tag.

### NPM/Yarn

With NPM:

```
npm install fluentvalidation-ts --save
```

or Yarn:

```
yarn add fluentvalidation-ts
```

### CDN

To target the latest version, add the following:

```html
<script src="https://unpkg.com/fluentvalidation-ts/dist/fluentvalidation-ts.umd.production.min.js"></script>
```

Or, to target a specific version (e.g. `2.1.2`), add the following:

```html
<script src="https://unpkg.com/fluentvalidation-ts@2.1.2/dist/fluentvalidation-ts.umd.production.min.js"></script>
```

Once you've done this, all you need is the `Validator` class which can be accessed via:

```
window['fluentvalidation-ts'].Validator
```

### Try it in your browser

Click [here](https://codesandbox.io/embed/the-gist-fluentvalidation-ts212-p632d?fontsize=14&hidenavigation=1&theme=dark) to explore fluentvalidation-ts in your browser with CodeSandbox.

## The Gist

To use fluentvalidation-ts simply import the `Validator` generic class, and define your own class which extends it using the appropriate generic type argument. Build up the rules for your various properties in the constructor of your derived class, then create an instance of your class to get hold of a validator. Finally, pass an instance of your model into the `.validate` function of your validator to obtain a validation errors object.

```typescript
import { Validator } from 'fluentvalidation-ts';

type FormModel = {
name: string;
age: number;
};

class FormValidator extends Validator<FormModel> {
constructor() {
super();

this.ruleFor('name')
.notEmpty()
.withMessage('Please enter your name');

this.ruleFor('age')
.greaterThanOrEqualTo(0)
.withMessage('Please enter a non-negative number');
}
}

const formValidator = new FormValidator();

const valid: FormModel = {
name: 'Alex',
age: 26,
};
formValidator.validate(valid);
// {}

const invalid: FormModel = {
name: '',
age: -1,
};
formValidator.validate(invalid);
// { name: 'Please enter your name', age: 'Please enter a non-negative number' }
```
---
id: overview
title: Overview
---

Front-end validation is a must-have for any project that involves forms, but the requirements vary hugely. You might have a simple sign-up form with a few text fields, or a complex configuration page with collections and deeply nested fields.

There are plenty of libraries out there which help you to solve the problem of front-end validation, but all the ones I've tried have felt lacking in one aspect or another - whether that's TypeScript support, their capacity to handle complex requirements, or the ability to define your own reusable validation logic.

So I wrote fluentvalidation-ts, a tiny library that is:

- Designed for TypeScript
- Simple yet powerful
- Fully extensible

Whatever your validation needs, fluentvalidation-ts can handle them.

## Motivation

In addition to the features mentioned above, one of the main motivators for writing fluentvalidation-ts was compatibility with [Formik](https://jaredpalmer.com/formik/). The errors object returned by fluentvalidation-ts has been designed to "just work" with Formik, so you can start using the two together with minimal effort. If you're not familiar with Formik, it's a fantastic library for writing forms in [React](https://reactjs.org/).

### Why not Yup?

If you're using TypeScript, chances are you've defined a type that describes your form model. Intuitively, you then want to define a validator which is tied to that type. This is exactly how fluentvalidation-ts works. If you need to make changes to the shape of your form model, you just update the base type. Those changes might cause your validator to break, but the compiler will let you know.

With [Yup](https://github.com/jquense/yup#typescript-support) you define your validation schema first, then infer the type of your form model from that. This gives you slightly less control over the typing of your form model, and forces you to modify your validation schema in order to make changes to it. Because Yup is written in JavaScript, you also have to install the TypeScript type definitions separately and keep them up to date.

There's no doubt that Yup is a great library, but it's painful to use with TypeScript.

## Influences

If you've ever worked on a .NET API, you might have heard of a library called [FluentValidation](https://fluentvalidation.net/). It has a really nice API for building up validation rules, and that made me wonder whether I could achieve something similar in TypeScript. While fluentvalidation-ts is not a direct port, it will still feel very familiar to anyone who's used FluentValidation before.

## Installation

You can install fluentvalidation-ts with NPM/Yarn, or include it directly via a `<script>` tag.

### NPM/Yarn

With NPM:

```
npm install fluentvalidation-ts --save
```

or Yarn:

```
yarn add fluentvalidation-ts
```

### CDN

To target the latest version, add the following:

```html
<script src="https://unpkg.com/fluentvalidation-ts/dist/index.global.js"></script>
```

Or, to target a specific version (e.g. `3.0.0`), add the following:

```html
<script src="https://unpkg.com/fluentvalidation-ts@3.0.0/dist/index.global.js"></script>
```

Once you've done this, all you need is the `Validator` class which can be accessed via:

```
window['fluentvalidation'].Validator
```

## The Gist

To use fluentvalidation-ts simply import the `Validator` generic class, and define your own class which extends it using the appropriate generic type argument. Build up the rules for your various properties in the constructor of your derived class, then create an instance of your class to get hold of a validator. Finally, pass an instance of your model into the `.validate` function of your validator to obtain a validation errors object.

```typescript
import { Validator } from 'fluentvalidation-ts';

type FormModel = {
name: string;
age: number;
};

class FormValidator extends Validator<FormModel> {
constructor() {
super();

this.ruleFor('name').notEmpty().withMessage('Please enter your name');

this.ruleFor('age')
.greaterThanOrEqualTo(0)
.withMessage('Please enter a non-negative number');
}
}

const formValidator = new FormValidator();

const valid: FormModel = {
name: 'Alex',
age: 26,
};
formValidator.validate(valid);
// {}

const invalid: FormModel = {
name: '',
age: -1,
};
formValidator.validate(invalid);
// { name: 'Please enter your name', age: 'Please enter a non-negative number' }
```
10 changes: 6 additions & 4 deletions package.json
@@ -1,6 +1,6 @@
{
"name": "fluentvalidation-ts",
"version": "2.3.0",
"version": "3.0.0",
"description": "A TypeScript-first library for building strongly-typed validation rules",
"keywords": [
"fluent",
Expand All @@ -23,15 +23,15 @@
"bugs": {
"url": "https://github.com/AlexJPotter/fluentvalidation-ts/issues"
},
"umd:main": "dist/fluentvalidation-ts.umd.production.min.js",
"module": "dist/fluentvalidation-ts.esm.js",
"umd:main": "dist/index.global.js",
"module": "dist/index.mjs",
"typings": "dist/index.d.ts",
"files": [
"dist"
],
"scripts": {
"start": "tsdx watch",
"build": "cross-env NODE_ENV=production tsdx build --format=cjs,esm,umd",
"build": "cross-env NODE_ENV=production tsup src/index.ts --dts --minify --treeshake --format cjs,esm,iife --global-name fluentvalidation --sourcemap",
"test": "tsdx test",
"lint": "tslint -c tslint.json 'src/**/*.{ts,.test.ts}'",
"prettier": "prettier --write \"{src,test}/**/*.ts\"",
Expand All @@ -47,6 +47,7 @@
"endOfLine": "crlf"
},
"devDependencies": {
"@swc/core": "^1.3.56",
"@types/jest": "^26.0.23",
"cross-env": "^7.0.3",
"husky": "^6.0.0",
Expand All @@ -56,6 +57,7 @@
"tslib": "^2.3.0",
"tslint": "^6.1.3",
"tslint-config-prettier": "^1.18.0",
"tsup": "^6.7.0",
"typescript": "^4.3.3"
}
}
112 changes: 112 additions & 0 deletions website/versioned_docs/version-3.0.0/overview.md
@@ -0,0 +1,112 @@
---
id: version-3.0.0-overview
title: Overview
original_id: overview
---

Front-end validation is a must-have for any project that involves forms, but the requirements vary hugely. You might have a simple sign-up form with a few text fields, or a complex configuration page with collections and deeply nested fields.

There are plenty of libraries out there which help you to solve the problem of front-end validation, but all the ones I've tried have felt lacking in one aspect or another - whether that's TypeScript support, their capacity to handle complex requirements, or the ability to define your own reusable validation logic.

So I wrote fluentvalidation-ts, a tiny library that is:

- Designed for TypeScript
- Simple yet powerful
- Fully extensible

Whatever your validation needs, fluentvalidation-ts can handle them.

## Motivation

In addition to the features mentioned above, one of the main motivators for writing fluentvalidation-ts was compatibility with [Formik](https://jaredpalmer.com/formik/). The errors object returned by fluentvalidation-ts has been designed to "just work" with Formik, so you can start using the two together with minimal effort. If you're not familiar with Formik, it's a fantastic library for writing forms in [React](https://reactjs.org/).

### Why not Yup?

If you're using TypeScript, chances are you've defined a type that describes your form model. Intuitively, you then want to define a validator which is tied to that type. This is exactly how fluentvalidation-ts works. If you need to make changes to the shape of your form model, you just update the base type. Those changes might cause your validator to break, but the compiler will let you know.

With [Yup](https://github.com/jquense/yup#typescript-support) you define your validation schema first, then infer the type of your form model from that. This gives you slightly less control over the typing of your form model, and forces you to modify your validation schema in order to make changes to it. Because Yup is written in JavaScript, you also have to install the TypeScript type definitions separately and keep them up to date.

There's no doubt that Yup is a great library, but it's painful to use with TypeScript.

## Influences

If you've ever worked on a .NET API, you might have heard of a library called [FluentValidation](https://fluentvalidation.net/). It has a really nice API for building up validation rules, and that made me wonder whether I could achieve something similar in TypeScript. While fluentvalidation-ts is not a direct port, it will still feel very familiar to anyone who's used FluentValidation before.

## Installation

You can install fluentvalidation-ts with NPM/Yarn, or include it directly via a `<script>` tag.

### NPM/Yarn

With NPM:

```
npm install fluentvalidation-ts --save
```

or Yarn:

```
yarn add fluentvalidation-ts
```

### CDN

To target the latest version, add the following:

```html
<script src="https://unpkg.com/fluentvalidation-ts/dist/index.global.js"></script>
```

Or, to target a specific version (e.g. `3.0.0`), add the following:

```html
<script src="https://unpkg.com/fluentvalidation-ts@3.0.0/dist/index.global.js"></script>
```

Once you've done this, all you need is the `Validator` class which can be accessed via:

```
window['fluentvalidation'].Validator
```

## The Gist

To use fluentvalidation-ts simply import the `Validator` generic class, and define your own class which extends it using the appropriate generic type argument. Build up the rules for your various properties in the constructor of your derived class, then create an instance of your class to get hold of a validator. Finally, pass an instance of your model into the `.validate` function of your validator to obtain a validation errors object.

```typescript
import { Validator } from 'fluentvalidation-ts';

type FormModel = {
name: string;
age: number;
};

class FormValidator extends Validator<FormModel> {
constructor() {
super();

this.ruleFor('name').notEmpty().withMessage('Please enter your name');

this.ruleFor('age')
.greaterThanOrEqualTo(0)
.withMessage('Please enter a non-negative number');
}
}

const formValidator = new FormValidator();

const valid: FormModel = {
name: 'Alex',
age: 26,
};
formValidator.validate(valid);
// {}

const invalid: FormModel = {
name: '',
age: -1,
};
formValidator.validate(invalid);
// { name: 'Please enter your name', age: 'Please enter a non-negative number' }
```
12 changes: 11 additions & 1 deletion website/versions.json
@@ -1 +1,11 @@
["2.3.0", "2.2.2", "2.2.0", "2.1.6", "2.1.5", "2.1.4", "2.1.3", "2.1.2"]
[
"3.0.0",
"2.3.0",
"2.2.2",
"2.2.0",
"2.1.6",
"2.1.5",
"2.1.4",
"2.1.3",
"2.1.2"
]

0 comments on commit 6f0be72

Please sign in to comment.