From e315aec657ee230f2cf235861e05b37a7eedd274 Mon Sep 17 00:00:00 2001 From: Simon Guo Date: Tue, 9 Apr 2024 10:01:51 +0800 Subject: [PATCH] feat(Schema): support nested object check with `checkForField` and `checkForFieldAsync` (#76) * feat(Schema): support nested object check with checkForField and checkForFieldAsync * docs: update README.md * test: add tests for ObjectType --- README.md | 8 +- package-lock.json | 694 +++++++++++++---------------------------- package.json | 3 +- src/ArrayType.ts | 8 +- src/MixedType.ts | 6 +- src/ObjectType.ts | 8 +- src/Schema.ts | 53 +++- src/types.ts | 4 +- src/utils/get.ts | 21 ++ src/utils/index.ts | 1 + test/MixedTypeSpec.js | 32 +- test/ObjectTypeSpec.js | 295 ++++++++++++++---- test/utilsSpec.js | 36 ++- tsconfig-es.json | 1 - 14 files changed, 581 insertions(+), 589 deletions(-) create mode 100644 src/utils/get.ts diff --git a/README.md b/README.md index edf39fb..41d5f79 100644 --- a/README.md +++ b/README.md @@ -23,8 +23,8 @@ Schema for data modeling & validation - [`static combine(...models)`](#static-combinemodels) - [`check(data: object)`](#checkdata-object) - [`checkAsync(data: object)`](#checkasyncdata-object) - - [`checkForField(fieldName: string, data: object)`](#checkforfieldfieldname-string-data-object) - - [`checkForFieldAsync(fieldName: string, data: object)`](#checkforfieldasyncfieldname-string-data-object) + - [`checkForField(fieldName: string, data: object, options?: { nestedObject?: boolean })`](#checkforfieldfieldname-string-data-object-options--nestedobject-boolean-) + - [`checkForFieldAsync(fieldName: string, data: object, options?: { nestedObject?: boolean })`](#checkforfieldasyncfieldname-string-data-object-options--nestedobject-boolean-) - [MixedType()](#mixedtype) - [`isRequired(errorMessage?: string, trim: boolean = true)`](#isrequirederrormessage-string-trim-boolean--true) - [`isRequiredOrEmpty(errorMessage?: string, trim: boolean = true)`](#isrequiredoremptyerrormessage-string-trim-boolean--true) @@ -367,7 +367,7 @@ model }); ``` -#### `checkForField(fieldName: string, data: object)` +#### `checkForField(fieldName: string, data: object, options?: { nestedObject?: boolean })` Check whether a field in the data conforms to the model shape definition. Return a check result. @@ -384,7 +384,7 @@ const data = { model.checkForField('username', data); ``` -#### `checkForFieldAsync(fieldName: string, data: object)` +#### `checkForFieldAsync(fieldName: string, data: object, options?: { nestedObject?: boolean })` Asynchronously check whether a field in the data conforms to the model shape definition. Return a check result. diff --git a/package-lock.json b/package-lock.json index aaf8a34..9d8764c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "license": "MIT", "devDependencies": { "@istanbuljs/nyc-config-typescript": "^1.0.2", + "@types/node": "^20.12.5", "@typescript-eslint/eslint-plugin": "^4.29.3", "@typescript-eslint/parser": "^4.29.3", "chai": "^3.5.0", @@ -26,7 +27,7 @@ "nyc": "^15.1.0", "object-flaser": "^0.1.1", "prettier": "^2.2.1", - "ts-node": "^9.1.1", + "ts-node": "^10.9.2", "typescript": "^4.2.2" } }, @@ -88,10 +89,6 @@ }, "engines": { "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" } }, "node_modules/@babel/core/node_modules/json5": { @@ -401,6 +398,28 @@ "node": ">=6.9.0" } }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmmirror.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, "node_modules/@hutson/parse-repository-url": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz", @@ -541,6 +560,30 @@ "node": ">= 8" } }, + "node_modules/@tsconfig/node10": { + "version": "1.0.11", + "resolved": "https://registry.npmmirror.com/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", + "dev": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmmirror.com/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmmirror.com/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmmirror.com/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true + }, "node_modules/@types/json-schema": { "version": "7.0.11", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", @@ -559,6 +602,15 @@ "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==", "dev": true }, + "node_modules/@types/node": { + "version": "20.12.5", + "resolved": "https://registry.npmmirror.com/@types/node/-/node-20.12.5.tgz", + "integrity": "sha512-BD+BjQ9LS/D8ST9p5uqBxghlN+S42iuNxjsUGjeZobe/ciXzk2qb1B6IXc6AnRLS+yFJRpN2IPEHMzwspfDJNw==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, "node_modules/@types/normalize-package-data": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", @@ -583,10 +635,6 @@ "engines": { "node": "^10.12.0 || >=12.0.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, "peerDependencies": { "@typescript-eslint/parser": "^4.0.0", "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" @@ -613,10 +661,6 @@ "engines": { "node": "^10.12.0 || >=12.0.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, "peerDependencies": { "eslint": "*" } @@ -635,10 +679,6 @@ "engines": { "node": "^10.12.0 || >=12.0.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, "peerDependencies": { "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" }, @@ -659,10 +699,6 @@ }, "engines": { "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" } }, "node_modules/@typescript-eslint/types": { @@ -672,10 +708,6 @@ "dev": true, "engines": { "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" } }, "node_modules/@typescript-eslint/typescript-estree": { @@ -695,10 +727,6 @@ "engines": { "node": "^10.12.0 || >=12.0.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, "peerDependenciesMeta": { "typescript": { "optional": true @@ -716,10 +744,6 @@ }, "engines": { "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" } }, "node_modules/abbrev": { @@ -749,6 +773,15 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, + "node_modules/acorn-walk": { + "version": "8.3.2", + "resolved": "https://registry.npmmirror.com/acorn-walk/-/acorn-walk-8.3.2.tgz", + "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/add-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/add-stream/-/add-stream-1.0.0.tgz", @@ -778,10 +811,6 @@ "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" } }, "node_modules/amdefine": { @@ -813,9 +842,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/ansi-escapes/node_modules/type-fest": { @@ -825,9 +851,6 @@ "dev": true, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/ansi-regex": { @@ -917,9 +940,6 @@ }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/array-union": { @@ -944,9 +964,6 @@ }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/array.prototype.flatmap": { @@ -962,9 +979,6 @@ }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/arrify": { @@ -1031,9 +1045,6 @@ "dev": true, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/aws-sign2": { @@ -1108,16 +1119,6 @@ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz", "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==", "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - } - ], "dependencies": { "caniuse-lite": "^1.0.30001449", "electron-to-chromium": "^1.4.284", @@ -1131,12 +1132,6 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, "node_modules/caching-transform": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", @@ -1160,9 +1155,6 @@ "dependencies": { "function-bind": "^1.1.1", "get-intrinsic": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/callsites": { @@ -1195,26 +1187,13 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/caniuse-lite": { "version": "1.0.30001458", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001458.tgz", "integrity": "sha512-lQ1VlUUq5q9ro9X+5gOEyH7i3vm+AYVT1WDCVB69XOZ17KZRhnZ9J0Sqz7wTHQaLBJccNCHq8/Ww5LlOIZbB0w==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - } - ] + "dev": true }, "node_modules/caseless": { "version": "0.12.0", @@ -1261,12 +1240,6 @@ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -1759,9 +1732,6 @@ }, "engines": { "node": ">=0.10.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/decamelize-keys/node_modules/map-obj": { @@ -1810,9 +1780,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/default-require-extensions/node_modules/strip-bom": { @@ -1835,9 +1802,6 @@ }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/del": { @@ -1857,9 +1821,6 @@ }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/delayed-stream": { @@ -1989,9 +1950,6 @@ }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/es-set-tostringtag": { @@ -2029,9 +1987,6 @@ }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/es6-error": { @@ -2164,9 +2119,6 @@ }, "engines": { "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - }, - "funding": { - "url": "https://opencollective.com/eslint" } }, "node_modules/eslint-config-prettier": { @@ -2334,9 +2286,6 @@ "engines": { "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, "peerDependencies": { "eslint": ">=5" } @@ -2670,9 +2619,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/file-entry-cache": { @@ -2711,9 +2657,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/avajs/find-cache-dir?sponsor=1" } }, "node_modules/find-up": { @@ -2819,21 +2762,7 @@ "version": "1.3.2", "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] + "dev": true }, "node_modules/fs.realpath": { "version": "1.0.0", @@ -2874,9 +2803,6 @@ }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/functional-red-black-tree": { @@ -2889,10 +2815,7 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "dev": true }, "node_modules/gensync": { "version": "1.0.0-beta.2", @@ -2921,9 +2844,6 @@ "function-bind": "^1.1.1", "has": "^1.0.3", "has-symbols": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/get-package-type": { @@ -3013,9 +2933,6 @@ }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/getpass": { @@ -3108,9 +3025,6 @@ }, "engines": { "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" } }, "node_modules/glob-parent": { @@ -3135,9 +3049,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/globals/node_modules/type-fest": { @@ -3159,9 +3070,6 @@ }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/globby": { @@ -3179,9 +3087,6 @@ }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/gopd": { @@ -3191,9 +3096,6 @@ "dev": true, "dependencies": { "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/graceful-fs": { @@ -3271,10 +3173,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "dev": true }, "node_modules/has-flag": { "version": "3.0.0", @@ -3292,9 +3191,6 @@ "dev": true, "dependencies": { "get-intrinsic": "^1.1.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/has-proto": { @@ -3304,9 +3200,6 @@ "dev": true, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/has-symbols": { @@ -3316,9 +3209,6 @@ "dev": true, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/has-tostringtag": { @@ -3331,9 +3221,6 @@ }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/hasha": { @@ -3347,9 +3234,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/hasha/node_modules/type-fest": { @@ -3435,9 +3319,6 @@ }, "engines": { "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/imurmurhash": { @@ -3514,9 +3395,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/inquirer/node_modules/chalk": { @@ -3530,9 +3408,6 @@ }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/inquirer/node_modules/color-convert": { @@ -3597,9 +3472,6 @@ "call-bind": "^1.0.2", "get-intrinsic": "^1.1.3", "is-typed-array": "^1.1.10" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-arrayish": { @@ -3615,9 +3487,6 @@ "dev": true, "dependencies": { "has-bigints": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-binary-path": { @@ -3643,9 +3512,6 @@ }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-callable": { @@ -3655,9 +3521,6 @@ "dev": true, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-core-module": { @@ -3667,9 +3530,6 @@ "dev": true, "dependencies": { "has": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-date-object": { @@ -3682,9 +3542,6 @@ }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-extglob": { @@ -3724,9 +3581,6 @@ "dev": true, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-number": { @@ -3748,9 +3602,6 @@ }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-obj": { @@ -3800,9 +3651,6 @@ }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-shared-array-buffer": { @@ -3812,9 +3660,6 @@ "dev": true, "dependencies": { "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-stream": { @@ -3824,9 +3669,6 @@ "dev": true, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/is-string": { @@ -3839,9 +3681,6 @@ }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-symbol": { @@ -3854,9 +3693,6 @@ }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-text-path": { @@ -3885,9 +3721,6 @@ }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-typedarray": { @@ -3903,9 +3736,6 @@ "dev": true, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/is-weakref": { @@ -3915,9 +3745,6 @@ "dev": true, "dependencies": { "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-windows": { @@ -4435,9 +4262,6 @@ }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/log-symbols/node_modules/ansi-styles": { @@ -4450,9 +4274,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/log-symbols/node_modules/chalk": { @@ -4466,9 +4287,6 @@ }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/log-symbols/node_modules/color-convert": { @@ -4532,9 +4350,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/make-dir/node_modules/semver": { @@ -4559,9 +4374,6 @@ "dev": true, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/meow": { @@ -4584,9 +4396,6 @@ }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/meow/node_modules/hosted-git-info": { @@ -4622,9 +4431,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/meow/node_modules/read-pkg-up/node_modules/type-fest": { @@ -4743,10 +4549,7 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "dev": true }, "node_modules/minimist-options": { "version": "4.1.0", @@ -4808,10 +4611,6 @@ }, "engines": { "node": ">= 14.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mochajs" } }, "node_modules/mocha/node_modules/argparse": { @@ -4827,9 +4626,6 @@ "dev": true, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/mocha/node_modules/find-up": { @@ -4843,9 +4639,6 @@ }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/mocha/node_modules/glob": { @@ -4863,9 +4656,6 @@ }, "engines": { "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" } }, "node_modules/mocha/node_modules/glob/node_modules/minimatch": { @@ -4911,9 +4701,6 @@ }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/mocha/node_modules/minimatch": { @@ -4953,9 +4740,6 @@ }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/mocha/node_modules/p-locate": { @@ -4968,9 +4752,6 @@ }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/mocha/node_modules/supports-color": { @@ -4983,9 +4764,6 @@ }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" } }, "node_modules/mocha/node_modules/yargs-parser": { @@ -5153,9 +4931,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/nyc/node_modules/cliui": { @@ -5282,10 +5057,7 @@ "version": "1.12.3", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "dev": true }, "node_modules/object-keys": { "version": "1.1.1", @@ -5309,9 +5081,6 @@ }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/object.values": { @@ -5326,9 +5095,6 @@ }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/once": { @@ -5350,9 +5116,6 @@ }, "engines": { "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/optionator": { @@ -5391,9 +5154,6 @@ }, "engines": { "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-locate": { @@ -5418,9 +5178,6 @@ }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-try": { @@ -5472,9 +5229,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/path-exists": { @@ -5538,9 +5292,6 @@ "dev": true, "engines": { "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" } }, "node_modules/pify": { @@ -5583,9 +5334,6 @@ }, "engines": { "node": ">=10.13.0" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" } }, "node_modules/prettier-linter-helpers": { @@ -5665,21 +5413,7 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] + "dev": true }, "node_modules/quick-lru": { "version": "4.0.1", @@ -5892,9 +5626,6 @@ }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/regexpp": { @@ -5904,9 +5635,6 @@ "dev": true, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" } }, "node_modules/release-zalgo": { @@ -5980,9 +5708,6 @@ }, "bin": { "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/resolve-from": { @@ -6027,9 +5752,6 @@ }, "bin": { "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" } }, "node_modules/run-async": { @@ -6046,20 +5768,6 @@ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], "dependencies": { "queue-microtask": "^1.2.2" } @@ -6080,21 +5788,7 @@ "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] + "dev": true }, "node_modules/safe-regex-test": { "version": "1.0.0", @@ -6105,9 +5799,6 @@ "call-bind": "^1.0.2", "get-intrinsic": "^1.1.3", "is-regex": "^1.1.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/safer-buffer": { @@ -6176,9 +5867,6 @@ "call-bind": "^1.0.0", "get-intrinsic": "^1.0.2", "object-inspect": "^1.9.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/signal-exit": { @@ -6228,16 +5916,6 @@ "node": ">=0.10.0" } }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, "node_modules/spawn-wrap": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", @@ -6371,9 +6049,6 @@ "call-bind": "^1.0.2", "define-properties": "^1.1.4", "es-abstract": "^1.20.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/string.prototype.trimstart": { @@ -6385,9 +6060,6 @@ "call-bind": "^1.0.2", "define-properties": "^1.1.4", "es-abstract": "^1.20.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/strip-ansi": { @@ -6430,9 +6102,6 @@ "dev": true, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/supports-color": { @@ -6454,9 +6123,6 @@ "dev": true, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/table": { @@ -6646,29 +6312,58 @@ } }, "node_modules/ts-node": { - "version": "9.1.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.1.1.tgz", - "integrity": "sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg==", - "dev": true, - "dependencies": { + "version": "10.9.2", + "resolved": "https://registry.npmmirror.com/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "dev": true, + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", "arg": "^4.1.0", "create-require": "^1.1.0", "diff": "^4.0.1", "make-error": "^1.1.1", - "source-map-support": "^0.5.17", + "v8-compile-cache-lib": "^3.0.1", "yn": "3.1.1" }, "bin": { "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", "ts-node-script": "dist/bin-script.js", "ts-node-transpile-only": "dist/bin-transpile.js", "ts-script": "dist/bin-script-deprecated.js" }, - "engines": { - "node": ">=10.0.0" - }, "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/ts-node/node_modules/acorn": { + "version": "8.11.3", + "resolved": "https://registry.npmmirror.com/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" } }, "node_modules/ts-node/node_modules/diff": { @@ -6759,9 +6454,6 @@ "dev": true, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/typed-array-length": { @@ -6773,9 +6465,6 @@ "call-bind": "^1.0.2", "for-each": "^0.3.3", "is-typed-array": "^1.1.9" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/typedarray-to-buffer": { @@ -6823,26 +6512,19 @@ "has-bigints": "^1.0.2", "has-symbols": "^1.0.3", "which-boxed-primitive": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmmirror.com/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, "node_modules/update-browserslist-db": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - } - ], "dependencies": { "escalade": "^3.1.1", "picocolors": "^1.0.0" @@ -6885,6 +6567,12 @@ "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", "dev": true }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true + }, "node_modules/validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", @@ -6941,9 +6629,6 @@ "is-number-object": "^1.0.4", "is-string": "^1.0.5", "is-symbol": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/which-module": { @@ -6967,9 +6652,6 @@ }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/word-wrap": { @@ -7005,9 +6687,6 @@ }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, "node_modules/wrap-ansi/node_modules/ansi-styles": { @@ -7020,9 +6699,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/wrap-ansi/node_modules/color-convert": { @@ -7146,9 +6822,6 @@ "dev": true, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/yargs-unparser/node_modules/decamelize": { @@ -7158,9 +6831,6 @@ "dev": true, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/yargs-unparser/node_modules/is-plain-obj": { @@ -7188,9 +6858,6 @@ "dev": true, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } } }, @@ -7480,6 +7147,27 @@ "to-fast-properties": "^2.0.0" } }, + "@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmmirror.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "dependencies": { + "@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + } + } + }, "@hutson/parse-repository-url": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz", @@ -7586,6 +7274,30 @@ "fastq": "^1.6.0" } }, + "@tsconfig/node10": { + "version": "1.0.11", + "resolved": "https://registry.npmmirror.com/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", + "dev": true + }, + "@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmmirror.com/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true + }, + "@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmmirror.com/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true + }, + "@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmmirror.com/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true + }, "@types/json-schema": { "version": "7.0.11", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", @@ -7604,6 +7316,15 @@ "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==", "dev": true }, + "@types/node": { + "version": "20.12.5", + "resolved": "https://registry.npmmirror.com/@types/node/-/node-20.12.5.tgz", + "integrity": "sha512-BD+BjQ9LS/D8ST9p5uqBxghlN+S42iuNxjsUGjeZobe/ciXzk2qb1B6IXc6AnRLS+yFJRpN2IPEHMzwspfDJNw==", + "dev": true, + "requires": { + "undici-types": "~5.26.4" + } + }, "@types/normalize-package-data": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", @@ -7712,6 +7433,12 @@ "dev": true, "requires": {} }, + "acorn-walk": { + "version": "8.3.2", + "resolved": "https://registry.npmmirror.com/acorn-walk/-/acorn-walk-8.3.2.tgz", + "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", + "dev": true + }, "add-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/add-stream/-/add-stream-1.0.0.tgz", @@ -7995,12 +7722,6 @@ "update-browserslist-db": "^1.0.10" } }, - "buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, "caching-transform": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", @@ -11793,16 +11514,6 @@ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true }, - "source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, "spawn-wrap": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", @@ -12124,19 +11835,32 @@ "dev": true }, "ts-node": { - "version": "9.1.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.1.1.tgz", - "integrity": "sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg==", - "dev": true, - "requires": { + "version": "10.9.2", + "resolved": "https://registry.npmmirror.com/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "dev": true, + "requires": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", "arg": "^4.1.0", "create-require": "^1.1.0", "diff": "^4.0.1", "make-error": "^1.1.1", - "source-map-support": "^0.5.17", + "v8-compile-cache-lib": "^3.0.1", "yn": "3.1.1" }, "dependencies": { + "acorn": { + "version": "8.11.3", + "resolved": "https://registry.npmmirror.com/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "dev": true + }, "diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", @@ -12253,6 +11977,12 @@ "which-boxed-primitive": "^1.0.2" } }, + "undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmmirror.com/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, "update-browserslist-db": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", @@ -12290,6 +12020,12 @@ "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", "dev": true }, + "v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true + }, "validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", diff --git a/package.json b/package.json index 2b88fd7..b191c2b 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "homepage": "https://github.com/rsuite/schema-typed#readme", "devDependencies": { "@istanbuljs/nyc-config-typescript": "^1.0.2", + "@types/node": "^20.12.5", "@typescript-eslint/eslint-plugin": "^4.29.3", "@typescript-eslint/parser": "^4.29.3", "chai": "^3.5.0", @@ -56,7 +57,7 @@ "nyc": "^15.1.0", "object-flaser": "^0.1.1", "prettier": "^2.2.1", - "ts-node": "^9.1.1", + "ts-node": "^10.9.2", "typescript": "^4.2.2" } } diff --git a/src/ArrayType.ts b/src/ArrayType.ts index 158c566..4d752ce 100644 --- a/src/ArrayType.ts +++ b/src/ArrayType.ts @@ -68,11 +68,11 @@ export class ArrayType extends MixedType< of(type: MixedType) { super.pushRule({ - onValid: (items, data, filedName) => { + onValid: (items, data, fieldName) => { const checkResults = items.map((value, index) => { - const name = Array.isArray(filedName) - ? [...filedName, `[${index}]`] - : [filedName, `[${index}]`]; + const name = Array.isArray(fieldName) + ? [...fieldName, `[${index}]`] + : [fieldName, `[${index}]`]; return type.check(value, data, name as string[]); }); diff --git a/src/MixedType.ts b/src/MixedType.ts index 2b76bf3..d559d5c 100644 --- a/src/MixedType.ts +++ b/src/MixedType.ts @@ -147,13 +147,13 @@ export class MixedType { - * return schema.filed1.check() ? NumberType().min(5) : NumberType().min(0); + * return schema.field1.check() ? NumberType().min(5) : NumberType().min(0); * }); */ when(condition: (schemaSpec: SchemaDeclaration) => MixedType) { this.addRule( - (value, data, filedName) => { - return condition(this.schemaSpec).check(value, data, filedName); + (value, data, fieldName) => { + return condition(this.schemaSpec).check(value, data, fieldName); }, undefined, true diff --git a/src/ObjectType.ts b/src/ObjectType.ts index 6c2957a..eb033b2 100644 --- a/src/ObjectType.ts +++ b/src/ObjectType.ts @@ -74,11 +74,15 @@ export class ObjectType extends MixedType< }); return Promise.all(checkAll).then(values => { - values.forEach((v, index) => { + let hasError = false; + values.forEach((v: any, index: number) => { + if (v?.hasError) { + hasError = true; + } checkResult[keys[index]] = v; }); - resolve({ object: checkResult }); + resolve({ hasError, object: checkResult }); }); } diff --git a/src/Schema.ts b/src/Schema.ts index 597792c..86d21eb 100644 --- a/src/Schema.ts +++ b/src/Schema.ts @@ -1,5 +1,20 @@ import { SchemaDeclaration, SchemaCheckResult, CheckResult, PlainObject } from './types'; import { MixedType } from './MixedType'; +import get from './utils/get'; + +interface CheckOptions { + /** + * Check for nested object + */ + nestedObject?: boolean; +} + +/** + * Get the field value from the data object + */ +function getFieldValue(data: PlainObject, fieldName: string, nestedObject?: boolean) { + return nestedObject ? get(data, fieldName) : data?.[fieldName]; +} export class Schema { readonly spec: SchemaDeclaration; @@ -9,7 +24,13 @@ export class Schema { this.spec = schema; } - getFieldType(fieldName: T) { + getFieldType(fieldName: T, nestedObject?: boolean) { + if (nestedObject) { + const namePath = (fieldName as string).split('.').join('.objectTypeSchemaSpec.'); + + return get(this.spec, namePath); + } + return this.spec?.[fieldName]; } @@ -29,34 +50,44 @@ export class Schema { this.data = data; } - checkForField(fieldName: T, data: DataType) { + checkForField( + fieldName: T, + data: DataType, + options: CheckOptions = {} + ): CheckResult { this.setSchemaOptionsForAllType(data); - const fieldChecker = this.spec[fieldName]; + const { nestedObject } = options; + const fieldChecker = this.getFieldType(fieldName, nestedObject); + if (!fieldChecker) { // fieldValue can be anything if no schema defined return { hasError: false }; } - return fieldChecker.check((data[fieldName] as unknown) as never, data, fieldName as string); + const fieldValue = getFieldValue(data, fieldName as string, nestedObject); + + return fieldChecker.check(fieldValue, data, fieldName as string); } checkForFieldAsync( fieldName: T, - data: DataType + data: DataType, + options: CheckOptions = {} ): Promise> { this.setSchemaOptionsForAllType(data); - const fieldChecker = this.spec[fieldName]; + const { nestedObject } = options; + const fieldChecker = this.getFieldType(fieldName, nestedObject); + if (!fieldChecker) { // fieldValue can be anything if no schema defined return Promise.resolve({ hasError: false }); } - return fieldChecker.checkAsync( - (data[fieldName] as unknown) as never, - data, - fieldName as string - ); + + const fieldValue = getFieldValue(data, fieldName as string, nestedObject); + + return fieldChecker.checkAsync(fieldValue, data, fieldName as string); } check(data: DataType) { diff --git a/src/types.ts b/src/types.ts index 9429313..5a8a735 100644 --- a/src/types.ts +++ b/src/types.ts @@ -19,13 +19,13 @@ export type ErrorMessageType = string; export type ValidCallbackType = ( value: V, data?: D, - filedName?: string | string[] + fieldName?: string | string[] ) => CheckResult | boolean; export type AsyncValidCallbackType = ( value: V, data?: D, - filedName?: string | string[] + fieldName?: string | string[] ) => CheckResult | boolean | Promise>; export type PlainObject = any> = { diff --git a/src/utils/get.ts b/src/utils/get.ts new file mode 100644 index 0000000..1014fca --- /dev/null +++ b/src/utils/get.ts @@ -0,0 +1,21 @@ +type Key = string | number | symbol; +type Path = Array | string; + +export default function get(object: any, path: Path, defaultValue?: any): any { + if (!object) { + return defaultValue; + } + + const keys = Array.isArray(path) ? path : path.split('.'); + let result = object; + + for (const key of keys) { + if (result && typeof result === 'object') { + result = result[key]; + } else { + return defaultValue; + } + } + + return result !== undefined ? result : defaultValue; +} diff --git a/src/utils/index.ts b/src/utils/index.ts index c9393e6..0247ee4 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -4,3 +4,4 @@ export { default as createValidator } from './createValidator'; export { default as createValidatorAsync } from './createValidatorAsync'; export { default as isEmpty } from './isEmpty'; export { default as formatErrorMessage } from './formatErrorMessage'; +export { default as get } from './get'; diff --git a/test/MixedTypeSpec.js b/test/MixedTypeSpec.js index 2a0d33c..84fd684 100644 --- a/test/MixedTypeSpec.js +++ b/test/MixedTypeSpec.js @@ -353,36 +353,36 @@ describe('#MixedType', () => { it('Should type be changed by condition', () => { const model = SchemaModel({ - filed1: NumberType().min(10), - filed2: MixedType().when(schema => { - const checkResult = schema.filed1.check(); + field1: NumberType().min(10), + field2: MixedType().when(schema => { + const checkResult = schema.field1.check(); return checkResult.hasError ? NumberType().min(10, 'error1') : NumberType().min(2, 'error2'); }) }); - const checkResult1 = model.check({ filed1: 20, filed2: 2 }); + const checkResult1 = model.check({ field1: 20, field2: 2 }); - checkResult1.filed1.hasError.should.equal(false); - checkResult1.filed2.hasError.should.equal(false); + checkResult1.field1.hasError.should.equal(false); + checkResult1.field2.hasError.should.equal(false); - const checkResult2 = model.check({ filed1: 1, filed2: 1 }); + const checkResult2 = model.check({ field1: 1, field2: 1 }); - checkResult2.filed1.hasError.should.equal(true); - checkResult2.filed2.hasError.should.equal(true); - checkResult2.filed2.errorMessage.should.equal('error1'); + checkResult2.field1.hasError.should.equal(true); + checkResult2.field2.hasError.should.equal(true); + checkResult2.field2.errorMessage.should.equal('error1'); - const checkResult3 = model.check({ filed1: 10, filed2: 1 }); + const checkResult3 = model.check({ field1: 10, field2: 1 }); - checkResult3.filed1.hasError.should.equal(false); - checkResult3.filed2.hasError.should.equal(true); - checkResult3.filed2.errorMessage.should.equal('error2'); + checkResult3.field1.hasError.should.equal(false); + checkResult3.field2.hasError.should.equal(true); + checkResult3.field2.errorMessage.should.equal('error2'); - const checkResult4 = model.checkForField('filed2', { filed1: 20, filed2: 1 }); + const checkResult4 = model.checkForField('field2', { field1: 20, field2: 1 }); checkResult4.errorMessage.should.equal('error2'); - const checkResult5 = model.checkForField('filed2', { filed1: 9, filed2: 1 }); + const checkResult5 = model.checkForField('field2', { field1: 9, field2: 1 }); checkResult5.errorMessage.should.equal('error1'); }); diff --git a/test/ObjectTypeSpec.js b/test/ObjectTypeSpec.js index dc029ea..bfc3eb0 100644 --- a/test/ObjectTypeSpec.js +++ b/test/ObjectTypeSpec.js @@ -1,57 +1,75 @@ +import { expect } from 'chai'; import { flaser } from 'object-flaser'; +import * as schema from '../src'; -/* eslint-disable @typescript-eslint/no-var-requires */ -require('chai').should(); - -const schema = require('../src'); const { ObjectType, StringType, NumberType, Schema } = schema; describe('#ObjectType', () => { it('Should be a valid object', () => { - let schemaData = { - url: StringType().isURL('应该是一个 url'), + const schemaData = { + url: StringType().isURL('Should be a url'), user: ObjectType().shape({ - email: StringType().isEmail('应该是一个 email'), - age: NumberType().min(18, '年龄应该大于18岁') + email: StringType().isEmail('Should be an email'), + age: NumberType().min(18, 'Age should be greater than 18') }) }; - let schema = new Schema(schemaData); + const schema = new Schema(schemaData); + + const checkResult = schema.checkForField('user', { + user: { email: 'simon.guo@hypers.com', age: 19 } + }); + + expect(checkResult).to.deep.equal({ + hasError: false, + object: { + email: { hasError: false }, + age: { hasError: false } + } + }); - schema - .checkForField('user', { user: { email: 'simon.guo@hypers.com', age: 19 } }) - .object.email.hasError.should.equal(false); - schema - .checkForField('user', { user: { email: 'simon.guo', age: 19 } }) - .object.email.hasError.should.equal(true); + const checkResult2 = schema.checkForField('user', { user: { email: 'simon.guo', age: 19 } }); + + expect(checkResult2).to.deep.equal({ + hasError: true, + object: { + email: { hasError: true, errorMessage: 'Should be an email' }, + age: { hasError: false } + } + }); - let checkStatus = schema.checkForField('user', { + const checkResult3 = schema.checkForField('user', { user: { email: 'simon.guo@hypers.com', age: 17 } }); - checkStatus.object.age.hasError.should.equal(true); - checkStatus.object.age.errorMessage.should.equal('年龄应该大于18岁'); + expect(checkResult3).to.deep.equal({ + hasError: true, + object: { + email: { hasError: false }, + age: { hasError: true, errorMessage: 'Age should be greater than 18' } + } + }); }); it('Should be checked for object nesting.', () => { const schemaData = { - url: StringType().isURL('应该是一个 url'), + url: StringType().isURL('Should be a url'), user: ObjectType().shape({ - email: StringType().isEmail('应该是一个 email'), - age: NumberType().min(18, '年龄应该大于18岁'), + email: StringType().isEmail('Should be an email'), + age: NumberType().min(18, 'Age should be greater than 18'), parent: ObjectType().shape({ - email: StringType().isEmail('应该是一个邮箱'), - age: NumberType().min(50, '年龄应该大于50岁') + email: StringType().isEmail('Should be an email'), + age: NumberType().min(50, 'Age should be greater than 50') }) }) }; const schema = new Schema(schemaData); - const checkStatus = schema.checkForField('user', { + const checkResult = schema.checkForField('user', { user: { email: 'simon.guo@hypers.com', age: 17, @@ -59,20 +77,22 @@ describe('#ObjectType', () => { } }); - checkStatus.hasError.should.equal(true); - checkStatus.object.email.hasError.should.equal(false); - checkStatus.object.age.hasError.should.equal(true); - checkStatus.object.age.errorMessage.should.equal('年龄应该大于18岁'); - checkStatus.object.parent.hasError.should.equal(true); - - const parentCheckStatus = checkStatus.object.parent.object; - - parentCheckStatus.email.hasError.should.equal(true); - parentCheckStatus.email.errorMessage.should.equal('应该是一个邮箱'); - parentCheckStatus.age.hasError.should.equal(true); - parentCheckStatus.age.errorMessage.should.equal('年龄应该大于50岁'); + expect(checkResult).to.deep.equal({ + hasError: true, + object: { + email: { hasError: false }, + age: { hasError: true, errorMessage: 'Age should be greater than 18' }, + parent: { + hasError: true, + object: { + email: { hasError: true, errorMessage: 'Should be an email' }, + age: { hasError: true, errorMessage: 'Age should be greater than 50' } + } + } + } + }); - const checkStatus2 = schema.checkForField('user', { + const checkResult2 = schema.checkForField('user', { user: { email: 'simon.guo@hypers.com', age: 18, @@ -80,19 +100,26 @@ describe('#ObjectType', () => { } }); - checkStatus2.hasError.should.equal(false); - checkStatus2.object.age.hasError.should.equal(false); - checkStatus2.object.age.hasError.should.equal(false); - checkStatus2.object.parent.hasError.should.equal(false); - const parentCheckStatus2 = checkStatus2.object.parent.object; - parentCheckStatus2.email.hasError.should.equal(false); - parentCheckStatus2.age.hasError.should.equal(false); + expect(checkResult2).to.deep.equal({ + hasError: false, + object: { + email: { hasError: false }, + age: { hasError: false }, + parent: { + hasError: false, + object: { + email: { hasError: false }, + age: { hasError: false } + } + } + } + }); }); it('Should be a valid object by flaser', () => { const schemaData = { - 'data.email': StringType().isEmail('error1'), - 'data.age': NumberType().min(18, 'error1') + 'data.email': StringType().isEmail('Should be an email'), + 'data.age': NumberType().min(18, 'Should be greater than 18') }; const data = { @@ -100,37 +127,175 @@ describe('#ObjectType', () => { }; const schema = new Schema(schemaData); - const checkStatus = schema.check(flaser(data)); + const checkResult = schema.check(flaser(data)); - checkStatus['data.email'].hasError.should.equal(false); - checkStatus['data.age'].hasError.should.equal(true); + expect(checkResult).to.deep.equal({ + 'data.email': { hasError: false }, + 'data.age': { hasError: true, errorMessage: 'Should be greater than 18' } + }); }); - it('Should call async check', done => { + it('Should aync check for object nesting', async () => { const schema = new Schema({ - url: StringType().isURL('error1'), + url: StringType().isURL('Should be a url'), user: ObjectType().shape({ email: StringType().addRule(() => { return new Promise(resolve => { - setTimeout(() => { - resolve(false); - }, 1000); + setTimeout(() => resolve(false), 400); }); - }, 'error1'), - age: NumberType().min(18, 'error2') + }, 'Should be an email'), + age: NumberType().min(18, 'Should be greater than 18') }) }); - schema.checkAsync({ url: 'url', user: { email: 'a', age: '10' } }).then(status => { - const user = status.user.object; - if ( - user.age.hasError && - user.age.errorMessage === 'error2' && - user.email.hasError && - user.email.errorMessage === 'error1' - ) { - done(); + const result = await schema.checkAsync({ url: 'url', user: { email: 'a', age: '10' } }); + + expect(result).to.deep.equal({ + url: { hasError: true, errorMessage: 'Should be a url' }, + user: { + hasError: true, + object: { + email: { hasError: true, errorMessage: 'Should be an email' }, + age: { hasError: true, errorMessage: 'Should be greater than 18' } + } } }); }); + + it('Should be checked for object nesting with nestedObject option.', () => { + const schemaData = { + url: StringType().isURL('Should be a url'), + user: ObjectType().shape({ + email: StringType().isEmail('Should be an email'), + age: NumberType().min(18, 'Age should be greater than 18'), + parent: ObjectType().shape({ + email: StringType().isEmail('Should be an email').isRequired('Email is required'), + age: NumberType().min(50, 'Age should be greater than 50') + }) + }) + }; + + const schema = new Schema(schemaData); + const options = { nestedObject: true }; + + const checkResult = schema.checkForField( + 'user.parent.age', + { user: { parent: { age: 40 } } }, + options + ); + + expect(checkResult).to.deep.equal({ + hasError: true, + errorMessage: 'Age should be greater than 50' + }); + + const checkResult2 = schema.checkForField( + 'user.parent.age', + { user: { parent: { age: 60 } } }, + options + ); + + expect(checkResult2).to.deep.equal({ hasError: false }); + + const checkResult3 = schema.checkForField( + 'user.parent.email', + { user: { parent: { age: 60 } } }, + options + ); + + expect(checkResult3).to.deep.equal({ hasError: true, errorMessage: 'Email is required' }); + }); + + it('Should aync check for object nesting', async () => { + const schema = new Schema({ + url: StringType().isURL('Should be a url'), + user: ObjectType().shape({ + email: StringType().isEmail('Should be an email'), + age: NumberType().min(18, 'Should be greater than 18'), + parent: ObjectType().shape({ + email: StringType().addRule(value => { + return new Promise(resolve => { + setTimeout(() => { + if (/@/.test(value)) { + resolve(true); + } + resolve(false); + }, 400); + }); + }, 'Should be an email'), + age: NumberType().min(50, 'Age should be greater than 50') + }) + }) + }); + + const options = { nestedObject: true }; + + const result = await schema.checkForFieldAsync( + 'user.parent.email', + { user: { parent: { email: 'a' } } }, + options + ); + + expect(result).to.deep.equal({ hasError: true, errorMessage: 'Should be an email' }); + + const result2 = await schema.checkForFieldAsync( + 'user.parent.email', + { user: { parent: { email: 'a@a.com' } } }, + options + ); + + expect(result2).to.deep.equal({ hasError: false }); + }); + + it('Should not allow empty object', () => { + const schema = new Schema({ + user: ObjectType().isRequired('User is required') + }); + + const result = schema.check({ user: null }); + expect(result).to.deep.equal({ user: { hasError: true, errorMessage: 'User is required' } }); + + const result2 = schema.check({ user: undefined }); + expect(result2).to.deep.equal({ user: { hasError: true, errorMessage: 'User is required' } }); + + const result3 = schema.check({ user: false }); + expect(result3).to.deep.equal({ + user: { hasError: true, errorMessage: 'user must be an object' } + }); + }); + + it('Should not allow empty object by async', async () => { + const schema = new Schema({ + user: ObjectType().isRequired('User is required') + }); + + const result = await schema.checkAsync({ user: null }); + expect(result).to.deep.equal({ user: { hasError: true, errorMessage: 'User is required' } }); + + const result2 = await schema.checkAsync({ user: undefined }); + expect(result2).to.deep.equal({ user: { hasError: true, errorMessage: 'User is required' } }); + + const result3 = await schema.checkAsync({ user: false }); + expect(result3).to.deep.equal({ + user: { hasError: true, errorMessage: 'user must be an object' } + }); + }); + + it('Should allow empty object', () => { + const schema = new Schema({ + user: ObjectType() + }); + + const result = schema.check({ user: null }); + expect(result).to.deep.equal({ user: { hasError: false } }); + }); + + it('Should allow empty object by async', async () => { + const schema = new Schema({ + user: ObjectType() + }); + + const result = await schema.checkAsync({ user: null }); + expect(result).to.deep.equal({ user: { hasError: false } }); + }); }); diff --git a/test/utilsSpec.js b/test/utilsSpec.js index c2b987b..ea09a5b 100644 --- a/test/utilsSpec.js +++ b/test/utilsSpec.js @@ -1,6 +1,7 @@ /* eslint-disable @typescript-eslint/no-var-requires */ require('chai').should(); -const { formatErrorMessage, checkRequired } = require('../src/utils'); +const { expect } = require('chai'); +const { formatErrorMessage, checkRequired, get } = require('../src/utils'); describe('#utils', () => { describe('## formatErrorMessage', () => { @@ -61,4 +62,37 @@ describe('#utils', () => { checkRequired(['']).should.equal(true); }); }); + + describe('## get', () => { + it('Should get the value of the object', () => { + const obj = { a: { b: { c: 1 } } }; + get(obj, 'a.b.c').should.equal(1); + get(obj, 'a.b').should.deep.equal({ c: 1 }); + get(obj, 'a').should.deep.equal({ b: { c: 1 } }); + + expect(get(obj, 'a.b.d')).to.be.undefined; + expect(get(obj, 'a.b.d.e')).to.be.undefined; + expect(get(obj, 'a.b.d.e.f')).to.be.undefined; + }); + + it('Should get the value of the array', () => { + const obj = { a: [{ b: 1 }, { b: 2 }] }; + get(obj, 'a.0.b').should.equal(1); + get(obj, 'a.1.b').should.equal(2); + expect(get(obj, 'a.2.b')).to.be.undefined; + }); + + it('Should get the value of the array and object', () => { + const obj = { a: [{ b: { c: 1 } }, { b: { c: 2 } }] }; + get(obj, 'a.0.b.c').should.equal(1); + get(obj, 'a.1.b.c').should.equal(2); + expect(get(obj, 'a.2.b.c')).to.be.undefined; + }); + + it('Should return the default value', () => { + const obj = { a: { b: [{ c: 1 }, { c: 2 }] } }; + expect(get(obj, 'a.b.2.c', 10)).to.equal(10); + expect(get(undefined, 'a.b', 10)).to.equal(10); + }); + }); }); diff --git a/tsconfig-es.json b/tsconfig-es.json index 9b1f01a..f052891 100644 --- a/tsconfig-es.json +++ b/tsconfig-es.json @@ -10,7 +10,6 @@ "sourceMap": true, "moduleResolution": "node", "target": "ES2019" - }, "include": ["./src/**/*.ts"] }