asarfuckery/electronasar/canary/common/api/deprecate.js

187 lines
6.5 KiB
JavaScript

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
let deprecationHandler = null;
function warnOnce(oldName, newName) {
let warned = false;
const msg = newName
? `'${oldName}' is deprecated and will be removed. Please use '${newName}' instead.`
: `'${oldName}' is deprecated and will be removed.`;
return () => {
if (!warned && !process.noDeprecation) {
warned = true;
deprecate.log(msg);
}
};
}
const deprecate = {
setHandler: (handler) => { deprecationHandler = handler; },
getHandler: () => deprecationHandler,
warn: (oldName, newName) => {
if (!process.noDeprecation) {
deprecate.log(`'${oldName}' is deprecated. Use '${newName}' instead.`);
}
},
log: (message) => {
if (typeof deprecationHandler === 'function') {
deprecationHandler(message);
}
else if (process.throwDeprecation) {
throw new Error(message);
}
else if (process.traceDeprecation) {
return console.trace(message);
}
else {
return console.warn(`(electron) ${message}`);
}
},
// remove a function with no replacement
removeFunction: (fn, removedName) => {
if (!fn) {
throw Error(`'${removedName} function' is invalid or does not exist.`);
}
// wrap the deprecated function to warn user
const warn = warnOnce(`${fn.name} function`);
return function () {
warn();
fn.apply(this, arguments);
};
},
// change the name of a function
renameFunction: (fn, newName) => {
const warn = warnOnce(`${fn.name} function`, `${newName} function`);
return function () {
warn();
fn.apply(this, arguments);
};
},
// change the name of an event
event: (emitter, oldName, newName) => {
const warn = newName.startsWith('-') /* internal event */
? warnOnce(`${oldName} event`)
: warnOnce(`${oldName} event`, `${newName} event`);
return emitter.on(newName, function (...args) {
if (this.listenerCount(oldName) !== 0) {
warn();
this.emit(oldName, ...args);
}
});
},
// deprecate a getter/setter function pair in favor of a property
fnToProperty: (module, prop, getter, setter) => {
const withWarnOnce = (obj, key, oldName, newName) => {
const warn = warnOnce(oldName, newName);
return (...args) => {
warn();
return obj[key](...args);
};
};
module[getter.substr(1)] = withWarnOnce(module, getter, `${getter.substr(1)} function`, `${prop} property`);
module[setter.substr(1)] = withWarnOnce(module, setter, `${setter.substr(1)} function`, `${prop} property`);
},
// remove a property with no replacement
removeProperty: (o, removedName) => {
// if the property's already been removed, warn about it
if (!(removedName in o)) {
deprecate.log(`Unable to remove property '${removedName}' from an object that lacks it.`);
}
// wrap the deprecated property in an accessor to warn
const warn = warnOnce(removedName);
let val = o[removedName];
return Object.defineProperty(o, removedName, {
configurable: true,
get: () => {
warn();
return val;
},
set: newVal => {
warn();
val = newVal;
}
});
},
// deprecate a callback-based function in favor of one returning a Promise
promisify: (fn) => {
const fnName = fn.name || 'function';
const oldName = `${fnName} with callbacks`;
const newName = `${fnName} with Promises`;
const warn = warnOnce(oldName, newName);
return function (...params) {
let cb;
if (params.length > 0 && typeof params[params.length - 1] === 'function') {
cb = params.pop();
}
const promise = fn.apply(this, params);
if (!cb)
return promise;
if (process.enablePromiseAPIs)
warn();
return promise
.then((res) => {
process.nextTick(() => {
cb.length === 2 ? cb(null, res) : cb(res);
});
return res;
}, (err) => {
process.nextTick(() => {
cb.length === 2 ? cb(err) : cb();
});
throw err;
});
};
},
// deprecate a callback-based function in favor of one returning a Promise
promisifyMultiArg: (fn, convertPromiseValue) => {
const fnName = fn.name || 'function';
const oldName = `${fnName} with callbacks`;
const newName = `${fnName} with Promises`;
const warn = warnOnce(oldName, newName);
return function (...params) {
let cb;
if (params.length > 0 && typeof params[params.length - 1] === 'function') {
cb = params.pop();
}
const promise = fn.apply(this, params);
if (!cb)
return promise;
if (process.enablePromiseAPIs)
warn();
return promise
.then((res) => {
if (convertPromiseValue) {
res = convertPromiseValue(res);
}
process.nextTick(() => {
// eslint-disable-next-line standard/no-callback-literal
cb.length > 2 ? cb(null, ...res) : cb(...res);
});
}, (err) => {
process.nextTick(() => cb(err));
});
};
},
// change the name of a property
renameProperty: (o, oldName, newName) => {
const warn = warnOnce(oldName, newName);
// if the new property isn't there yet,
// inject it and warn about it
if ((oldName in o) && !(newName in o)) {
warn();
o[newName] = o[oldName];
}
// wrap the deprecated property in an accessor to warn
// and redirect to the new property
return Object.defineProperty(o, oldName, {
get: () => {
warn();
return o[newName];
},
set: value => {
warn();
o[newName] = value;
}
});
}
};
exports.default = deprecate;