diff --git a/.gitignore b/.gitignore index 8fb947a..eb99a21 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ node_modules yarn.lock -dist +/distribution .tsimp diff --git a/package.json b/package.json index 0cbbf4a..7f01400 100644 --- a/package.json +++ b/package.json @@ -11,19 +11,21 @@ "url": "https://sindresorhus.com" }, "type": "module", - "exports": "./dist/index.js", - "types": "./dist/index.d.ts", + "exports": { + "types": "./distribution/index.d.ts", + "default": "./distribution/index.js" + }, "sideEffects": false, "engines": { - "node": ">=16" + "node": ">=18" }, "scripts": { - "build": "del dist && tsc", + "build": "del distribution && tsc", "test": "tsc --noEmit && xo && ava", "prepare": "npm run build" }, "files": [ - "dist" + "distribution" ], "keywords": [ "type", @@ -50,19 +52,19 @@ "types" ], "devDependencies": { - "@sindresorhus/tsconfig": "^5.0.0", + "@sindresorhus/tsconfig": "^6.0.0", "@types/jsdom": "^21.1.7", - "@types/node": "^20.14.8", - "@types/zen-observable": "^0.8.3", + "@types/node": "^20.14.10", + "@types/zen-observable": "^0.8.7", "ava": "^6.1.3", - "del-cli": "^5.0.0", - "expect-type": "^0.16.0", - "jsdom": "^22.1.0", + "del-cli": "^5.1.0", + "expect-type": "^0.19.0", + "jsdom": "^24.1.0", "rxjs": "^7.8.1", "tempy": "^3.1.0", "tsimp": "^2.0.11", - "typescript": "^5.1.6", - "xo": "^0.56.0", + "typescript": "^5.5.3", + "xo": "^0.58.0", "zen-observable": "^0.10.0" }, "ava": { diff --git a/readme.md b/readme.md index 7416c87..1966a5b 100644 --- a/readme.md +++ b/readme.md @@ -133,6 +133,10 @@ is.array(value, is.number); // Validate `value` is an array and all of its items ##### .function(value) ##### .buffer(value) + +> [!NOTE] +> [Prefer using `Uint8Array` instead of `Buffer`.](https://sindresorhus.com/blog/goodbye-nodejs-buffer) + ##### .blob(value) ##### .object(value) diff --git a/source/index.ts b/source/index.ts index cd7deaf..9fd1923 100644 --- a/source/index.ts +++ b/source/index.ts @@ -1,4 +1,3 @@ -import type {Buffer} from 'node:buffer'; import type { ArrayLike, Class, @@ -13,6 +12,14 @@ import type { Whitespace, } from './types.js'; +// From type-fest. +type ExtractFromGlobalConstructors = + Name extends string + ? typeof globalThis extends Record infer T> ? T : never + : never; + +type NodeBuffer = ExtractFromGlobalConstructors<'Buffer'>; + const typedArrayTypeNames = [ 'Int8Array', 'Uint8Array', @@ -314,7 +321,7 @@ const is = Object.assign( }, ); -function isAbsoluteMod2(remainder: 0 | 1) { +function isAbsoluteModule2(remainder: 0 | 1) { return (value: unknown): value is number => isInteger(value) && Math.abs(value % 2) === remainder; } @@ -350,7 +357,7 @@ export function isArrayLike(value: unknown): value is ArrayLike return !isNullOrUndefined(value) && !isFunction(value) && isValidLength((value as ArrayLike).length); } -export function isAsyncFunction(value: unknown): value is ((...args: any[]) => Promise) { +export function isAsyncFunction(value: unknown): value is ((...arguments_: any[]) => Promise) { return getObjectType(value) === 'AsyncFunction'; } @@ -358,7 +365,7 @@ export function isAsyncGenerator(value: unknown): value is AsyncGenerator { return isAsyncIterable(value) && isFunction((value as AsyncGenerator).next) && isFunction((value as AsyncGenerator).throw); } -export function isAsyncGeneratorFunction(value: unknown): value is ((...args: any[]) => Promise) { +export function isAsyncGeneratorFunction(value: unknown): value is ((...arguments_: any[]) => Promise) { return getObjectType(value) === 'AsyncGeneratorFunction'; } @@ -388,10 +395,13 @@ export function isBoolean(value: unknown): value is boolean { // eslint-disable-next-line @typescript-eslint/ban-types export function isBoundFunction(value: unknown): value is Function { - return isFunction(value) && !Object.prototype.hasOwnProperty.call(value, 'prototype'); + return isFunction(value) && !Object.hasOwn(value, 'prototype'); } -export function isBuffer(value: unknown): value is Buffer { +/** +Note: [Prefer using `Uint8Array` instead of `Buffer`.](https://sindresorhus.com/blog/goodbye-nodejs-buffer) +*/ +export function isBuffer(value: unknown): value is NodeBuffer { // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-call return (value as any)?.constructor?.isBuffer?.(value) ?? false; } @@ -450,7 +460,7 @@ export function isError(value: unknown): value is Error { } export function isEvenInteger(value: unknown): value is number { - return isAbsoluteMod2(0)(value); + return isAbsoluteModule2(0)(value); } // Example: `is.falsy = (value: unknown): value is (not true | 0 | '' | undefined | null) => Boolean(value);` @@ -629,7 +639,7 @@ export function isObservable(value: unknown): value is ObservableLike { } export function isOddInteger(value: unknown): value is number { - return isAbsoluteMod2(1)(value); + return isAbsoluteModule2(1)(value); } export function isPlainObject(value: unknown): value is Record { @@ -768,7 +778,7 @@ export function isWeakMap(value: u return getObjectType(value) === 'WeakMap'; } -// eslint-disable-next-line @typescript-eslint/ban-types +// eslint-disable-next-line @typescript-eslint/ban-types, unicorn/prevent-abbreviations export function isWeakRef(value: unknown): value is WeakRef { return getObjectType(value) === 'WeakRef'; } @@ -782,7 +792,7 @@ export function isWhitespaceString(value: unknown): value is Whitespace { return isString(value) && /^\s+$/.test(value); } -type ArrayMethod = (fn: (value: unknown, index: number, array: unknown[]) => boolean, thisArg?: unknown) => boolean; +type ArrayMethod = (function_: (value: unknown, index: number, array: unknown[]) => boolean, thisArgument?: unknown) => boolean; function predicateOnArray(method: ArrayMethod, predicate: Predicate, values: unknown[]) { if (!isFunction(predicate)) { @@ -832,7 +842,7 @@ type Assert = { symbol: (value: unknown, message?: string) => asserts value is symbol; numericString: (value: unknown, message?: string) => asserts value is `${number}`; array: (value: unknown, assertion?: (element: unknown) => asserts element is T, message?: string) => asserts value is T[]; - buffer: (value: unknown, message?: string) => asserts value is Buffer; + buffer: (value: unknown, message?: string) => asserts value is NodeBuffer; blob: (value: unknown, message?: string) => asserts value is Blob; // eslint-disable-next-line @typescript-eslint/ban-types nullOrUndefined: (value: unknown, message?: string) => asserts value is null | undefined; @@ -1218,7 +1228,10 @@ export function assertBoundFunction(value: unknown, message?: string): asserts v } } -export function assertBuffer(value: unknown, message?: string): asserts value is Buffer { +/** +Note: [Prefer using `Uint8Array` instead of `Buffer`.](https://sindresorhus.com/blog/goodbye-nodejs-buffer) +*/ +export function assertBuffer(value: unknown, message?: string): asserts value is NodeBuffer { if (!isBuffer(value)) { throw new TypeError(message ?? typeErrorMessage('Buffer', value)); } @@ -1656,7 +1669,7 @@ export function assertWeakMap(valu } } -// eslint-disable-next-line @typescript-eslint/ban-types +// eslint-disable-next-line @typescript-eslint/ban-types, unicorn/prevent-abbreviations export function assertWeakRef(value: unknown, message?: string): asserts value is WeakRef { if (!isWeakRef(value)) { throw new TypeError(message ?? typeErrorMessage('WeakRef', value)); diff --git a/source/types.ts b/source/types.ts index 2340d36..b79a603 100644 --- a/source/types.ts +++ b/source/types.ts @@ -56,7 +56,7 @@ export type ObservableLike = { // eslint-disable-next-line @typescript-eslint/ban-types export type Falsy = false | 0 | 0n | '' | null | undefined; -export type WeakRef = { // eslint-disable-line @typescript-eslint/ban-types +export type WeakRef = { // eslint-disable-line @typescript-eslint/ban-types, unicorn/prevent-abbreviations readonly [Symbol.toStringTag]: 'WeakRef'; deref(): T | undefined; }; diff --git a/test/test.ts b/test/test.ts index 0c9913c..4017cc3 100644 --- a/test/test.ts +++ b/test/test.ts @@ -27,18 +27,18 @@ const {document} = window; const structuredClone = globalThis.structuredClone ?? (x => x); type Test = { - assert: (...args: any[]) => void | never; + assert: (...arguments_: any[]) => void | never; fixtures: unknown[]; typename?: TypeName; typeDescription?: AssertionTypeDescription; is(value: unknown): boolean; }; -const invertAssertThrow = (description: AssertionTypeDescription, fn: () => void | never, value: unknown): void | never => { +const invertAssertThrow = (description: AssertionTypeDescription, function_: () => void | never, value: unknown): void | never => { const expectedAssertErrorMessage = `Expected value which is \`${description}\`, received value of type \`${is(value)}\`.`; try { - fn(); + function_(); } catch (error: unknown) { if (error instanceof TypeError && error.message.includes(expectedAssertErrorMessage)) { return; @@ -488,10 +488,10 @@ const types = new Map([ fixtures: [ {x: 1}, Object.create(null), - new Object(), // eslint-disable-line no-new-object + new Object(), // eslint-disable-line no-object-constructor structuredClone({x: 1}), structuredClone(Object.create(null)), - structuredClone(new Object()), // eslint-disable-line no-new-object + structuredClone(new Object()), // eslint-disable-line no-object-constructor ], typename: 'Object', typeDescription: 'plain object', @@ -1841,14 +1841,14 @@ test('is.nonEmptyStringAndNotWhitespace', t => { test('is.emptyObject', t => { t.true(is.emptyObject({})); - t.true(is.emptyObject(new Object())); // eslint-disable-line no-new-object + t.true(is.emptyObject(new Object())); // eslint-disable-line no-object-constructor t.false(is.emptyObject({unicorn: '🦄'})); t.notThrows(() => { assert.emptyObject({}); }); t.notThrows(() => { - assert.emptyObject(new Object()); // eslint-disable-line no-new-object + assert.emptyObject(new Object()); // eslint-disable-line no-object-constructor }); t.throws(() => { assert.emptyObject({unicorn: '🦄'}); @@ -1860,14 +1860,14 @@ test('is.nonEmptyObject', t => { is.nonEmptyObject(foo); t.false(is.nonEmptyObject({})); - t.false(is.nonEmptyObject(new Object())); // eslint-disable-line no-new-object + t.false(is.nonEmptyObject(new Object())); // eslint-disable-line no-object-constructor t.true(is.nonEmptyObject({unicorn: '🦄'})); t.throws(() => { assert.nonEmptyObject({}); }); t.throws(() => { - assert.nonEmptyObject(new Object()); // eslint-disable-line no-new-object + assert.nonEmptyObject(new Object()); // eslint-disable-line no-object-constructor }); t.notThrows(() => { assert.nonEmptyObject({unicorn: '🦄'}); diff --git a/tsconfig.json b/tsconfig.json index b5ebd0e..0aace6f 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,8 +1,5 @@ { "extends": "@sindresorhus/tsconfig", - "compilerOptions": { - "outDir": "dist", - }, "include": [ "source" ],