Skip to content

Commit

Permalink
Merge pull request #550 from shimataro/develop
Browse files Browse the repository at this point in the history
version 3.1.0
  • Loading branch information
shimataro authored Sep 27, 2021
2 parents 73fd44b + f3f5a50 commit 759d7a9
Show file tree
Hide file tree
Showing 101 changed files with 3,539 additions and 2,419 deletions.
21 changes: 14 additions & 7 deletions .github/workflows/verify-examples.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ jobs:
os:
- windows-2019
- macos-10.15
- ubuntu-16.04
- ubuntu-18.04
- ubuntu-20.04
nodejs:
Expand Down Expand Up @@ -57,7 +56,8 @@ jobs:
- name: Check syntax
run: node ./dist/index.js
- name: Install dependencies (example)
run: npm --prefix ./examples i --only=production
run: npm i --only=production
working-directory: ./examples
- name: Run example
run: node ./examples/example.js
- name: Run example (TypeScript/Babel compatible)
Expand All @@ -71,7 +71,6 @@ jobs:
os:
- windows-2019
- macos-10.15
- ubuntu-16.04
- ubuntu-18.04
- ubuntu-20.04
nodejs:
Expand Down Expand Up @@ -114,7 +113,8 @@ jobs:
- name: Check syntax (ESM)
run: node --experimental-modules ./dist/index.mjs
- name: Install dependencies (example)
run: npm --prefix ./examples i --only=production
run: npm i --only=production
working-directory: ./examples
- name: Run example (CJS)
run: node --experimental-modules ./examples/example.js
- name: Run example (CJS; TypeScript/Babel compatible)
Expand All @@ -130,7 +130,6 @@ jobs:
os:
- windows-2019
- macos-10.15
- ubuntu-16.04
- ubuntu-18.04
- ubuntu-20.04
nodejs:
Expand Down Expand Up @@ -166,7 +165,8 @@ jobs:
- name: Check syntax (ESM)
run: node --experimental-conditional-exports ./dist/index.mjs
- name: Install dependencies (example)
run: npm --prefix ./examples i --only=production
run: npm i --only=production
working-directory: ./examples
- name: Run example (CJS)
run: node --experimental-conditional-exports ./examples/example.js
- name: Run example (CJS; TypeScript/Babel compatible)
Expand All @@ -182,7 +182,6 @@ jobs:
os:
- windows-2019
- macos-10.15
- ubuntu-16.04
- ubuntu-18.04
- ubuntu-20.04
deno:
Expand All @@ -193,6 +192,14 @@ jobs:
- "1.4.0"
- "1.5.0"
- "1.6.0"
- "1.7.0"
- "1.8.0"
- "1.9.0"
- "1.10.1"
- "1.11.0"
- "1.12.0"
- "1.13.0"
- "1.14.0"
fail-fast: false
steps:
- name: Checkout source codes
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/verify-on-linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ jobs:
- "3.9"
- "4.0"
- "4.1"
- "4.2"
- "4.3"
- "4.4"
fail-fast: false
steps:
- name: Checkout source codes
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/verify-on-macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ jobs:
- "3.9"
- "4.0"
- "4.1"
- "4.2"
- "4.3"
- "4.4"
fail-fast: false
steps:
- name: Checkout source codes
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/verify-on-windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ jobs:
- "3.9"
- "4.0"
- "4.1"
- "4.2"
- "4.3"
- "4.4"
fail-fast: false
steps:
- name: Turn off auto-crlf
Expand Down
20 changes: 19 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,23 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

## [Unreleased]

## [3.1.0] - 2021-09-27

### Added

* `vs.enumeration()`

### Fixed

* TypeScript example in README
* Option types

### Others

* add JSDoc comments for parameters
* support TypeScript 4.2 - 4.4
* support Deno 1.7 - 1.14

## [3.0.0] - 2020-12-09

### Others
Expand Down Expand Up @@ -544,7 +561,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

* First release.

[Unreleased]: https://github.com/shimataro/value-schema/compare/v3.0.0...HEAD
[Unreleased]: https://github.com/shimataro/value-schema/compare/v3.1.0...HEAD
[3.1.0]: https://github.com/shimataro/value-schema/compare/v3.0.0...v3.1.0
[3.0.0]: https://github.com/shimataro/value-schema/compare/v3.0.0-rc.15...v3.0.0
[3.0.0-rc.15]: https://github.com/shimataro/value-schema/compare/v3.0.0-rc.14...v3.0.0-rc.15
[3.0.0-rc.14]: https://github.com/shimataro/value-schema/compare/v3.0.0-rc.13...v3.0.0-rc.14
Expand Down
221 changes: 199 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
[![Deno version][image-deno]][link-deno]
[![License][image-license]][link-license]

simple, easy-to-use, and declarative schema validator
simple, easy-to-use, and declarative input validator

supports [Node.js](https://nodejs.org/), [TypeScript](https://www.typescriptlang.org/), and [Deno](https://deno.land/)

Expand All @@ -28,6 +28,7 @@ supports [Node.js](https://nodejs.org/), [TypeScript](https://www.typescriptlang
* [string](#string)
* [numeric string](#numeric-string)
* [email](#email)
* [enumeration](#enumeration)
* [array](#array)
* [object](#object)
* [Changelog](#changelog)
Expand Down Expand Up @@ -196,10 +197,12 @@ $ node --experimental-modules foo.mjs

### [Deno](https://deno.land/)

Deno has been supported as of v3.0.0-rc.4.
Deno has been supported as of v3.

```typescript
import vs from "https://deno.land/x/value_schema/mod.ts";
import vs from "https://deno.land/x/value_schema/mod.ts"; // latest version
import vs from "https://deno.land/x/value_schema@3/mod.ts"; // latest version of v3
import vs from "https://deno.land/x/[email protected]/mod.ts"; // v3.0.0
```

**CAUTION**: specify `value_schema` (underscore) NOT `value-schema` (hyphen) because [deno.land](https://deno.land/) module database does not support name with hyphen!
Expand Down Expand Up @@ -467,25 +470,7 @@ const actual = vs.applySchemaObject(schemaObject, input);
assert.deepStrictEqual(actual, expected);
```

In TypeScript, use "Generics" for type-safe.

```typescript
interface Parameters {
foo: number
bar: string
}

const schemaObject = {
foo: vs.number(),
bar: vs.string(),
};
const input = {
foo: "12345",
bar: "abcde",
};

const actual = vs.applySchemaObject<Parameters>(schemaObject, input);
```
In TypeScript, type inference and auto-completion work perfectly!

###### error handling 1

Expand Down Expand Up @@ -1840,6 +1825,198 @@ assert.throws(
{name: "ValueSchemaError", cause: vs.CAUSE.PATTERN});
```

### enumeration

Return type of `applyTo()` can be limited to enum-like type; `enum` and union.
**This is useful for TypeScript**.

#### ambient declarations

```typescript
export function enumeration<E = never>(options: OptionsForEnumeration): EnumerationSchema<E>;

type OptionsForEnumeration = {
ifUndefined?: string | null;
ifEmptyString?: string | null;
ifNull?: string | null;

only: E[]; // this is NOT an optional.
}
type ErrorHandler = (err: ValueSchemaError) => E | null | never;
interface EnumerationSchema {
applyTo(value: unknown, onError?: ErrorHandler): E | null
}
```

#### `applyTo(value[, onError])`

Applies schema to `value`.

If an error occurs, this method calls `onError` (if specified) or throw `ValueSchemaError` (otherwise).

See example of `only`.

#### options

##### `only`

Accepts only particular values.
This is NOT an optional.

```typescript
// enum version
enum NumberEnum
{
zero,
one,
}
enum StringEnum
{
a = "a",
b = "b",
}

// should be OK
{
// pattern 1: enum that contains number elements
const val: NumberEnum = vs.enumeration({only: [NumberEnum.zero, NumberEnum.one]}).applyTo(1);
assert.strictEqual(val, 1);
}
{
// pattern 2: enum that contains only string elements
const val: StringEnum = vs.enumeration({only: Object.values(StringEnum)}).applyTo("a");
assert.strictEqual(val, "a");
}

// should cause error
assert.throws(
() => vs.enumeration({only: Object.values(StringEnum)}).applyTo("c"),
{name: "ValueSchemaError", cause: vs.CAUSE.ONLY});
```

```typescript
// union version
type NumberUnion = 0 | 1;
type StringUnion = "a" | "b";

// should be OK
{
// you can use "as const" for union type
const val: NumberUnion = vs.enumeration({only: [0, 1] as const}).applyTo(1);
assert.strictEqual(val, 1);
}
{
// you can also use "<Type>"
const val: StringEnum = vs.enumeration<StringUnion>({only: ["a", "b"]}).applyTo("a");
assert.strictEqual(val, "a");
}

// should cause error
assert.throws(
() => vs.enumeratino({only: ["a", "b"] as const}).applyTo("c"),
{name: "ValueSchemaError", cause: vs.CAUSE.ONLY});
```

CAUTION: In union version, `only` must be "array of literal union types", "const-asserted array", or "array literal with generics".

```typescript
type NumberUnion = 0 | 1;

// OK
{
// array of literal union types
const val: NumberUnion = vs.enumeration({only: [0, 1] as NumberUnion[]}).applyTo(1);
}
{
// const-asserted array
const val: NumberUnion = vs.enumeration({only: [0, 1] as const}).applyTo(1);
}
{
// array literal with generics
const val: NumberUnion = vs.enumeration<NumberUnion>({only: [0, 1]}).applyTo(1);
}

// NG (compile error)
{
// TS2322: Type 'number' is not assignable to type 'NumberUnion'.
const val: NumberUnion = vs.enumeration({only: [0, 1]}).applyTo(1); // number
}
{
const only = [0, 1]; // number[]
const val: NumberUnion = vs.enumeration({only: only}).applyTo(1);
}
{
const only = [0, 1]; // number[]
const val: NumberUnion = vs.enumeration<NumberUnion>({only: only}).applyTo(1);
}
```

##### `ifUndefined`

Specifies return value when input value is `undefined`.

```typescript
enum StringEnum
{
a = "a",
b = "b",
}

// should be adjusted
assert.strictEqual(
vs.enumeration({ifUndefined: StringEnum.a, only: Object.values(StringEnum)}).applyTo(undefined),
"a");

// should cause error
assert.throws(
() => vs.enumeration({only: Object.values(StringEnum)}).applyTo(undefined),
{name: "ValueSchemaError", cause: vs.CAUSE.UNDEFINED});
```

##### `ifNull`

Specifies return value when input value is `null`.

```typescript
enum StringEnum
{
a = "a",
b = "b",
}

// should be adjusted
assert.strictEqual(
vs.enumeration({ifNull: StringEnum.a, only: Object.values(StringEnum)}).applyTo(null),
"a");

// should cause error
assert.throws(
() => vs.enumeration({only: Object.values(StringEnum)}).applyTo(null),
{name: "ValueSchemaError", cause: vs.CAUSE.NULL});
```

##### `ifEmptyString`

Specifies return value when input value is `""`.

```typescript
enum StringEnum
{
a = "a",
b = "b",
}

// should be adjusted
assert.strictEqual(
vs.enumeration({ifEmptyString: StringEnum.a, only: Object.values(StringEnum)}).applyTo(""),
"a");

// should cause error
assert.throws(
() => vs.enumeration({only: Object.values(StringEnum)}).applyTo(""),
{name: "ValueSchemaError", cause: vs.CAUSE.EMPTY_STRING});
```

### array

#### ambient declarations
Expand Down
Loading

0 comments on commit 759d7a9

Please sign in to comment.