Skip to content

Commit

Permalink
Merge pull request #495 from shimataro/develop
Browse files Browse the repository at this point in the history
version 3.0.0-rc.12
  • Loading branch information
shimataro committed Jul 10, 2020
2 parents bb9338f + 15e1b16 commit 7db15aa
Show file tree
Hide file tree
Showing 60 changed files with 1,825 additions and 72 deletions.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ node_modules/

# auto-generated files
/dist/
/dist-deno/
/coverage/

# IDE files
Expand Down
1 change: 1 addition & 0 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/.github/
/coverage/
/dist-deno/
/examples/
/node_modules/
/scripts/
Expand Down
9 changes: 8 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

## [Unreleased]

## [3.0.0-rc.12] - 2020-07-11

### Others

* host [Deno modules](https://deno.land/x) on GitHub: <https://github.com/denoland/deno_website2/pull/1302>

## [3.0.0-rc.11] - 2020-07-09

### Fixed
Expand Down Expand Up @@ -512,7 +518,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-rc.11...HEAD
[Unreleased]: https://github.com/shimataro/value-schema/compare/v3.0.0-rc.12...HEAD
[3.0.0-rc.12]: https://github.com/shimataro/value-schema/compare/v3.0.0-rc.11...v3.0.0-rc.12
[3.0.0-rc.11]: https://github.com/shimataro/value-schema/compare/v3.0.0-rc.10...v3.0.0-rc.11
[3.0.0-rc.10]: https://github.com/shimataro/value-schema/compare/v3.0.0-rc.9...v3.0.0-rc.10
[3.0.0-rc.9]: https://github.com/shimataro/value-schema/compare/v3.0.0-rc.8...v3.0.0-rc.9
Expand Down
69 changes: 69 additions & 0 deletions dist-deno/appliers/array/each.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { Key, Values, isArray } from "../../libs/types.ts";
import { ValueSchemaError } from "../../libs/ValueSchemaError.ts";
import { BaseSchema } from "../../schemaClasses/BaseSchema.ts";
type Each<T> = {
schema: BaseSchema<T>;
ignoresErrors: boolean;
};
type EachLike<T> = BaseSchema<T> | Each<T>;
export interface Options<T> {
each?: EachLike<T>;
}
/**
* apply schema
* @param values input/output values
* @param options options
* @param keyStack key stack for error handling
* @returns applied value
*/
export function applyTo<T>(values: Values, options: Options<T>, keyStack: Key[]): values is Values<T[]> {
const each = normalizeOptions(options.each);
if (each === undefined) {
return false;
}
// istanbul ignore next
if (!isArray(values.output)) {
return false;
}
const adjustedValues: T[] = [];
for (let idx = 0; idx < values.output.length; idx++) {
const element = values.output[idx];
// A trick in order to call _applyTo() private method from the outside (like "friend")
try {
const adjustedValue = each.schema["_applyTo"](element, (err) => {
if (each.ignoresErrors) {
throw Error("!IGNORE!");
}
return ValueSchemaError.raise(err.cause, values, err.keyStack);
}, [...keyStack, idx]);
adjustedValues.push(adjustedValue);
}
catch (err) {
if (err.message === "!IGNORE!") {
// ignore
continue;
}
throw err;
}
}
// replace with adjusted values
values.output = adjustedValues;
return false;
}
/**
* normalize options
* @param each each
* @returns normalized options
*/
function normalizeOptions<T>(each?: EachLike<T>): Each<T> | void {
if (each === undefined) {
return;
}
if (each instanceof BaseSchema) {
return {
schema: each as BaseSchema<T>,
ignoresErrors: false
};
}
return each;
}
56 changes: 56 additions & 0 deletions dist-deno/appliers/array/maxLength.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { Key, Values, isArray, isNumber } from "../../libs/types.ts";
import { CAUSE, ValueSchemaError } from "../../libs/ValueSchemaError.ts";
type MaxLength = {
length: number;
trims: boolean;
};
type MaxLengthLike = number | MaxLength;
export interface Options {
maxLength?: MaxLengthLike;
}
/**
* apply schema
* @param values input/output values
* @param options options
* @param keyStack key stack for error handling
* @returns applied value
*/
export function applyTo<T>(values: Values, options: Options, keyStack: Key[]): values is Values<T> {
const maxLength = normalizeOptions(options.maxLength);
// istanbul ignore next
if (!isArray(values.output)) {
return false;
}
if (values.output.length <= maxLength.length) {
return false;
}
if (maxLength.trims) {
values.output.splice(maxLength.length);
return false;
}
return ValueSchemaError.raise(CAUSE.MAX_LENGTH, values, keyStack);
}
/**
* normalize options
* @param maxLength options
* @returns normalized options
*/
function normalizeOptions(maxLength?: MaxLengthLike): MaxLength {
const defaultOptions: MaxLength = {
length: Number.MAX_SAFE_INTEGER,
trims: false
};
if (maxLength === undefined) {
return defaultOptions;
}
if (isNumber(maxLength)) {
return {
...defaultOptions,
length: maxLength
};
}
return {
...defaultOptions,
...maxLength
};
}
26 changes: 26 additions & 0 deletions dist-deno/appliers/array/minLength.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Key, Values, isArray } from "../../libs/types.ts";
import { CAUSE, ValueSchemaError } from "../../libs/ValueSchemaError.ts";
export interface Options {
minLength?: number;
}
/**
* apply schema
* @param values input/output values
* @param options options
* @param keyStack key stack for error handling
* @returns applied value
*/
export function applyTo<T>(values: Values, options: Options, keyStack: Key[]): values is Values<T> {
const normalizedOptions: Required<Options> = {
minLength: 0,
...options
};
// istanbul ignore next
if (!isArray(values.output)) {
return false;
}
if (values.output.length >= normalizedOptions.minLength) {
return false;
}
return ValueSchemaError.raise(CAUSE.MIN_LENGTH, values, keyStack);
}
28 changes: 28 additions & 0 deletions dist-deno/appliers/array/type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { Key, Values, isArray, isString } from "../../libs/types.ts";
import { CAUSE, ValueSchemaError } from "../../libs/ValueSchemaError.ts";
export interface Options {
separatedBy?: string | RegExp;
toArray?: boolean;
}
/**
* apply schema
* @param values input/output values
* @param options options
* @param keyStack key stack for error handling
* @returns applied value
*/
export function applyTo<T>(values: Values, options: Options, keyStack: Key[]): values is Values<T> {
if (isArray(values.output)) {
// already array
return false;
}
if (isString(values.output) && options.separatedBy !== undefined) {
values.output = values.output.split(options.separatedBy);
return false;
}
if (options.toArray !== undefined && options.toArray) {
values.output = [values.output];
return false;
}
return ValueSchemaError.raise(CAUSE.TYPE, values, keyStack);
}
51 changes: 51 additions & 0 deletions dist-deno/appliers/boolean/type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { Key, Values, isBoolean, isNumber, isString } from "../../libs/types.ts";
import { CAUSE, ValueSchemaError } from "../../libs/ValueSchemaError.ts";
const REGEXP_TRUE = /^\s*(true|yes|on)\s*$/i;
const REGEXP_FALSE = /^\s*(false|no|off)\s*$/i;
export interface Options {
strictType?: boolean;
acceptsAllNumbers?: boolean;
}
/**
* apply schema
* @param values input/output values
* @param options options
* @param keyStack key stack for error handling
* @returns applied value
*/
export function applyTo(values: Values, options: Options, keyStack: Key[]): values is Values<boolean> {
const normalizedOptions: Required<Options> = {
strictType: false,
acceptsAllNumbers: false,
...options
};
if (isBoolean(values.output)) {
// already boolean
return true;
}
// not boolean
if (normalizedOptions.strictType) {
// strict type check
ValueSchemaError.raise(CAUSE.TYPE, values, keyStack);
}
if (isString(values.output)) {
// "true" is true, "false" is false
if (REGEXP_TRUE.test(values.output)) {
values.output = true;
return true;
}
if (REGEXP_FALSE.test(values.output)) {
values.output = false;
return true;
}
// convert to number
values.output = Number(values.output);
}
if (isNumber(values.output)) {
if (values.output === 0 || values.output === 1 || normalizedOptions.acceptsAllNumbers) {
values.output = Boolean(values.output);
return true;
}
}
return ValueSchemaError.raise(CAUSE.TYPE, values, keyStack);
}
21 changes: 21 additions & 0 deletions dist-deno/appliers/converter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Key, Values } from "../libs/types.ts";
import { CAUSE, ValueSchemaError } from "../libs/ValueSchemaError.ts";
export interface Options<T> {
converter?: (value: T, fail: () => never) => T;
}
/**
* apply schema
* @param values input/output values
* @param options options
* @param keyStack key stack for error handling
* @returns applied value
*/
export function applyTo<T>(values: Values, options: Options<T>, keyStack: Key[]): values is Values<T> {
if (options.converter === undefined) {
return false;
}
values.output = options.converter(values.output as T, () => {
return ValueSchemaError.raise(CAUSE.CONVERTER, values, keyStack);
});
return true;
}
34 changes: 34 additions & 0 deletions dist-deno/appliers/email/maxLength.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { Key, Values, isString } from "../../libs/types.ts";
import { CAUSE, ValueSchemaError } from "../../libs/ValueSchemaError.ts";
const MAX_LENGTH_LOCAL = 64;
const MAX_LENGTH_DOMAIN = 255;
const MAX_LENGTH = MAX_LENGTH_LOCAL + 1 + MAX_LENGTH_DOMAIN; // local-part + "@" + domain-part
export interface Options {
}
/**
* apply schema
* @param values input/output values
* @param options options
* @param keyStack key stack for error handling
* @returns applied value
*/
export function applyTo(values: Values, options: Options, keyStack: Key[]): values is Values<string> // eslint-disable-line @typescript-eslint/no-unused-vars
{
// istanbul ignore next
if (!isString(values.output)) {
return false;
}
if (values.output.length > MAX_LENGTH) {
ValueSchemaError.raise(CAUSE.MAX_LENGTH, values, keyStack);
}
const atPosition = values.output.lastIndexOf("@");
if (atPosition > MAX_LENGTH_LOCAL) {
// local-part length error
ValueSchemaError.raise(CAUSE.MAX_LENGTH, values, keyStack);
}
if (values.output.length - atPosition - 1 > MAX_LENGTH_DOMAIN) {
// domain-part length error
ValueSchemaError.raise(CAUSE.MAX_LENGTH, values, keyStack);
}
return false;
}
20 changes: 20 additions & 0 deletions dist-deno/appliers/email/pattern.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { REGEXP_EMAIL } from "../../libs/regexp/email.ts";
import { Key, Values } from "../../libs/types.ts";
import * as pattern from "../string/pattern.ts";
export interface Options {
pattern?: RegExp;
}
/**
* apply schema
* @param values input/output values
* @param options options
* @param keyStack key stack for error handling
* @returns applied value
*/
export function applyTo(values: Values, options: Options, keyStack: Key[]): values is Values<string> {
const normalizedOptions: Required<Options> = {
pattern: REGEXP_EMAIL,
...options
};
return pattern.applyTo(values, normalizedOptions, keyStack);
}
22 changes: 22 additions & 0 deletions dist-deno/appliers/ifEmptyString.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Key, Values } from "../libs/types.ts";
import { CAUSE, ValueSchemaError } from "../libs/ValueSchemaError.ts";
export interface Options<T> {
ifEmptyString?: T | null;
}
/**
* apply schema
* @param values input/output values
* @param options options
* @param keyStack key stack for error handling
* @returns applied value
*/
export function applyTo<T>(values: Values, options: Options<T>, keyStack: Key[]): values is Values<T> {
if (values.output !== "") {
return false;
}
if (options.ifEmptyString !== undefined) {
values.output = options.ifEmptyString;
return true;
}
return ValueSchemaError.raise(CAUSE.EMPTY_STRING, values, keyStack);
}
22 changes: 22 additions & 0 deletions dist-deno/appliers/ifNull.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Key, Values } from "../libs/types.ts";
import { CAUSE, ValueSchemaError } from "../libs/ValueSchemaError.ts";
export interface Options<T> {
ifNull?: T | null;
}
/**
* apply schema
* @param values input/output values
* @param options options
* @param keyStack key stack for error handling
* @returns applied value
*/
export function applyTo<T>(values: Values, options: Options<T>, keyStack: Key[]): values is Values<T> {
if (values.output !== null) {
return false;
}
if (options.ifNull !== undefined) {
values.output = options.ifNull;
return true;
}
return ValueSchemaError.raise(CAUSE.NULL, values, keyStack);
}

0 comments on commit 7db15aa

Please sign in to comment.