Skip to content

Commit

Permalink
typings: add JSDoc for internal/validators
Browse files Browse the repository at this point in the history
PR-URL: #44181
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
  • Loading branch information
anonrig authored and ruyadorno committed Aug 22, 2022
1 parent 19557ad commit 2efce0f
Show file tree
Hide file tree
Showing 2 changed files with 153 additions and 7 deletions.
5 changes: 3 additions & 2 deletions lib/internal/errors.js
Expand Up @@ -392,8 +392,9 @@ function makeNodeErrorWithCode(Base, key) {

/**
* This function removes unnecessary frames from Node.js core errors.
* @template {(...args: any[]) => any} T
* @type {(fn: T) => T}
* @template {(...args: unknown[]) => unknown} T
* @param {T} fn
* @returns {T}
*/
function hideStackFrames(fn) {
// We rename the functions that will be hidden to cut off the stacktrace
Expand Down
155 changes: 150 additions & 5 deletions lib/internal/validators.js
Expand Up @@ -34,10 +34,18 @@ const {
} = require('internal/util/types');
const { signals } = internalBinding('constants').os;

/**
* @param {*} value
* @returns {boolean}
*/
function isInt32(value) {
return value === (value | 0);
}

/**
* @param {*} value
* @returns {boolean}
*/
function isUint32(value) {
return value === (value >>> 0);
}
Expand Down Expand Up @@ -70,6 +78,16 @@ function parseFileMode(value, name, def) {
return value;
}

/**
* @callback validateInteger
* @param {*} value
* @param {string} name
* @param {number} [min]
* @param {number} [max]
* @returns {asserts value is number}
*/

/** @type {validateInteger} */
const validateInteger = hideStackFrames(
(value, name, min = NumberMIN_SAFE_INTEGER, max = NumberMAX_SAFE_INTEGER) => {
if (typeof value !== 'number')
Expand All @@ -81,6 +99,16 @@ const validateInteger = hideStackFrames(
}
);

/**
* @callback validateInt32
* @param {*} value
* @param {string} name
* @param {number} [min]
* @param {number} [max]
* @returns {asserts value is number}
*/

/** @type {validateInt32} */
const validateInt32 = hideStackFrames(
(value, name, min = -2147483648, max = 2147483647) => {
// The defaults for min and max correspond to the limits of 32-bit integers.
Expand All @@ -96,7 +124,16 @@ const validateInt32 = hideStackFrames(
}
);

const validateUint32 = hideStackFrames((value, name, positive) => {
/**
* @callback validateUint32
* @param {*} value
* @param {string} name
* @param {number|boolean} [positive=false]
* @returns {asserts value is number}
*/

/** @type {validateUint32} */
const validateUint32 = hideStackFrames((value, name, positive = false) => {
if (typeof value !== 'number') {
throw new ERR_INVALID_ARG_TYPE(name, 'number', value);
}
Expand All @@ -111,11 +148,29 @@ const validateUint32 = hideStackFrames((value, name, positive) => {
}
});

/**
* @callback validateString
* @param {*} value
* @param {string} name
* @returns {asserts value is string}
*/

/** @type {validateString} */
function validateString(value, name) {
if (typeof value !== 'string')
throw new ERR_INVALID_ARG_TYPE(name, 'string', value);
}

/**
* @callback validateNumber
* @param {*} value
* @param {string} name
* @param {number} [min]
* @param {number} [max]
* @returns {asserts value is number}
*/

/** @type {validateNumber} */
function validateNumber(value, name, min = undefined, max) {
if (typeof value !== 'number')
throw new ERR_INVALID_ARG_TYPE(name, 'number', value);
Expand All @@ -129,6 +184,15 @@ function validateNumber(value, name, min = undefined, max) {
}
}

/**
* @callback validateOneOf
* @template T
* @param {T} value
* @param {string} name
* @param {T[]} oneOf
*/

/** @type {validateOneOf} */
const validateOneOf = hideStackFrames((value, name, oneOf) => {
if (!ArrayPrototypeIncludes(oneOf, value)) {
const allowed = ArrayPrototypeJoin(
Expand All @@ -140,6 +204,14 @@ const validateOneOf = hideStackFrames((value, name, oneOf) => {
}
});

/**
* @callback validateBoolean
* @param {*} value
* @param {string} name
* @returns {asserts value is boolean}
*/

/** @type {validateBoolean} */
function validateBoolean(value, name) {
if (typeof value !== 'boolean')
throw new ERR_INVALID_ARG_TYPE(name, 'boolean', value);
Expand All @@ -152,16 +224,19 @@ function getOwnPropertyValueOrDefault(options, key, defaultValue) {
}

/**
* @param {unknown} value
* @callback validateObject
* @param {*} value
* @param {string} name
* @param {{
* allowArray?: boolean,
* allowFunction?: boolean,
* nullable?: boolean
* }} [options]
*/

/** @type {validateObject} */
const validateObject = hideStackFrames(
(value, name, options) => {
(value, name, options = null) => {
const allowArray = getOwnPropertyValueOrDefault(options, 'allowArray', false);
const allowFunction = getOwnPropertyValueOrDefault(options, 'allowFunction', false);
const nullable = getOwnPropertyValueOrDefault(options, 'nullable', false);
Expand All @@ -174,6 +249,15 @@ const validateObject = hideStackFrames(
}
});

/**
* @callback validateArray
* @param {*} value
* @param {string} name
* @param {number} [minLength]
* @returns {asserts value is any[]}
*/

/** @type {validateArray} */
const validateArray = hideStackFrames((value, name, minLength = 0) => {
if (!ArrayIsArray(value)) {
throw new ERR_INVALID_ARG_TYPE(name, 'Array', value);
Expand All @@ -184,6 +268,12 @@ const validateArray = hideStackFrames((value, name, minLength = 0) => {
}
});

// eslint-disable-next-line jsdoc/require-returns-check
/**
* @param {*} signal
* @param {string} [name='signal']
* @returns {asserts signal is keyof signals}
*/
function validateSignalName(signal, name = 'signal') {
validateString(signal, name);

Expand All @@ -197,6 +287,14 @@ function validateSignalName(signal, name = 'signal') {
}
}

/**
* @callback validateBuffer
* @param {*} buffer
* @param {string} [name='buffer']
* @returns {asserts buffer is ArrayBufferView}
*/

/** @type {validateBuffer} */
const validateBuffer = hideStackFrames((buffer, name = 'buffer') => {
if (!isArrayBufferView(buffer)) {
throw new ERR_INVALID_ARG_TYPE(name,
Expand All @@ -205,6 +303,10 @@ const validateBuffer = hideStackFrames((buffer, name = 'buffer') => {
}
});

/**
* @param {string} data
* @param {string} encoding
*/
function validateEncoding(data, encoding) {
const normalizedEncoding = normalizeEncoding(encoding);
const length = data.length;
Expand All @@ -215,8 +317,14 @@ function validateEncoding(data, encoding) {
}
}

// Check that the port number is not NaN when coerced to a number,
// is an integer and that it falls within the legal range of port numbers.
/**
* Check that the port number is not NaN when coerced to a number,
* is an integer and that it falls within the legal range of port numbers.
* @param {*} port
* @param {string} [name='Port']
* @param {boolean} [allowZero=true]
* @returns {number}
*/
function validatePort(port, name = 'Port', allowZero = true) {
if ((typeof port !== 'number' && typeof port !== 'string') ||
(typeof port === 'string' && StringPrototypeTrim(port).length === 0) ||
Expand All @@ -228,6 +336,13 @@ function validatePort(port, name = 'Port', allowZero = true) {
return port | 0;
}

/**
* @callback validateAbortSignal
* @param {*} signal
* @param {string} name
*/

/** @type {validateAbortSignal} */
const validateAbortSignal = hideStackFrames((signal, name) => {
if (signal !== undefined &&
(signal === null ||
Expand All @@ -237,21 +352,51 @@ const validateAbortSignal = hideStackFrames((signal, name) => {
}
});

/**
* @callback validateFunction
* @param {*} value
* @param {string} name
* @returns {asserts value is Function}
*/

/** @type {validateFunction} */
const validateFunction = hideStackFrames((value, name) => {
if (typeof value !== 'function')
throw new ERR_INVALID_ARG_TYPE(name, 'Function', value);
});

/**
* @callback validatePlainFunction
* @param {*} value
* @param {string} name
* @returns {asserts value is Function}
*/

/** @type {validatePlainFunction} */
const validatePlainFunction = hideStackFrames((value, name) => {
if (typeof value !== 'function' || isAsyncFunction(value))
throw new ERR_INVALID_ARG_TYPE(name, 'Function', value);
});

/**
* @callback validateUndefined
* @param {*} value
* @param {string} name
* @returns {asserts value is undefined}
*/

/** @type {validateUndefined} */
const validateUndefined = hideStackFrames((value, name) => {
if (value !== undefined)
throw new ERR_INVALID_ARG_TYPE(name, 'undefined', value);
});

/**
* @template T
* @param {T} value
* @param {string} name
* @param {T[]} union
*/
function validateUnion(value, name, union) {
if (!ArrayPrototypeIncludes(union, value)) {
throw new ERR_INVALID_ARG_TYPE(name, `('${ArrayPrototypeJoin(union, '|')}')`, value);
Expand Down

0 comments on commit 2efce0f

Please sign in to comment.