Skip to content

Commit

Permalink
Require Node.js 14 and TypeScript 4.7 (#238)
Browse files Browse the repository at this point in the history
  • Loading branch information
sindresorhus committed Jun 13, 2022
1 parent 8b6a208 commit 391fc91
Show file tree
Hide file tree
Showing 49 changed files with 133 additions and 136 deletions.
7 changes: 4 additions & 3 deletions .github/workflows/main.yml
Expand Up @@ -10,16 +10,17 @@ jobs:
fail-fast: false
matrix:
node-version:
- 18
- 16
- 14
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
- run: npm install --force
- run: npm test
- uses: codecov/codecov-action@v2
- uses: codecov/codecov-action@v3
if: matrix.node-version == 16
with:
fail_ci_if_error: true
11 changes: 6 additions & 5 deletions dev-only.js
@@ -1,12 +1,13 @@
'use strict';

let ow;
if (process.env.NODE_ENV === 'production') {
const shim = new Proxy((() => {}), {
get: () => shim,
apply: () => shim
apply: () => shim,
});

module.exports = shim;
ow = shim;
} else {
module.exports = require('./dist');
ow = await import('./dist/index.js');
}

export default ow;
65 changes: 32 additions & 33 deletions package.json
Expand Up @@ -4,18 +4,25 @@
"description": "Function argument validation for humans",
"license": "MIT",
"repository": "sindresorhus/ow",
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
},
"funding": "https://github.com/sponsors/sindresorhus",
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "https://sindresorhus.com"
},
"type": "module",
"main": "dist/index.js",
"exports": {
".": {
"types": "./dist/index.d.ts",
"node": "./dist/index.js"
},
"./dev-only": {
"types": "./dist/index.d.ts",
"node": "./dev-only.js"
}
},
"engines": {
"node": ">=12"
"node": ">=14.16"
},
"scripts": {
"test": "xo && c8 ava",
Expand Down Expand Up @@ -50,37 +57,33 @@
"object"
],
"dependencies": {
"@sindresorhus/is": "^4.2.0",
"callsites": "^3.1.0",
"dot-prop": "^6.0.1",
"@sindresorhus/is": "^5.1.0",
"callsites": "^4.0.0",
"dot-prop": "^7.2.0",
"lodash.isequal": "^4.5.0",
"type-fest": "^2.3.4",
"type-fest": "^2.13.0",
"vali-date": "^1.0.0"
},
"devDependencies": {
"@sindresorhus/tsconfig": "^0.8.0",
"@types/lodash.isequal": "^4.5.5",
"@types/node": "^16.10.2",
"@sindresorhus/tsconfig": "^3.0.1",
"@types/lodash.isequal": "^4.5.6",
"@types/node": "^17.0.42",
"@types/vali-date": "^1.0.0",
"ava": "^3.15.0",
"c8": "^7.10.0",
"del-cli": "^4.0.0",
"expect-type": "^0.12.0",
"gh-pages": "^3.2.3",
"ts-node": "^10.4.0",
"typedoc": "^0.22.5",
"typescript": "^4.5.0-beta",
"xo": "^0.46.4"
"ava": "^4.3.0",
"c8": "^7.11.3",
"del-cli": "^4.0.1",
"expect-type": "^0.13.0",
"gh-pages": "^4.0.0",
"ts-node": "^10.8.1",
"typedoc": "^0.22.17",
"typescript": "^4.7.3",
"xo": "^0.50.0"
},
"browser": {
"./dist/utils/infer-label.js": "./dist/utils/infer-label.browser.js"
},
"types": "dist",
"sideEffects": false,
"xo": {
"parserOptions": {
"project": "./tsconfig.xo.json"
},
"ignores": [
"example.js",
"dev-only.js",
Expand All @@ -98,20 +101,16 @@
}
},
"ava": {
"nonSemVerExperiments": {
"configurableModuleFormat": true
},
"nodeArguments": [
"--loader=ts-node/esm",
"--experimental-specifier-resolution=node"
],
"files": [
"test/**",
"!test/fixtures/**"
],
"extensions": {
"ts": "module"
}
},
"nodeArguments": [
"--loader=ts-node/esm"
]
},
"c8": {
"reporter": [
Expand Down
13 changes: 8 additions & 5 deletions readme.md
Expand Up @@ -20,14 +20,12 @@

## Install

```
$ npm install ow
```sh
npm install ow
```

## Usage

*If you use CommonJS, you need to import is as `const {default: ow} = require('ow')`.*

```ts
import ow from 'ow';

Expand Down Expand Up @@ -65,7 +63,7 @@ ow(unicorn, ow.object.exactShape({
//=> ArgumentError: Expected property `stars.value` to be of type `number` but received type `string` in object `unicorn`
```

***Note:*** If you intend on using `ow` for development purposes only, use `require('ow/dev-only')` instead of the usual `import 'ow'`, and run the bundler with `NODE_ENV` set to `production` (e.g. `$ NODE_ENV="production" parcel build index.js`). This will make `ow` automatically export a shim when running in production, which should result in a significantly lower bundle size.
***Note:*** If you intend on using `ow` for development purposes only, use `import ow from 'ow/dev-only'` instead of the usual `import ow from 'ow'`, and run the bundler with `NODE_ENV` set to `production` (e.g. `$ NODE_ENV="production" parcel build index.js`). This will make `ow` automatically export a shim when running in production, which should result in a significantly lower bundle size.

## API

Expand Down Expand Up @@ -291,6 +289,8 @@ This can be useful for creating your own reusable validators which can be extrac

### TypeScript

**Requires TypeScript 4.7 or later.**

Ow includes a type utility that lets you to extract a TypeScript type from the given predicate.

```ts
Expand All @@ -306,6 +306,9 @@ type User = Infer<typeof userPredicate>;
## Maintainers

- [Sindre Sorhus](https://github.com/sindresorhus)

**Former:**

- [Sam Verschueren](https://github.com/SamVerschueren)

## Related
Expand Down
9 changes: 5 additions & 4 deletions source/index.ts
@@ -1,6 +1,5 @@
import callsites from 'callsites';
import {inferLabel} from './utils/infer-label.js';
import {Predicate} from './predicates/predicate.js';
import {BasePredicate, isPredicate} from './predicates/base-predicate.js';
import modifiers, {Modifiers} from './modifiers.js';
import predicates, {Predicates} from './predicates.js';
Expand Down Expand Up @@ -72,7 +71,7 @@ export interface ReusableValidator<T> {
@param value - Value to test.
@param label - Override the label which should be used in error messages.
*/
// eslint-disable-next-line @typescript-eslint/prefer-function-type
// eslint-disable-next-line @typescript-eslint/prefer-function-type, @typescript-eslint/no-redundant-type-constituents
(value: unknown | T, label?: string): void;
}

Expand Down Expand Up @@ -117,7 +116,7 @@ const ow = <T>(value: unknown, labelOrPredicate: unknown, predicate?: BasePredic

Object.defineProperties(ow, {
isValid: {
value: <T>(value: unknown, predicate: BasePredicate<T>): boolean => {
value<T>(value: unknown, predicate: BasePredicate<T>): boolean {
try {
test(value, '', predicate);
return true;
Expand Down Expand Up @@ -148,6 +147,8 @@ const _ow: Ow = predicates(modifiers(ow)) as Ow;

export default _ow;

export {BasePredicate, Predicate};
export * from './predicates.js';
export {ArgumentError} from './argument-error.js';

export {Predicate} from './predicates/predicate.js';
export type {BasePredicate} from './predicates/base-predicate.js';
38 changes: 18 additions & 20 deletions source/predicates.ts
Expand Up @@ -6,7 +6,7 @@ import {BigIntPredicate} from './predicates/bigint.js';
import {BooleanPredicate} from './predicates/boolean.js';
import {Predicate, PredicateOptions} from './predicates/predicate.js';
import {ArrayPredicate} from './predicates/array.js';
import {ObjectPredicate, Shape} from './predicates/object.js';
import {ObjectPredicate} from './predicates/object.js';
import {DatePredicate} from './predicates/date.js';
import {ErrorPredicate} from './predicates/error.js';
import {MapPredicate} from './predicates/map.js';
Expand Down Expand Up @@ -328,22 +328,20 @@ const predicates = <T>(object: T, options?: PredicateOptions): T & Predicates =>

export default predicates;

export {
StringPredicate,
NumberPredicate,
BigIntPredicate,
BooleanPredicate,
ArrayPredicate,
ObjectPredicate,
DatePredicate,
ErrorPredicate,
MapPredicate,
WeakMapPredicate,
SetPredicate,
WeakSetPredicate,
TypedArrayPredicate,
ArrayBufferPredicate,
DataViewPredicate,
AnyPredicate,
Shape,
};
export {ObjectPredicate} from './predicates/object.js';
export type {Shape} from './predicates/object.js';
export {StringPredicate} from './predicates/string.js';
export {NumberPredicate} from './predicates/number.js';
export {BigIntPredicate} from './predicates/bigint.js';
export {BooleanPredicate} from './predicates/boolean.js';
export {ArrayPredicate} from './predicates/array.js';
export {DatePredicate} from './predicates/date.js';
export {ErrorPredicate} from './predicates/error.js';
export {MapPredicate} from './predicates/map.js';
export {WeakMapPredicate} from './predicates/weak-map.js';
export {SetPredicate} from './predicates/set.js';
export {WeakSetPredicate} from './predicates/weak-set.js';
export {TypedArrayPredicate} from './predicates/typed-array.js';
export {ArrayBufferPredicate} from './predicates/array-buffer.js';
export {DataViewPredicate} from './predicates/data-view.js';
export {AnyPredicate} from './predicates/any.js';
2 changes: 1 addition & 1 deletion source/predicates/error.ts
Expand Up @@ -25,7 +25,7 @@ export class ErrorPredicate extends Predicate<Error> {
@param expected - Expected message of the Error.
*/
message(expected: string): this {
override message(expected: string): this {
return this.addValidator({
message: (error, label) => `Expected ${label} message to be \`${expected}\`, got \`${error.message}\``,
validator: error => error.message === expected,
Expand Down
2 changes: 1 addition & 1 deletion source/predicates/map.ts
Expand Up @@ -93,7 +93,7 @@ export class MapPredicate<T1 = unknown, T2 = unknown> extends Predicate<Map<T1,
hasAnyValues(...values: readonly T2[]): this {
return this.addValidator({
message: (_, label) => `Expected ${label} to have any value of \`${JSON.stringify(values)}\``,
validator: map => {
validator(map) {
const valueSet = new Set(map.values());
return values.some(key => valueSet.has(key));
},
Expand Down
2 changes: 1 addition & 1 deletion source/predicates/number.ts
Expand Up @@ -89,7 +89,7 @@ export class NumberPredicate extends Predicate<number> {
*/
oneOf(list: readonly number[]): this {
return this.addValidator({
message: (value, label) => {
message(value, label) {
let printedList = JSON.stringify(list);

if (list.length > 10) {
Expand Down
13 changes: 6 additions & 7 deletions source/predicates/object.ts
@@ -1,6 +1,5 @@
import is from '@sindresorhus/is';

import dotProp from 'dot-prop';
import {hasProperty} from 'dot-prop';
import isEqual from 'lodash.isequal';
import hasItems from '../utils/has-items.js';
import ofType from '../utils/of-type.js';
Expand All @@ -9,8 +8,6 @@ import {partial, exact, Shape, TypeOfShape} from '../utils/match-shape.js';
import {Predicate, PredicateOptions} from './predicate.js';
import {BasePredicate} from './base-predicate.js';

export {Shape};

export class ObjectPredicate<T extends object = object> extends Predicate<T> {
/**
@hidden
Expand Down Expand Up @@ -92,7 +89,7 @@ export class ObjectPredicate<T extends object = object> extends Predicate<T> {
*/
instanceOf(instance: Function): this {
return this.addValidator({
message: (object: object, label: string) => {
message(object: object, label: string) {
let {name} = object?.constructor ?? {};

if (!name || name === 'Object') {
Expand All @@ -115,7 +112,7 @@ export class ObjectPredicate<T extends object = object> extends Predicate<T> {
message: (_, label, missingKeys) => `Expected ${label} to have keys \`${JSON.stringify(missingKeys)}\``,
validator: object => hasItems(
{
has: item => dotProp.has(object, item),
has: item => hasProperty(object, item),
},
keys,
),
Expand All @@ -130,7 +127,7 @@ export class ObjectPredicate<T extends object = object> extends Predicate<T> {
hasAnyKeys(...keys: readonly string[]): this {
return this.addValidator({
message: (_, label) => `Expected ${label} to have any key of \`${JSON.stringify(keys)}\``,
validator: object => keys.some(key => dotProp.has(object, key)),
validator: object => keys.some(key => hasProperty(object, key)),
});
}

Expand Down Expand Up @@ -191,3 +188,5 @@ export class ObjectPredicate<T extends object = object> extends Predicate<T> {
}) as ObjectPredicate<any>;
}
}

export type {Shape} from '../utils/match-shape.js';
2 changes: 1 addition & 1 deletion source/predicates/predicate.ts
Expand Up @@ -179,7 +179,7 @@ export class Predicate<T = unknown> implements BasePredicate<T> {
? `(${label}) ${error}`
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
: error(label),
validator: value => {
validator(value) {
const {message, validator} = customValidator(value);

if (validator) {
Expand Down
4 changes: 2 additions & 2 deletions source/predicates/string.ts
Expand Up @@ -103,7 +103,7 @@ export class StringPredicate extends Predicate<string> {
*/
oneOf(list: readonly string[]): this {
return this.addValidator({
message: (value, label) => {
message(value, label) {
let printedList = JSON.stringify(list);

if (list.length > 10) {
Expand Down Expand Up @@ -132,7 +132,7 @@ export class StringPredicate extends Predicate<string> {
*/
get nonBlank(): this {
return this.addValidator({
message: (value, label) => {
message(value, label) {
// Unicode's formal substitute characters can be barely legible and may not be easily recognized.
// Hence this alternative substitution scheme.
const madeVisible = value
Expand Down
5 changes: 2 additions & 3 deletions source/utils/infer-label.ts
Expand Up @@ -51,14 +51,13 @@ export const inferLabel = (callsites: readonly CallSite[]): void | string => {
line = line.slice(columnNumber - 1);

const match = labelRegex.exec(line);
const token = match?.groups?.['label'];

if (!match?.groups?.label) {
if (!token) {
// Exit if we didn't find a label
return;
}

const token = match.groups.label;

if (isValidIdentifier(token) || isValidIdentifier(token.split('.').pop())) {
return token;
}
Expand Down

0 comments on commit 391fc91

Please sign in to comment.