electron/lib/common/api/deprecate.ts

136 lines
3.9 KiB
TypeScript
Raw Normal View History

2020-03-20 20:28:31 +00:00
let deprecationHandler: ElectronInternal.DeprecationHandler | null = null;
2016-01-12 02:40:23 +00:00
function warnOnce (oldName: string, newName?: string) {
2020-03-20 20:28:31 +00:00
let warned = false;
const msg = newName
? `'${oldName}' is deprecated and will be removed. Please use '${newName}' instead.`
2020-03-20 20:28:31 +00:00
: `'${oldName}' is deprecated and will be removed.`;
return () => {
if (!warned && !process.noDeprecation) {
2020-03-20 20:28:31 +00:00
warned = true;
deprecate.log(msg);
}
2020-03-20 20:28:31 +00:00
};
}
const deprecate: ElectronInternal.DeprecationUtil = {
warnOnce,
2020-03-20 20:28:31 +00:00
setHandler: (handler) => { deprecationHandler = handler; },
getHandler: () => deprecationHandler,
warn: (oldName, newName) => {
if (!process.noDeprecation) {
2020-03-20 20:28:31 +00:00
deprecate.log(`'${oldName}' is deprecated. Use '${newName}' instead.`);
}
},
log: (message) => {
if (typeof deprecationHandler === 'function') {
2020-03-20 20:28:31 +00:00
deprecationHandler(message);
} else if (process.throwDeprecation) {
2020-03-20 20:28:31 +00:00
throw new Error(message);
} else if (process.traceDeprecation) {
2020-03-20 20:28:31 +00:00
return console.trace(message);
} else {
2020-03-20 20:28:31 +00:00
return console.warn(`(electron) ${message}`);
}
},
// remove a function with no replacement
removeFunction: (fn, removedName) => {
2020-03-20 20:28:31 +00:00
if (!fn) { throw Error(`'${removedName} function' is invalid or does not exist.`); }
// wrap the deprecated function to warn user
2020-03-20 20:28:31 +00:00
const warn = warnOnce(`${fn.name} function`);
return function (this: any) {
2020-03-20 20:28:31 +00:00
warn();
fn.apply(this, arguments);
};
},
// change the name of a function
renameFunction: (fn, newName) => {
2020-03-20 20:28:31 +00:00
const warn = warnOnce(`${fn.name} function`, `${newName} function`);
return function (this: any) {
2020-03-20 20:28:31 +00:00
warn();
return fn.apply(this, arguments);
};
},
2020-06-30 19:49:08 +00:00
moveAPI<T extends Function> (fn: T, oldUsage: string, newUsage: string): T {
2020-03-20 20:28:31 +00:00
const warn = warnOnce(oldUsage, newUsage);
return function (this: any) {
2020-03-20 20:28:31 +00:00
warn();
return fn.apply(this, arguments);
2020-06-30 19:49:08 +00:00
} as any;
},
// change the name of an event
event: (emitter, oldName, newName) => {
const warn = newName.startsWith('-') /* internal event */
? warnOnce(`${oldName} event`)
2020-03-20 20:28:31 +00:00
: warnOnce(`${oldName} event`, `${newName} event`);
return emitter.on(newName, function (this: NodeJS.EventEmitter, ...args) {
if (this.listenerCount(oldName) !== 0) {
2020-03-20 20:28:31 +00:00
warn();
this.emit(oldName, ...args);
}
2020-03-20 20:28:31 +00:00
});
},
// remove a property with no replacement
removeProperty: (o, removedName, onlyForValues) => {
// if the property's already been removed, warn about it
const info = Object.getOwnPropertyDescriptor((o as any).__proto__, removedName) // eslint-disable-line
if (!info) {
2020-03-20 20:28:31 +00:00
deprecate.log(`Unable to remove property '${removedName}' from an object that lacks it.`);
return o;
}
if (!info.get || !info.set) {
2020-03-20 20:28:31 +00:00
deprecate.log(`Unable to remove property '${removedName}' from an object does not have a getter / setter`);
return o;
}
// wrap the deprecated property in an accessor to warn
2020-03-20 20:28:31 +00:00
const warn = warnOnce(removedName);
return Object.defineProperty(o, removedName, {
configurable: true,
get: () => {
2020-03-20 20:28:31 +00:00
warn();
return info.get!.call(o);
},
set: newVal => {
if (!onlyForValues || onlyForValues.includes(newVal)) {
2020-03-20 20:28:31 +00:00
warn();
}
2020-03-20 20:28:31 +00:00
return info.set!.call(o, newVal);
}
2020-03-20 20:28:31 +00:00
});
},
// change the name of a property
renameProperty: (o, oldName, newName) => {
2020-03-20 20:28:31 +00:00
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)) {
2020-03-20 20:28:31 +00:00
warn();
o[newName] = (o as any)[oldName];
2018-05-29 13:40:19 +00:00
}
// wrap the deprecated property in an accessor to warn
// and redirect to the new property
return Object.defineProperty(o, oldName, {
get: () => {
2020-03-20 20:28:31 +00:00
warn();
return o[newName];
},
set: value => {
2020-03-20 20:28:31 +00:00
warn();
o[newName] = value;
}
2020-03-20 20:28:31 +00:00
});
}
2020-03-20 20:28:31 +00:00
};
2017-11-20 14:12:34 +00:00
2020-03-20 20:28:31 +00:00
export default deprecate;