@buildo/formo
Advanced tools
Comparing version 2.0.0-beta.4 to 2.0.0-beta.5
@@ -1,2 +0,1 @@ | ||
import { Option } from "fp-ts/Option"; | ||
export declare type FieldProps<V, Label, FieldError> = { | ||
@@ -8,4 +7,4 @@ name: string; | ||
label: Label; | ||
issues: Option<FieldError>; | ||
issues?: FieldError; | ||
disabled?: boolean; | ||
}; |
import { FieldProps } from "./FieldProps"; | ||
import { NonEmptyArray } from "fp-ts/NonEmptyArray"; | ||
import { Option } from "fp-ts/Option"; | ||
import { NonEmptyArray } from "./NonEmptyArray"; | ||
import { Validator } from "./Validator"; | ||
import { TaskEither } from "fp-ts/TaskEither"; | ||
import { IO } from "fp-ts/lib/IO"; | ||
import { Result } from "./Result"; | ||
declare type ComputedFieldProps<V, Label, Issues> = Pick<FieldProps<V, Label, Issues>, "name" | "value" | "onChange" | "onBlur" | "issues"> & { | ||
@@ -11,6 +9,6 @@ isTouched: boolean; | ||
}; | ||
export declare type FieldValidators<Values> = { | ||
declare type FieldValidators<Values> = { | ||
[k in keyof Values]: Validator<Values[k], unknown, unknown>; | ||
}; | ||
export declare type FieldArrayValidators<Values> = { | ||
declare type FieldArrayValidators<Values> = { | ||
[k in ArrayRecordKeys<Values>]: Partial<FieldValidators<ArrayRecord<Values, keyof ArrayRecordValues<Values> & string>[k][number]>>; | ||
@@ -20,5 +18,5 @@ }; | ||
declare type ValidatedValues<Values, Validators extends Partial<FieldValidators<Values>>, ArrayValidators extends Partial<FieldArrayValidators<Values>>> = { | ||
[k in keyof Values]: Validators[k] extends Validator<Values[k], infer O, infer _E> ? O : Validators[k] extends Validator<Values[k], infer O, infer _E> | undefined ? O | Values[k] : k extends ArrayRecordKeys<Values> ? ValidatedValues<ArrayRecord<Values, keyof ArrayRecordValues<Values> & string>[k][number], GetOrElse<ArrayValidators[k], {}>, {}>[] : Values[k]; | ||
[k in keyof Required<Values>]: Validators[k] extends Validator<Values[k], infer O, infer _E> ? O : Validators[k] extends Validator<Values[k], infer O, infer _E> | undefined ? O | Values[k] : k extends ArrayRecordKeys<Values> ? ValidatedValues<ArrayRecord<Values, keyof ArrayRecordValues<Values> & string>[k][number], GetOrElse<ArrayValidators[k], {}>, {}>[] : Values[k]; | ||
}; | ||
export declare type FormOptions<Values, Validators extends Partial<FieldValidators<Values>>, ArrayValidators extends Partial<FieldArrayValidators<Values>>, FormErrors> = [ | ||
declare type FormOptions<Values, Validators extends Partial<FieldValidators<Values>>, ArrayValidators extends Partial<FieldArrayValidators<Values>>, FormErrors> = [ | ||
{ | ||
@@ -32,3 +30,3 @@ initialValues: Values; | ||
{ | ||
onSubmit: (values: ValidatedValues<Values, Validators, ArrayValidators>) => TaskEither<FormErrors, unknown>; | ||
onSubmit: (values: ValidatedValues<Values, Validators, ArrayValidators>) => Promise<Result<FormErrors, unknown>>; | ||
} | ||
@@ -62,8 +60,8 @@ ]; | ||
fieldProps: <K extends keyof Values & string>(name: K) => ComputedFieldProps<Values[K], Label, NonEmptyArray<FieldError>>; | ||
handleSubmit: TaskEither<unknown, unknown>; | ||
handleSubmit: () => Promise<Result<unknown, unknown>>; | ||
isSubmitting: boolean; | ||
fieldArray: <K extends ArrayRecordKeys<Values>>(name: K) => FieldArray<Values, K, Label, FieldError>; | ||
formErrors: Option<FormErrors>; | ||
fieldErrors: Record<keyof Values, Option<NonEmptyArray<FieldError>>>; | ||
resetForm: IO<void>; | ||
formErrors?: FormErrors; | ||
fieldErrors: Partial<Record<keyof Values, NonEmptyArray<FieldError>>>; | ||
resetForm: () => void; | ||
submissionCount: number; | ||
@@ -73,4 +71,4 @@ }; | ||
[k in keyof Values]: Validator<Values[k], unknown, infer E>; | ||
}> ? E : null; | ||
}> ? E extends unknown ? never : E : null; | ||
export declare function useFormo<Values extends Record<string, unknown>, Validators extends Partial<FieldValidators<Values>>, ArrayValidators extends Partial<FieldArrayValidators<Values>>, FormErrors, Label>(...args: FormOptions<Values, Validators, ArrayValidators, FormErrors>): UseFormReturn<Values, FormErrors, Label, ValidatorErrorType<Values, Validators>>; | ||
export {}; |
@@ -13,11 +13,53 @@ "use strict"; | ||
}; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
var __generator = (this && this.__generator) || function (thisArg, body) { | ||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; | ||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; | ||
function verb(n) { return function (v) { return step([n, v]); }; } | ||
function step(op) { | ||
if (f) throw new TypeError("Generator is already executing."); | ||
while (_) try { | ||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; | ||
if (y = 0, t) op = [op[0] & 2, t.value]; | ||
switch (op[0]) { | ||
case 0: case 1: t = op; break; | ||
case 4: _.label++; return { value: op[1], done: false }; | ||
case 5: _.label++; y = op[1]; op = [0]; continue; | ||
case 7: op = _.ops.pop(); _.trys.pop(); continue; | ||
default: | ||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } | ||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } | ||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } | ||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } | ||
if (t[2]) _.ops.pop(); | ||
_.trys.pop(); continue; | ||
} | ||
op = body.call(thisArg, _); | ||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } | ||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; | ||
} | ||
}; | ||
var __spreadArrays = (this && this.__spreadArrays) || function () { | ||
for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; | ||
for (var r = Array(s), k = 0, i = 0; i < il; i++) | ||
for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) | ||
r[k] = a[j]; | ||
return r; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.useFormo = void 0; | ||
var react_1 = require("react"); | ||
var fp_ts_1 = require("fp-ts"); | ||
var function_1 = require("fp-ts/function"); | ||
var Apply_1 = require("fp-ts/Apply"); | ||
var useRefReducer_1 = require("./useRefReducer"); | ||
var Result_1 = require("./Result"); | ||
function formReducer(state, action) { | ||
var _a; | ||
var _a, _b, _c, _d, _e; | ||
var _f, _g; | ||
switch (action.type) { | ||
@@ -31,19 +73,13 @@ case "setValues": | ||
case "setFieldArrayTouched": | ||
var updatedTouchedField = function_1.pipe(state.fieldArrayTouched[action.field][action.index], fp_ts_1.option.fromNullable, fp_ts_1.option.alt(function_1.constant(fp_ts_1.option.some({}))), fp_ts_1.option.map(function (v) { | ||
var _a; | ||
return fp_ts_1.array.unsafeUpdateAt(action.index, __assign(__assign({}, v), (_a = {}, _a[action.subfield] = action.touched, _a)), state.fieldArrayTouched[action.field]); | ||
})); | ||
return function_1.pipe(updatedTouchedField, fp_ts_1.option.fold(function () { return state; }, function (updatedField) { | ||
var _a; | ||
return (__assign(__assign({}, state), { fieldArrayTouched: __assign(__assign({}, state.fieldArrayTouched), (_a = {}, _a[action.field] = updatedField, _a)) })); | ||
})); | ||
var touchedSubfields = (_f = state.fieldArrayTouched[action.field][action.index]) !== null && _f !== void 0 ? _f : {}; | ||
var updatedTouchedField = __spreadArrays(state.fieldArrayTouched[action.field].slice(0, action.index), [ | ||
__assign(__assign({}, touchedSubfields), (_b = {}, _b[action.subfield] = action.touched, _b)) | ||
], state.fieldArrayTouched[action.field].slice(action.index + 1, state.fieldArrayTouched[action.field].length)); | ||
return __assign(__assign({}, state), { fieldArrayTouched: __assign(__assign({}, state.fieldArrayTouched), (_c = {}, _c[action.field] = updatedTouchedField, _c)) }); | ||
case "setFieldArrayErrors": | ||
var updatedErrorsField = function_1.pipe(state.fieldArrayErrors[action.field][action.index], fp_ts_1.option.fromNullable, fp_ts_1.option.alt(function_1.constant(fp_ts_1.option.some({}))), fp_ts_1.option.map(function (v) { | ||
var _a; | ||
return fp_ts_1.array.unsafeUpdateAt(action.index, __assign(__assign({}, v), (_a = {}, _a[action.subfield] = action.errors, _a)), state.fieldArrayErrors[action.field]); | ||
})); | ||
return function_1.pipe(updatedErrorsField, fp_ts_1.option.fold(function () { return state; }, function (updatedField) { | ||
var _a; | ||
return (__assign(__assign({}, state), { fieldArrayErrors: __assign(__assign({}, state.fieldArrayErrors), (_a = {}, _a[action.field] = updatedField, _a)) })); | ||
})); | ||
var errorsSubfields = (_g = state.fieldArrayErrors[action.field][action.index]) !== null && _g !== void 0 ? _g : {}; | ||
var updatedErrorsField = __spreadArrays(state.fieldArrayErrors[action.field].slice(0, action.index), [ | ||
__assign(__assign({}, errorsSubfields), (_d = {}, _d[action.subfield] = action.errors, _d)) | ||
], state.fieldArrayErrors[action.field].slice(action.index + 1, state.fieldArrayErrors[action.field].length)); | ||
return __assign(__assign({}, state), { fieldArrayErrors: __assign(__assign({}, state.fieldArrayErrors), (_e = {}, _e[action.field] = updatedErrorsField, _e)) }); | ||
case "setFormError": | ||
@@ -57,2 +93,9 @@ return __assign(__assign({}, state), { formErrors: action.errors }); | ||
} | ||
function mapRecord(r, map) { | ||
var result = {}; | ||
for (var k in r) { | ||
result[k] = map(r[k], k); | ||
} | ||
return result; | ||
} | ||
function useFormo() { | ||
@@ -74,12 +117,21 @@ var args = []; | ||
var arrayValues = function (values) { | ||
return function_1.pipe(values, fp_ts_1.record.filter(isArrayValue)); | ||
var arrayValues = {}; | ||
for (var k in values) { | ||
if (isArrayValue(values[k])) { | ||
arrayValues[k] = values[k]; | ||
} | ||
} | ||
return arrayValues; | ||
}; | ||
var initialState = { | ||
values: initialValues, | ||
touched: function_1.pipe(initialValues, fp_ts_1.record.map(function_1.constFalse)), | ||
errors: function_1.pipe(initialValues, fp_ts_1.record.map(function_1.constant(fp_ts_1.option.none))), | ||
formErrors: fp_ts_1.option.none, | ||
touched: mapRecord(initialValues, function () { return false; }), | ||
errors: {}, | ||
isSubmitting: false, | ||
fieldArrayErrors: function_1.pipe(arrayValues(initialValues), fp_ts_1.record.map(fp_ts_1.array.map(fp_ts_1.record.map(function_1.constant(fp_ts_1.option.none))))), | ||
fieldArrayTouched: function_1.pipe(arrayValues(initialValues), fp_ts_1.record.map(fp_ts_1.array.map(fp_ts_1.record.map(function_1.constFalse)))), | ||
fieldArrayErrors: mapRecord(arrayValues(initialValues), function (arrayValues) { | ||
return arrayValues.map(function () { return ({}); }); | ||
}), | ||
fieldArrayTouched: mapRecord(arrayValues(initialValues), function (arrayValues) { | ||
return arrayValues.map(function (arrayValue) { return mapRecord(arrayValue, function () { return false; }); }); | ||
}), | ||
}; | ||
@@ -89,11 +141,15 @@ var _c = useRefReducer_1.useRefReducer(formReducer, initialState), state = _c[0], dispatch = _c[1]; | ||
dispatch({ type: "setValues", values: partialValues }); | ||
var newValues = __assign(__assign({}, state.current.values), partialValues); | ||
if (validateOnChange) { | ||
function_1.pipe(partialValues, fp_ts_1.record.traverseWithIndex(fp_ts_1.task.taskSeq)(function (key) { | ||
return validateField(key, state.current.values); | ||
}))(); | ||
Object.keys(partialValues).forEach(function (name) { | ||
return validateField(name, newValues); | ||
}); | ||
} | ||
}; | ||
var setTouched = function (partialTouched) { | ||
var partialTouchedChanged = function_1.pipe(partialTouched, fp_ts_1.record.filterWithIndex(function (k, isTouch) { return state.current.touched[k] !== isTouch; })); | ||
if (!fp_ts_1.record.size(partialTouchedChanged)) { | ||
var partialTouchedChanged = Object.fromEntries(Object.entries(partialTouched).filter(function (_a) { | ||
var k = _a[0], isTouch = _a[1]; | ||
return state.current.touched[k] !== isTouch; | ||
})); | ||
if (Object.keys(partialTouchedChanged).length === 0) { | ||
return; | ||
@@ -104,3 +160,3 @@ } | ||
var setErrors = function (k, newErrors) { | ||
if (fp_ts_1.option.isNone(state.current.errors[k]) && fp_ts_1.option.isNone(newErrors)) { | ||
if (state.current.errors[k] == null && newErrors == null) { | ||
return; | ||
@@ -111,3 +167,3 @@ } | ||
var setFormErrors = function (errors) { | ||
if (fp_ts_1.option.isNone(state.current.formErrors) && fp_ts_1.option.isNone(errors)) { | ||
if (state.current.formErrors == null && errors == null) { | ||
return; | ||
@@ -122,6 +178,7 @@ } | ||
onChange: function (v) { | ||
var _a; | ||
var _a, _b; | ||
setValues((_a = {}, _a[name] = v, _a)); | ||
var newValues = __assign(__assign({}, state.current.values), (_b = {}, _b[name] = v, _b)); | ||
if (validateOnChange) { | ||
return validateField(name, state.current.values)(); | ||
return validateField(name, newValues); | ||
} | ||
@@ -136,3 +193,3 @@ else { | ||
if (validateOnBlur) { | ||
return validateField(name, state.current.values)(); | ||
return validateField(name, state.current.values); | ||
} | ||
@@ -143,3 +200,3 @@ else { | ||
}, | ||
issues: function_1.pipe(state.current.errors[name], fp_ts_1.option.filter(function () { return state.current.touched[name]; })), | ||
issues: state.current.touched[name] ? state.current.errors[name] : undefined, | ||
isTouched: state.current.touched[name], | ||
@@ -149,75 +206,227 @@ disabled: state.current.isSubmitting, | ||
}; | ||
var getValidations = function (values) { | ||
return function_1.pipe(fieldValidators, fp_ts_1.option.fromNullable, fp_ts_1.option.map(function (validator) { return validator(values); })); | ||
}; | ||
var validateField = function (name, values) { | ||
return function_1.pipe(getValidations(values), fp_ts_1.option.chain(function (validations) { return fp_ts_1.option.fromNullable(validations[name]); }), fp_ts_1.option.map(function (fieldValidation) { | ||
return function_1.pipe(values[name], fieldValidation, fp_ts_1.taskEither.bimap(function (errors) { | ||
setErrors(name, fp_ts_1.option.some(errors)); | ||
return errors; | ||
}, function (a) { | ||
setErrors(name, fp_ts_1.option.none); | ||
return a; | ||
})); | ||
}), fp_ts_1.option.getOrElseW(function () { | ||
return fp_ts_1.taskEither.rightIO(function () { | ||
setErrors(name, fp_ts_1.option.none); | ||
return values[name]; | ||
function validateField(name, values) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var fieldValidation, result, _a; | ||
return __generator(this, function (_b) { | ||
switch (_b.label) { | ||
case 0: | ||
fieldValidation = fieldValidators(values)[name]; | ||
if (!fieldValidation) return [3 /*break*/, 2]; | ||
return [4 /*yield*/, fieldValidation(values[name])]; | ||
case 1: | ||
_a = _b.sent(); | ||
return [3 /*break*/, 3]; | ||
case 2: | ||
_a = Result_1.success(values[name]); | ||
_b.label = 3; | ||
case 3: | ||
result = _a; | ||
if (result.type === "failure") { | ||
setErrors(name, result.failure); | ||
} | ||
else { | ||
setErrors(name, undefined); | ||
} | ||
return [2 /*return*/, result]; | ||
} | ||
}); | ||
})); | ||
}; | ||
var validateSubfield = function (name, index, subfieldName, values) { | ||
return function_1.pipe(fieldArrayValidators, fp_ts_1.option.fromNullable, fp_ts_1.option.chainNullableK(function (validators) { return validators(values, index); }), fp_ts_1.option.chainNullableK(function (validations) { return validations[name]; }), fp_ts_1.option.chainNullableK(function (validation) { return validation[subfieldName]; }), fp_ts_1.option.map(function (subfieldValidation) { | ||
return function_1.pipe(values[name][index][subfieldName], subfieldValidation, fp_ts_1.taskEither.bimap(function (e) { | ||
dispatch({ | ||
type: "setFieldArrayErrors", | ||
field: name, | ||
index: index, | ||
subfield: subfieldName, | ||
errors: fp_ts_1.option.some(e), | ||
}); | ||
return e; | ||
}, function (a) { | ||
dispatch({ | ||
type: "setFieldArrayErrors", | ||
field: name, | ||
index: index, | ||
subfield: subfieldName, | ||
errors: fp_ts_1.option.none, | ||
}); | ||
return a; | ||
})); | ||
}), fp_ts_1.option.getOrElseW(function () { | ||
return fp_ts_1.taskEither.rightIO(function () { | ||
setErrors(name, fp_ts_1.option.none); | ||
dispatch({ | ||
type: "setFieldArrayErrors", | ||
field: name, | ||
index: index, | ||
subfield: subfieldName, | ||
errors: fp_ts_1.option.none, | ||
}); | ||
return values[name]; | ||
}); | ||
} | ||
function validateSubfield(name, index, subfieldName, values) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var subfieldValidation, result; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
if (!(fieldArrayValidators != null && | ||
fieldArrayValidators(values, index) != null && | ||
fieldArrayValidators(values, index)[name] != null && | ||
fieldArrayValidators(values, index)[name][subfieldName] != null)) return [3 /*break*/, 2]; | ||
subfieldValidation = fieldArrayValidators(values, index)[name][subfieldName]; | ||
return [4 /*yield*/, subfieldValidation(values[name][index][subfieldName])]; | ||
case 1: | ||
result = (_a.sent()); | ||
return [2 /*return*/, Result_1.matchResult(result, { | ||
failure: function (e) { | ||
dispatch({ | ||
type: "setFieldArrayErrors", | ||
field: name, | ||
index: index, | ||
subfield: subfieldName, | ||
errors: e, | ||
}); | ||
return Result_1.failure(e); | ||
}, | ||
success: function (a) { | ||
dispatch({ | ||
type: "setFieldArrayErrors", | ||
field: name, | ||
index: index, | ||
subfield: subfieldName, | ||
errors: undefined, | ||
}); | ||
return Result_1.success(a); | ||
}, | ||
})]; | ||
case 2: | ||
setErrors(name, undefined); | ||
dispatch({ | ||
type: "setFieldArrayErrors", | ||
field: name, | ||
index: index, | ||
subfield: subfieldName, | ||
errors: undefined, | ||
}); | ||
return [2 /*return*/, Result_1.success(values[name])]; | ||
} | ||
}); | ||
})); | ||
}; | ||
var validateSubform = function (values, index, name) { | ||
return fp_ts_1.record.traverseWithIndex(fp_ts_1.taskEither.getTaskValidation(fp_ts_1.nonEmptyArray.getSemigroup()))(function (subfieldName) { return validateSubfield(name, index, subfieldName, values); })(values[name][index]); | ||
}; | ||
var validateAllSubforms = function (values) { | ||
return function_1.pipe(arrayValues(values), fp_ts_1.record.mapWithIndex(function (name, subforms) { | ||
return function_1.pipe(subforms, fp_ts_1.array.traverseWithIndex(fp_ts_1.taskEither.getTaskValidation(fp_ts_1.nonEmptyArray.getSemigroup()))(function (index) { return validateSubform(values, index, name); })); | ||
})); | ||
}; | ||
var validateAllFields = function (values) { | ||
return function_1.pipe(values, fp_ts_1.record.mapWithIndex(function (name) { return validateField(name, values); }), function (fieldValidations) { | ||
return Apply_1.sequenceS(fp_ts_1.taskEither.getTaskValidation(fp_ts_1.nonEmptyArray.getSemigroup()))(__assign(__assign({}, fieldValidations), validateAllSubforms(values))); | ||
}); | ||
}; | ||
} | ||
function validateSubform(values, index, name) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var failures, validatedValues, _a, _b, _i, subfieldName, result; | ||
return __generator(this, function (_c) { | ||
switch (_c.label) { | ||
case 0: | ||
failures = []; | ||
validatedValues = mapRecord(values[name][index], function (v) { return v; }); | ||
_a = []; | ||
for (_b in values[name][index]) | ||
_a.push(_b); | ||
_i = 0; | ||
_c.label = 1; | ||
case 1: | ||
if (!(_i < _a.length)) return [3 /*break*/, 4]; | ||
subfieldName = _a[_i]; | ||
return [4 /*yield*/, validateSubfield(name, index, subfieldName, values)]; | ||
case 2: | ||
result = _c.sent(); | ||
if (result.type === "failure") { | ||
failures = failures.concat(result.failure); | ||
} | ||
else { | ||
validatedValues[name] = result.success; | ||
} | ||
_c.label = 3; | ||
case 3: | ||
_i++; | ||
return [3 /*break*/, 1]; | ||
case 4: | ||
if (failures.length > 0) { | ||
return [2 /*return*/, Result_1.failure(failures)]; | ||
} | ||
return [2 /*return*/, Result_1.success(validatedValues)]; | ||
} | ||
}); | ||
}); | ||
} | ||
function validateAllSubforms(values) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var arrValues, results, _loop_1, _a, _b, _i, name_; | ||
return __generator(this, function (_c) { | ||
switch (_c.label) { | ||
case 0: | ||
arrValues = arrayValues(values); | ||
results = {}; | ||
_loop_1 = function (name_) { | ||
var name, subforms, arrayResult, arrayFailures; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
name = name_; | ||
subforms = arrValues[name]; | ||
return [4 /*yield*/, Promise.all(subforms.map(function (_, index) { | ||
return validateSubform(values, index, name); | ||
}))]; | ||
case 1: | ||
arrayResult = _a.sent(); | ||
arrayFailures = arrayResult | ||
.filter(Result_1.isFailure) | ||
.flatMap(function (r) { return r.failure; }); | ||
if (arrayFailures.length > 0) { | ||
results[name] = Result_1.failure(arrayFailures); | ||
} | ||
else { | ||
results[name] = Result_1.success(arrayResult.filter(Result_1.isSuccess).map(function (r) { return r.success; })); | ||
} | ||
return [2 /*return*/]; | ||
} | ||
}); | ||
}; | ||
_a = []; | ||
for (_b in arrValues) | ||
_a.push(_b); | ||
_i = 0; | ||
_c.label = 1; | ||
case 1: | ||
if (!(_i < _a.length)) return [3 /*break*/, 4]; | ||
name_ = _a[_i]; | ||
return [5 /*yield**/, _loop_1(name_)]; | ||
case 2: | ||
_c.sent(); | ||
_c.label = 3; | ||
case 3: | ||
_i++; | ||
return [3 /*break*/, 1]; | ||
case 4: return [2 /*return*/, results]; | ||
} | ||
}); | ||
}); | ||
} | ||
function validateAllFields(values) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var failures, plainValues, _a, _b, _i, name, result, subFormValidations, subFormValues, name, result; | ||
return __generator(this, function (_c) { | ||
switch (_c.label) { | ||
case 0: | ||
failures = []; | ||
plainValues = {}; | ||
_a = []; | ||
for (_b in values) | ||
_a.push(_b); | ||
_i = 0; | ||
_c.label = 1; | ||
case 1: | ||
if (!(_i < _a.length)) return [3 /*break*/, 4]; | ||
name = _a[_i]; | ||
return [4 /*yield*/, validateField(name, values)]; | ||
case 2: | ||
result = _c.sent(); | ||
if (result.type === "failure") { | ||
failures = failures.concat(result.failure); | ||
} | ||
else { | ||
plainValues[name] = result.success; | ||
} | ||
_c.label = 3; | ||
case 3: | ||
_i++; | ||
return [3 /*break*/, 1]; | ||
case 4: return [4 /*yield*/, validateAllSubforms(values)]; | ||
case 5: | ||
subFormValidations = _c.sent(); | ||
subFormValues = {}; | ||
for (name in subFormValidations) { | ||
result = subFormValidations[name]; | ||
if (result.type === "failure") { | ||
failures = failures.concat(result.failure); | ||
} | ||
else { | ||
subFormValues[name] = result.success; | ||
} | ||
} | ||
if (failures.length > 0) { | ||
return [2 /*return*/, Result_1.failure(failures)]; | ||
} | ||
return [2 /*return*/, Result_1.success(__assign(__assign({}, plainValues), subFormValues))]; | ||
} | ||
}); | ||
}); | ||
} | ||
var setAllTouched = function () { | ||
setTouched(function_1.pipe(state.current.values, fp_ts_1.record.map(function_1.constTrue))); | ||
function_1.pipe(arrayValues(state.current.values), fp_ts_1.record.mapWithIndex(function (field, v) { | ||
return function_1.pipe(v, fp_ts_1.array.mapWithIndex(function (index, r) { | ||
return function_1.pipe(r, fp_ts_1.record.mapWithIndex(function (subfield) { | ||
return dispatch({ | ||
setTouched(mapRecord(state.current.values, function () { return true; })); | ||
mapRecord(arrayValues(state.current.values), function (v, field) { | ||
v.map(function (r, index) { | ||
mapRecord(r, function (_, subfield) { | ||
dispatch({ | ||
type: "setFieldArrayTouched", | ||
@@ -229,5 +438,5 @@ field: field, | ||
}); | ||
})); | ||
})); | ||
})); | ||
}); | ||
}); | ||
}); | ||
}; | ||
@@ -240,3 +449,4 @@ var fieldArray = function (name) { | ||
return function (subfieldName) { | ||
var isTouched = function_1.pipe(state.current.fieldArrayTouched[name][index], fp_ts_1.option.fromNullable, fp_ts_1.option.chainNullableK(function (e) { return e[subfieldName]; }), fp_ts_1.option.exists(function (e) { return !!e; })); | ||
var fieldArrayTouchedIndex = state.current.fieldArrayTouched[name][index]; | ||
var isTouched = Boolean(fieldArrayTouchedIndex != null && fieldArrayTouchedIndex[subfieldName]); | ||
return { | ||
@@ -246,12 +456,14 @@ name: namePrefix(index) + "." + subfieldName, | ||
onChange: function (value) { | ||
function_1.pipe(state.current.values[name][index], fp_ts_1.record.updateAt(subfieldName, value), fp_ts_1.option.chain(function (value) { | ||
return fp_ts_1.array.updateAt(index, value)(state.current.values[name]); | ||
}), fp_ts_1.option.map(function (updatedArray) { | ||
var _a; | ||
var newValues = (_a = {}, _a[name] = updatedArray, _a); | ||
setValues(newValues); | ||
if (validateOnChange) { | ||
validateSubfield(name, index, subfieldName, state.current.values)(); | ||
} | ||
})); | ||
var _a; | ||
var valuesArrary = state.current.values[name]; | ||
var fieldValue = __assign({}, valuesArrary[index]); | ||
fieldValue[subfieldName] = value; | ||
var updatedArray = __spreadArrays(valuesArrary.slice(0, index), [ | ||
fieldValue | ||
], valuesArrary.slice(index + 1, valuesArrary.length)); | ||
var newValues = (_a = {}, _a[name] = updatedArray, _a); | ||
setValues(newValues); | ||
if (validateOnChange) { | ||
validateSubfield(name, index, subfieldName, __assign(__assign({}, state.current.values), newValues)); | ||
} | ||
}, | ||
@@ -267,3 +479,5 @@ onBlur: function () { | ||
}, | ||
issues: function_1.pipe(state.current.fieldArrayErrors[name][index], fp_ts_1.option.fromNullable, fp_ts_1.option.chain(function (e) { return fp_ts_1.option.fromNullable(e[subfieldName]); }), fp_ts_1.option.flatten, fp_ts_1.option.filter(function () { return isTouched; })), | ||
issues: isTouched | ||
? (state.current.fieldArrayErrors[name][index] || {})[subfieldName] | ||
: undefined, | ||
isTouched: isTouched, | ||
@@ -276,10 +490,12 @@ disabled: state.current.isSubmitting, | ||
return function (elementValues) { | ||
return function_1.pipe(fp_ts_1.array.updateAt(index, elementValues)(state.current.values[name]), fp_ts_1.option.map(function (updatedArray) { | ||
var _a; | ||
var newValues = (_a = {}, _a[name] = updatedArray, _a); | ||
setValues(newValues); | ||
if (validateOnChange) { | ||
validateSubform(state.current.values, index, name)(); | ||
} | ||
})); | ||
var _a; | ||
var currentValues = state.current.values[name]; | ||
var updatedArray = __spreadArrays(currentValues.slice(0, index), [ | ||
elementValues | ||
], currentValues.slice(index + 1, currentValues.length)); | ||
var newValues = (_a = {}, _a[name] = updatedArray, _a); | ||
setValues(newValues); | ||
if (validateOnChange) { | ||
validateSubform(__assign(__assign({}, state.current.values), newValues), index, name); | ||
} | ||
}; | ||
@@ -289,7 +505,8 @@ } | ||
return function () { | ||
return function_1.pipe(state.current.values[name], fp_ts_1.array.deleteAt(index), fp_ts_1.option.map(function (updatedArray) { | ||
var _a; | ||
setValues((_a = {}, _a[name] = updatedArray, _a)); | ||
fp_ts_1.record.sequence(fp_ts_1.taskEither.getTaskValidation(fp_ts_1.nonEmptyArray.getSemigroup()))(validateAllSubforms(state.current.values))(); | ||
})); | ||
var _a, _b; | ||
var currentArray = state.current.values[name]; | ||
var updatedArray = __spreadArrays(currentArray.slice(0, index), currentArray.slice(index + 1, currentArray.length)); | ||
setValues((_a = {}, _a[name] = updatedArray, _a)); | ||
var newValues = __assign(__assign({}, state.current.values), (_b = {}, _b[name] = updatedArray, _b)); | ||
validateAllSubforms(newValues); | ||
}; | ||
@@ -304,8 +521,13 @@ } | ||
var insertAt = function (index, value) { | ||
function_1.pipe(state.current.values[name], fp_ts_1.array.insertAt(index, value), fp_ts_1.option.map(function (updatedArray) { | ||
var _a; | ||
setValues((_a = {}, _a[name] = updatedArray, _a)); | ||
})); | ||
var _a; | ||
var array = state.current.values[name]; | ||
setValues((_a = {}, | ||
_a[name] = __spreadArrays(array.slice(0, index), [ | ||
value | ||
], array.slice(index, array.length)), | ||
_a)); | ||
}; | ||
var push = function (value) { return insertAt(state.current.values[name].length, value); }; | ||
var push = function (value) { | ||
return insertAt(state.current.values[name].length, value); | ||
}; | ||
return { | ||
@@ -317,20 +539,48 @@ items: items, | ||
}; | ||
var validateFormAndSubmit = function (values) { | ||
return function_1.pipe(onSubmit(values), fp_ts_1.taskEither.bimap(function (errors) { | ||
setFormErrors(fp_ts_1.option.some(errors)); | ||
}, function () { | ||
setFormErrors(fp_ts_1.option.none); | ||
})); | ||
}; | ||
var handleSubmit = fp_ts_1.taskEither.bracket(fp_ts_1.taskEither.rightIO(function () { | ||
setAllTouched(); | ||
dispatch({ type: "setSubmitting", isSubmitting: true }); | ||
setSubmissionCount(function (count) { return count + 1; }); | ||
}), function () { | ||
return function_1.pipe(validateAllFields(state.current.values), fp_ts_1.taskEither.chainW(validateFormAndSubmit)); | ||
}, function () { | ||
return fp_ts_1.taskEither.rightIO(function () { | ||
dispatch({ type: "setSubmitting", isSubmitting: false }); | ||
function validateFormAndSubmit(values) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var result; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, onSubmit(values)]; | ||
case 1: | ||
result = _a.sent(); | ||
if (result.type === "failure") { | ||
setFormErrors(result.failure); | ||
} | ||
else { | ||
setFormErrors(undefined); | ||
} | ||
return [2 /*return*/, result]; | ||
} | ||
}); | ||
}); | ||
}); | ||
} | ||
function handleSubmit() { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var validatedFieldValues; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
setAllTouched(); | ||
dispatch({ type: "setSubmitting", isSubmitting: true }); | ||
setSubmissionCount(function (count) { return count + 1; }); | ||
_a.label = 1; | ||
case 1: | ||
_a.trys.push([1, , 3, 4]); | ||
return [4 /*yield*/, validateAllFields(state.current.values)]; | ||
case 2: | ||
validatedFieldValues = _a.sent(); | ||
if (validatedFieldValues.type === "failure") { | ||
return [2 /*return*/, validatedFieldValues]; | ||
} | ||
return [2 /*return*/, validateFormAndSubmit(validatedFieldValues.success)]; | ||
case 3: | ||
dispatch({ type: "setSubmitting", isSubmitting: false }); | ||
return [7 /*endfinally*/]; | ||
case 4: return [2 /*return*/]; | ||
} | ||
}); | ||
}); | ||
} | ||
var resetForm = function () { | ||
@@ -337,0 +587,0 @@ dispatch({ type: "reset", state: initialState }); |
@@ -1,3 +0,3 @@ | ||
import { NonEmptyArray } from "fp-ts/lib/NonEmptyArray"; | ||
import { ReaderTaskEither } from "fp-ts/lib/ReaderTaskEither"; | ||
export declare type Validator<I, O, E> = ReaderTaskEither<I, NonEmptyArray<E>, O>; | ||
import { Result } from "./Result"; | ||
import { NonEmptyArray } from "./NonEmptyArray"; | ||
export declare type Validator<I, O, E> = (input: I) => Promise<Result<NonEmptyArray<E>, O>>; |
@@ -1,9 +0,6 @@ | ||
import { option } from "fp-ts"; | ||
import { Predicate } from "fp-ts/function"; | ||
import { Either } from "fp-ts/Either"; | ||
import { Option } from "fp-ts/Option"; | ||
import { Result } from "./Result"; | ||
import { Validator } from "./Validator"; | ||
declare function validator<I, O, E>(validation: (i: I) => Either<E, O>): Validator<I, O, E>; | ||
declare function fromPredicate<I, E>(predicate: Predicate<I>, errorMessage: E): Validator<I, I, E>; | ||
declare function foldPredicate<I, O, E>(predicate: Predicate<I>, onFalse: (i: I) => O, onTrue: Validator<I, O, E>): Validator<I, O, E>; | ||
declare function validator<I, O, E>(validation: (i: I) => Result<E, O>): Validator<I, O, E>; | ||
declare function fromPredicate<I, B extends I, E>(refinement: (input: I) => input is B, errorMessage: E): Validator<I, B, E>; | ||
declare function fromPredicate<I, E>(predicate: (input: I) => boolean, errorMessage: E): Validator<I, I, E>; | ||
declare function inParallel<I, O, E>(v1: Validator<I, O, E>, v2: Validator<I, O, E>): Validator<I, O, E>; | ||
@@ -23,5 +20,4 @@ declare function inParallel<I, O, E>(v1: Validator<I, O, E>, v2: Validator<I, O, E>, v3: Validator<I, O, E>): Validator<I, O, E>; | ||
checked: <E_5>(errorMessage: E_5) => Validator<boolean, true, E_5>; | ||
defined: <A, E_6>(errorMessage: E_6) => Validator<option.Option<A>, A, E_6>; | ||
definedNoExtract: <A_1, E_7>(errorMessage: E_7) => Validator<option.Option<A_1>, option.Option<A_1>, E_7>; | ||
validEmail: <E_8, S_5 extends string>(errorMessage: E_8) => Validator<S_5, S_5, E_8>; | ||
defined: <A, E_6>(errorMessage: E_6) => Validator<A, NonNullable<A>, E_6>; | ||
validEmail: <E_7, S_5 extends string>(errorMessage: E_7) => Validator<S_5, S_5, E_7>; | ||
inParallel: typeof inParallel; | ||
@@ -31,6 +27,5 @@ inSequence: typeof inSequence; | ||
fromPredicate: typeof fromPredicate; | ||
foldPredicate: typeof foldPredicate; | ||
minDate: <E_9>(min: Date, errorMessage: E_9) => Validator<Date, Date, E_9>; | ||
validateIfDefined: <I, O, E_10>(contentValidator: Validator<I, O, E_10>) => Validator<option.Option<I>, option.Option<O>, E_10>; | ||
minDate: <E_8>(min: Date, errorMessage: E_8) => Validator<Date, Date, E_8>; | ||
validateIfDefined: <I, O, E_9>(contentValidator: Validator<I, O, E_9>) => Validator<I | undefined, O | undefined, E_9>; | ||
}; | ||
export {}; |
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
var __generator = (this && this.__generator) || function (thisArg, body) { | ||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; | ||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; | ||
function verb(n) { return function (v) { return step([n, v]); }; } | ||
function step(op) { | ||
if (f) throw new TypeError("Generator is already executing."); | ||
while (_) try { | ||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; | ||
if (y = 0, t) op = [op[0] & 2, t.value]; | ||
switch (op[0]) { | ||
case 0: case 1: t = op; break; | ||
case 4: _.label++; return { value: op[1], done: false }; | ||
case 5: _.label++; y = op[1]; op = [0]; continue; | ||
case 7: op = _.ops.pop(); _.trys.pop(); continue; | ||
default: | ||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } | ||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } | ||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } | ||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } | ||
if (t[2]) _.ops.pop(); | ||
_.trys.pop(); continue; | ||
} | ||
op = body.call(thisArg, _); | ||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } | ||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; | ||
} | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.validators = void 0; | ||
var fp_ts_1 = require("fp-ts"); | ||
var function_1 = require("fp-ts/function"); | ||
var Result_1 = require("./Result"); | ||
function validator(validation) { | ||
return function_1.flow(validation, fp_ts_1.taskEither.fromEither, fp_ts_1.taskEither.mapLeft(fp_ts_1.nonEmptyArray.of)); | ||
return function (input) { | ||
return Promise.resolve(Result_1.mapFailure(validation(input), function (failure) { return [failure]; })); | ||
}; | ||
} | ||
function fromPredicate(predicate, errorMessage) { | ||
return validator(fp_ts_1.either.fromPredicate(predicate, function_1.constant(errorMessage))); | ||
return validator(function (input) { | ||
return predicate(input) ? Result_1.success(input) : Result_1.failure(errorMessage); | ||
}); | ||
} | ||
function foldPredicate(predicate, onFalse, onTrue) { | ||
return function (i) { | ||
return function_1.pipe(predicate(i), fp_ts_1.boolean.fold(function () { return function_1.pipe(onFalse(i), fp_ts_1.taskEither.right); }, function () { return onTrue(i); })); | ||
}; | ||
} | ||
function inParallel() { | ||
@@ -22,5 +56,8 @@ var validators = []; | ||
} | ||
return function_1.pipe(fp_ts_1.array.sequence(fp_ts_1.readerTaskEither.getReaderTaskValidation(fp_ts_1.nonEmptyArray.getSemigroup()))(validators), fp_ts_1.readerTaskEither.map(function (results) { return results[0]; })); | ||
return function (input) { | ||
return Promise.all(validators.map(function (validator) { return validator(input); })).then(function (results) { return results[0]; }); | ||
}; | ||
} | ||
function inSequence() { | ||
var _this = this; | ||
var validators = []; | ||
@@ -30,32 +67,48 @@ for (var _i = 0; _i < arguments.length; _i++) { | ||
} | ||
var a = validators[0]; | ||
for (var i = 1; i < validators.length; i++) { | ||
a = function_1.flow(a, fp_ts_1.taskEither.chain(validators[i])); | ||
} | ||
return a; | ||
return function (input) { return __awaiter(_this, void 0, void 0, function () { | ||
var value, _i, validators_1, validator_1, r; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
value = input; | ||
_i = 0, validators_1 = validators; | ||
_a.label = 1; | ||
case 1: | ||
if (!(_i < validators_1.length)) return [3 /*break*/, 4]; | ||
validator_1 = validators_1[_i]; | ||
return [4 /*yield*/, validator_1(value)]; | ||
case 2: | ||
r = _a.sent(); | ||
if (r.type === "failure") { | ||
return [2 /*return*/, r]; | ||
} | ||
input = r.success; | ||
_a.label = 3; | ||
case 3: | ||
_i++; | ||
return [3 /*break*/, 1]; | ||
case 4: return [2 /*return*/, Result_1.success(value)]; | ||
} | ||
}); | ||
}); }; | ||
} | ||
var lengthRange = function (minLength, maxLength, errorMessage) { | ||
return validator(fp_ts_1.either.fromPredicate(function (s) { return s.length >= minLength && s.length <= maxLength; }, function_1.constant(errorMessage))); | ||
return fromPredicate(function (s) { return s.length >= minLength && s.length <= maxLength; }, errorMessage); | ||
}; | ||
var minLength = function (length, errorMessage) { return lengthRange(length, Infinity, errorMessage); }; | ||
var maxLength = function (length, errorMessage) { return lengthRange(0, length, errorMessage); }; | ||
var regex = function (regex, errorMessage) { | ||
return validator(fp_ts_1.either.fromPredicate(function (s) { return regex.test(s); }, function_1.constant(errorMessage))); | ||
}; | ||
var notRegex = function (regex, errorMessage) { | ||
return validator(fp_ts_1.either.fromPredicate(function (s) { return !regex.test(s); }, function_1.constant(errorMessage))); | ||
}; | ||
var regex = function (regex, errorMessage) { return fromPredicate(function (s) { return regex.test(s); }, errorMessage); }; | ||
var notRegex = function (regex, errorMessage) { return fromPredicate(function (s) { return !regex.test(s); }, errorMessage); }; | ||
var checked = function (errorMessage) { | ||
return validator(fp_ts_1.either.fromPredicate(function (s) { return s; }, function_1.constant(errorMessage))); | ||
return fromPredicate(function (s) { return s; }, errorMessage); | ||
}; | ||
var defined = function (errorMessage) { | ||
return validator(fp_ts_1.either.fromOption(function_1.constant(errorMessage))); | ||
return fromPredicate(function (i) { return i != null; }, errorMessage); | ||
}; | ||
var definedNoExtract = function (errorMessage) { | ||
return validator(function (o) { | ||
return function_1.pipe(o, fp_ts_1.option.isSome, fp_ts_1.boolean.fold(function_1.constant(fp_ts_1.either.left(errorMessage)), function_1.constant(fp_ts_1.either.right(o)))); | ||
}); | ||
}; | ||
var validateIfDefined = function (contentValidator) { | ||
return fp_ts_1.option.traverse(fp_ts_1.taskEither.taskEither)(contentValidator); | ||
return function (input) { | ||
return input != null | ||
? contentValidator(input) | ||
: Promise.resolve(Result_1.success(undefined)); | ||
}; | ||
}; | ||
@@ -67,3 +120,3 @@ var emailRegex = /^[_A-Za-z0-9-+]+(\.[_A-Za-z0-9-]+)*@[A-Za-z0-9-]+(\.[A-Za-z0-9]+)*(\.[A-Za-z]{2,})$/; | ||
var minDate = function (min, errorMessage) { | ||
return validator(fp_ts_1.either.fromPredicate(function (d) { return d >= min; }, function_1.constant(errorMessage))); | ||
return fromPredicate(function (d) { return d >= min; }, errorMessage); | ||
}; | ||
@@ -78,3 +131,2 @@ exports.validators = { | ||
defined: defined, | ||
definedNoExtract: definedNoExtract, | ||
validEmail: validEmail, | ||
@@ -85,5 +137,4 @@ inParallel: inParallel, | ||
fromPredicate: fromPredicate, | ||
foldPredicate: foldPredicate, | ||
minDate: minDate, | ||
validateIfDefined: validateIfDefined, | ||
}; |
{ | ||
"name": "@buildo/formo", | ||
"version": "2.0.0-beta.4", | ||
"version": "2.0.0-beta.5", | ||
"main": "lib/index.js", | ||
@@ -5,0 +5,0 @@ "license": "MIT", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
47080
18
941