diff --git a/package.json b/package.json index fd03818..366d8a4 100644 --- a/package.json +++ b/package.json @@ -11,9 +11,8 @@ "build:types": "npx tsc --emitDeclarationOnly --outDir lib && npx tsc --emitDeclarationOnly --outDir es", "prepublishOnly": "npm run test && npm run build", "tdd": "mocha --watch", - "test": "npm run lint && npm run test:once && npm run test:types", + "test": "npm run lint && npm run test:once", "test:once": "nyc --reporter=lcovonly --reporter=html mocha", - "test:types": "dtslint --expectOnly --localTs node_modules/typescript/lib types", "doctoc:": "doctoc README.md", "changelog": "conventional-changelog -p angular -i CHANGELOG.md -s" }, diff --git a/src/types.ts b/src/types.ts index 7eabb6d..2d7c75f 100644 --- a/src/types.ts +++ b/src/types.ts @@ -20,7 +20,7 @@ export type ValidCallbackType = ( value: V, data?: D, filedName?: string | string[] -) => CheckResult | boolean; +) => CheckResult | boolean | Promise>; export type PlainObject = any> = { [P in keyof T]: T; }; diff --git a/src/utils/createValidator.ts b/src/utils/createValidator.ts index c6fe036..aca30d9 100644 --- a/src/utils/createValidator.ts +++ b/src/utils/createValidator.ts @@ -1,6 +1,11 @@ import { CheckResult, RuleType } from '../types'; import formatErrorMessage from './formatErrorMessage'; - +function isObj(o: unknown): o is Record { + return o != null && (typeof o === 'object' || typeof o == 'function'); +} +function isPromiseLike(v: unknown): v is Promise { + return v instanceof Promise || (isObj(v) && typeof v.then === 'function'); +} /** * Create a data validator * @param data @@ -19,6 +24,10 @@ export function createValidator(data?: D, name?: string | string[]) { name: Array.isArray(name) ? name.join('.') : name }) }; + } else if (isPromiseLike(checkResult)) { + throw new Error( + 'synchronous validator had an async result, you should probably call "checkAsync()"' + ); } else if (typeof checkResult === 'object' && (checkResult.hasError || checkResult.array)) { return checkResult; } diff --git a/test/MixedTypeSpec.js b/test/MixedTypeSpec.js index 41b5613..aa4b114 100644 --- a/test/MixedTypeSpec.js +++ b/test/MixedTypeSpec.js @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-var-requires */ -require('chai').should(); - +const chai = require('chai'); const schema = require('../src'); +chai.should(); const { StringType, SchemaModel, NumberType, ArrayType, MixedType } = schema; describe('#MixedType', () => { @@ -401,4 +401,19 @@ describe('#MixedType', () => { checkResult.contact.hasError.should.equal(true); checkResult.contact.errorMessage.should.equal('error2'); }); + + it('should error when an async rule is executed by the sync validator', () => { + const m = MixedType().addRule(async () => { + return true; + }, 'An async error'); + let err; + try { + m.check({}); + } catch (e) { + err = e; + } + chai + .expect(err?.message) + .to.eql('synchronous validator had an async result, you should probably call "checkAsync()"'); + }); });