Skip to main content
Module

std/node/_util/_util_promisify.ts

Deno standard library
Go to Latest
File
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.//// Adapted from Node.js. Copyright Joyent, Inc. and other Node contributors.//// Permission is hereby granted, free of charge, to any person obtaining a// copy of this software and associated documentation files (the// "Software"), to deal in the Software without restriction, including// without limitation the rights to use, copy, modify, merge, publish,// distribute, sublicense, and/or sell copies of the Software, and to permit// persons to whom the Software is furnished to do so, subject to the// following conditions://// The above copyright notice and this permission notice shall be included// in all copies or substantial portions of the Software.//// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE// USE OR OTHER DEALINGS IN THE SOFTWARE.
// Hack: work around the following TypeScript error:// error: TS2345 [ERROR]: Argument of type 'typeof kCustomPromisifiedSymbol'// is not assignable to parameter of type 'typeof kCustomPromisifiedSymbol'.// assertStrictEquals(kCustomPromisifiedSymbol, promisify.custom);// ~~~~~~~~~~~~~~~~declare const _CustomPromisifiedSymbol: unique symbol;declare const _CustomPromisifyArgsSymbol: unique symbol;declare let Symbol: SymbolConstructor;interface SymbolConstructor { for(key: "nodejs.util.promisify.custom"): typeof _CustomPromisifiedSymbol; for( key: "nodejs.util.promisify.customArgs", ): typeof _CustomPromisifyArgsSymbol;}// End hack.
// In addition to being accessible through util.promisify.custom,// this symbol is registered globally and can be accessed in any environment as// Symbol.for('nodejs.util.promisify.custom').const kCustomPromisifiedSymbol = Symbol.for("nodejs.util.promisify.custom");// This is an internal Node symbol used by functions returning multiple// arguments, e.g. ['bytesRead', 'buffer'] for fs.read().const kCustomPromisifyArgsSymbol = Symbol.for( "nodejs.util.promisify.customArgs",);
class NodeInvalidArgTypeError extends TypeError { public code = "ERR_INVALID_ARG_TYPE"; constructor(argumentName: string, type: string, received: unknown) { super( `The "${argumentName}" argument must be of type ${type}. Received ${typeof received}`, ); }}
export function promisify(original: Function): Function { if (typeof original !== "function") { throw new NodeInvalidArgTypeError("original", "Function", original); } // eslint-disable-next-line @typescript-eslint/no-explicit-any if ((original as any)[kCustomPromisifiedSymbol]) { // eslint-disable-next-line @typescript-eslint/no-explicit-any const fn = (original as any)[kCustomPromisifiedSymbol]; if (typeof fn !== "function") { throw new NodeInvalidArgTypeError( "util.promisify.custom", "Function", fn, ); } return Object.defineProperty(fn, kCustomPromisifiedSymbol, { value: fn, enumerable: false, writable: false, configurable: true, }); }
// Names to create an object from in case the callback receives multiple // arguments, e.g. ['bytesRead', 'buffer'] for fs.read. // eslint-disable-next-line @typescript-eslint/no-explicit-any const argumentNames = (original as any)[kCustomPromisifyArgsSymbol]; // eslint-disable-next-line @typescript-eslint/no-explicit-any function fn(this: any, ...args: unknown[]): Promise<unknown> { return new Promise((resolve, reject) => { original.call(this, ...args, (err: Error, ...values: unknown[]) => { if (err) { return reject(err); } if (argumentNames !== undefined && values.length > 1) { const obj = {}; for (let i = 0; i < argumentNames.length; i++) { // eslint-disable-next-line @typescript-eslint/no-explicit-any (obj as any)[argumentNames[i]] = values[i]; } resolve(obj); } else { resolve(values[0]); } }); }); }
Object.setPrototypeOf(fn, Object.getPrototypeOf(original));
Object.defineProperty(fn, kCustomPromisifiedSymbol, { value: fn, enumerable: false, writable: false, configurable: true, }); return Object.defineProperties( fn, Object.getOwnPropertyDescriptors(original), );}
promisify.custom = kCustomPromisifiedSymbol;