1// Copyright Joyent, Inc. and other Node contributors. 2// 3// Permission is hereby granted, free of charge, to any person obtaining a 4// copy of this software and associated documentation files (the 5// "Software"), to deal in the Software without restriction, including 6// without limitation the rights to use, copy, modify, merge, publish, 7// distribute, sublicense, and/or sell copies of the Software, and to permit 8// persons to whom the Software is furnished to do so, subject to the 9// following conditions: 10// 11// The above copyright notice and this permission notice shall be included 12// in all copies or substantial portions of the Software. 13// 14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 17// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 18// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 19// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 20// USE OR OTHER DEALINGS IN THE SOFTWARE. 21 22'use strict'; 23 24const { 25 ArrayIsArray, 26 ArrayPrototypeJoin, 27 ArrayPrototypePop, 28 Date, 29 DatePrototypeGetDate, 30 DatePrototypeGetHours, 31 DatePrototypeGetMinutes, 32 DatePrototypeGetMonth, 33 DatePrototypeGetSeconds, 34 Error, 35 FunctionPrototypeBind, 36 NumberIsSafeInteger, 37 ObjectDefineProperties, 38 ObjectDefineProperty, 39 ObjectGetOwnPropertyDescriptors, 40 ObjectKeys, 41 ObjectPrototypeToString, 42 ObjectSetPrototypeOf, 43 ObjectValues, 44 ReflectApply, 45 StringPrototypePadStart, 46} = primordials; 47 48const { 49 codes: { 50 ERR_FALSY_VALUE_REJECTION, 51 ERR_INVALID_ARG_TYPE, 52 ERR_OUT_OF_RANGE, 53 }, 54 errnoException, 55 exceptionWithHostPort, 56 hideStackFrames, 57} = require('internal/errors'); 58const { 59 format, 60 formatWithOptions, 61 inspect, 62 stripVTControlCharacters, 63} = require('internal/util/inspect'); 64const { debuglog } = require('internal/util/debuglog'); 65const { 66 validateFunction, 67 validateNumber, 68} = require('internal/validators'); 69const { isBuffer } = require('buffer').Buffer; 70const types = require('internal/util/types'); 71 72const { 73 deprecate, 74 getSystemErrorMap, 75 getSystemErrorName: internalErrorName, 76 promisify, 77 toUSVString, 78 defineLazyProperties, 79} = require('internal/util'); 80 81let abortController; 82 83function lazyAbortController() { 84 abortController ??= require('internal/abort_controller'); 85 return abortController; 86} 87 88let internalDeepEqual; 89 90/** 91 * @deprecated since v4.0.0 92 * @param {any} arg 93 * @returns {arg is boolean} 94 */ 95function isBoolean(arg) { 96 return typeof arg === 'boolean'; 97} 98 99/** 100 * @deprecated since v4.0.0 101 * @param {any} arg 102 * @returns {arg is null} 103 */ 104function isNull(arg) { 105 return arg === null; 106} 107 108/** 109 * @deprecated since v4.0.0 110 * @param {any} arg 111 * @returns {arg is (null | undefined)} 112 */ 113function isNullOrUndefined(arg) { 114 return arg === null || arg === undefined; 115} 116 117/** 118 * @deprecated since v4.0.0 119 * @param {any} arg 120 * @returns {arg is number} 121 */ 122function isNumber(arg) { 123 return typeof arg === 'number'; 124} 125 126/** 127 * @param {any} arg 128 * @returns {arg is string} 129 */ 130function isString(arg) { 131 return typeof arg === 'string'; 132} 133 134/** 135 * @deprecated since v4.0.0 136 * @param {any} arg 137 * @returns {arg is symbol} 138 */ 139function isSymbol(arg) { 140 return typeof arg === 'symbol'; 141} 142 143/** 144 * @deprecated since v4.0.0 145 * @param {any} arg 146 * @returns {arg is undefined} 147 */ 148function isUndefined(arg) { 149 return arg === undefined; 150} 151 152/** 153 * @deprecated since v4.0.0 154 * @param {any} arg 155 * @returns {a is NonNullable<object>} 156 */ 157function isObject(arg) { 158 return arg !== null && typeof arg === 'object'; 159} 160 161/** 162 * @deprecated since v4.0.0 163 * @param {any} e 164 * @returns {arg is Error} 165 */ 166function isError(e) { 167 return ObjectPrototypeToString(e) === '[object Error]' || e instanceof Error; 168} 169 170/** 171 * @deprecated since v4.0.0 172 * @param {any} arg 173 * @returns {arg is Function} 174 */ 175function isFunction(arg) { 176 return typeof arg === 'function'; 177} 178 179/** 180 * @deprecated since v4.0.0 181 * @param {any} arg 182 * @returns {arg is (boolean | null | number | string | symbol | undefined)} 183 */ 184function isPrimitive(arg) { 185 return arg === null || 186 (typeof arg !== 'object' && typeof arg !== 'function'); 187} 188 189/** 190 * @param {number} n 191 * @returns {string} 192 */ 193function pad(n) { 194 return StringPrototypePadStart(n.toString(), 2, '0'); 195} 196 197const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 198 'Oct', 'Nov', 'Dec']; 199 200/** 201 * @returns {string} 26 Feb 16:19:34 202 */ 203function timestamp() { 204 const d = new Date(); 205 const t = ArrayPrototypeJoin([ 206 pad(DatePrototypeGetHours(d)), 207 pad(DatePrototypeGetMinutes(d)), 208 pad(DatePrototypeGetSeconds(d)), 209 ], ':'); 210 return `${DatePrototypeGetDate(d)} ${months[DatePrototypeGetMonth(d)]} ${t}`; 211} 212 213let console; 214/** 215 * Log is just a thin wrapper to console.log that prepends a timestamp 216 * @deprecated since v6.0.0 217 * @type {(...args: any[]) => void} 218 */ 219function log(...args) { 220 if (!console) { 221 console = require('internal/console/global'); 222 } 223 console.log('%s - %s', timestamp(), format(...args)); 224} 225 226/** 227 * Inherit the prototype methods from one constructor into another. 228 * 229 * The Function.prototype.inherits from lang.js rewritten as a standalone 230 * function (not on Function.prototype). NOTE: If this file is to be loaded 231 * during bootstrapping this function needs to be rewritten using some native 232 * functions as prototype setup using normal JavaScript does not work as 233 * expected during bootstrapping (see mirror.js in r114903). 234 * @param {Function} ctor Constructor function which needs to inherit the 235 * prototype. 236 * @param {Function} superCtor Constructor function to inherit prototype from. 237 * @throws {TypeError} Will error if either constructor is null, or if 238 * the super constructor lacks a prototype. 239 */ 240function inherits(ctor, superCtor) { 241 242 if (ctor === undefined || ctor === null) 243 throw new ERR_INVALID_ARG_TYPE('ctor', 'Function', ctor); 244 245 if (superCtor === undefined || superCtor === null) 246 throw new ERR_INVALID_ARG_TYPE('superCtor', 'Function', superCtor); 247 248 if (superCtor.prototype === undefined) { 249 throw new ERR_INVALID_ARG_TYPE('superCtor.prototype', 250 'Object', superCtor.prototype); 251 } 252 ObjectDefineProperty(ctor, 'super_', { 253 __proto__: null, 254 value: superCtor, 255 writable: true, 256 configurable: true, 257 }); 258 ObjectSetPrototypeOf(ctor.prototype, superCtor.prototype); 259} 260 261/** 262 * @deprecated since v6.0.0 263 * @template T 264 * @template S 265 * @param {T} target 266 * @param {S} source 267 * @returns {S extends null ? T : (T & S)} 268 */ 269function _extend(target, source) { 270 // Don't do anything if source isn't an object 271 if (source === null || typeof source !== 'object') return target; 272 273 const keys = ObjectKeys(source); 274 let i = keys.length; 275 while (i--) { 276 target[keys[i]] = source[keys[i]]; 277 } 278 return target; 279} 280 281const callbackifyOnRejected = hideStackFrames((reason, cb) => { 282 // `!reason` guard inspired by bluebird (Ref: https://goo.gl/t5IS6M). 283 // Because `null` is a special error value in callbacks which means "no error 284 // occurred", we error-wrap so the callback consumer can distinguish between 285 // "the promise rejected with null" or "the promise fulfilled with undefined". 286 if (!reason) { 287 reason = new ERR_FALSY_VALUE_REJECTION(reason); 288 } 289 return cb(reason); 290}); 291 292/** 293 * @template {(...args: any[]) => Promise<any>} T 294 * @param {T} original 295 * @returns {T extends (...args: infer TArgs) => Promise<infer TReturn> ? 296 * ((...params: [...TArgs, ((err: Error, ret: TReturn) => any)]) => void) : 297 * never 298 * } 299 */ 300function callbackify(original) { 301 validateFunction(original, 'original'); 302 303 // We DO NOT return the promise as it gives the user a false sense that 304 // the promise is actually somehow related to the callback's execution 305 // and that the callback throwing will reject the promise. 306 function callbackified(...args) { 307 const maybeCb = ArrayPrototypePop(args); 308 validateFunction(maybeCb, 'last argument'); 309 const cb = FunctionPrototypeBind(maybeCb, this); 310 // In true node style we process the callback on `nextTick` with all the 311 // implications (stack, `uncaughtException`, `async_hooks`) 312 ReflectApply(original, this, args) 313 .then((ret) => process.nextTick(cb, null, ret), 314 (rej) => process.nextTick(callbackifyOnRejected, rej, cb)); 315 } 316 317 const descriptors = ObjectGetOwnPropertyDescriptors(original); 318 // It is possible to manipulate a functions `length` or `name` property. This 319 // guards against the manipulation. 320 if (typeof descriptors.length.value === 'number') { 321 descriptors.length.value++; 322 } 323 if (typeof descriptors.name.value === 'string') { 324 descriptors.name.value += 'Callbackified'; 325 } 326 const propertiesValues = ObjectValues(descriptors); 327 for (let i = 0; i < propertiesValues.length; i++) { 328 // We want to use null-prototype objects to not rely on globally mutable 329 // %Object.prototype%. 330 ObjectSetPrototypeOf(propertiesValues[i], null); 331 } 332 ObjectDefineProperties(callbackified, descriptors); 333 return callbackified; 334} 335 336/** 337 * @param {number} err 338 * @returns {string} 339 */ 340function getSystemErrorName(err) { 341 validateNumber(err, 'err'); 342 if (err >= 0 || !NumberIsSafeInteger(err)) { 343 throw new ERR_OUT_OF_RANGE('err', 'a negative integer', err); 344 } 345 return internalErrorName(err); 346} 347 348// Keep the `exports =` so that various functions can still be monkeypatched 349module.exports = { 350 _errnoException: errnoException, 351 _exceptionWithHostPort: exceptionWithHostPort, 352 _extend, 353 callbackify, 354 debug: debuglog, 355 debuglog, 356 deprecate, 357 format, 358 formatWithOptions, 359 getSystemErrorMap, 360 getSystemErrorName, 361 inherits, 362 inspect, 363 isArray: ArrayIsArray, 364 isBoolean, 365 isBuffer, 366 isDeepStrictEqual(a, b) { 367 if (internalDeepEqual === undefined) { 368 internalDeepEqual = require('internal/util/comparisons') 369 .isDeepStrictEqual; 370 } 371 return internalDeepEqual(a, b); 372 }, 373 isNull, 374 isNullOrUndefined, 375 isNumber, 376 isString, 377 isSymbol, 378 isUndefined, 379 isRegExp: types.isRegExp, 380 isObject, 381 isDate: types.isDate, 382 isError, 383 isFunction, 384 isPrimitive, 385 log, 386 promisify, 387 stripVTControlCharacters, 388 toUSVString, 389 get transferableAbortSignal() { 390 return lazyAbortController().transferableAbortSignal; 391 }, 392 get transferableAbortController() { 393 return lazyAbortController().transferableAbortController; 394 }, 395 get aborted() { 396 return lazyAbortController().aborted; 397 }, 398 types, 399}; 400 401defineLazyProperties( 402 module.exports, 403 'internal/util/parse_args/parse_args', 404 ['parseArgs'], 405); 406 407defineLazyProperties( 408 module.exports, 409 'internal/encoding', 410 ['TextDecoder', 'TextEncoder'], 411); 412 413defineLazyProperties( 414 module.exports, 415 'internal/mime', 416 ['MIMEType', 'MIMEParams'], 417); 418