mirror of
https://github.com/arthur-pbty/portfolio2023.git
synced 2026-06-03 23:36:21 +02:00
116 lines
3.4 KiB
JavaScript
116 lines
3.4 KiB
JavaScript
"use strict";
|
|
/*
|
|
* @poppinss/macroable
|
|
*
|
|
* (c) Harminder Virk <virk@adonisjs.com>
|
|
*
|
|
* For the full copyright and license information, please view the LICENSE
|
|
* file that was distributed with this source code.
|
|
*/
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.Macroable = void 0;
|
|
/**
|
|
* Macroable is an abstract class to add ability to extend your class
|
|
* prototype using better syntax.
|
|
*
|
|
* Macroable has handful of benefits over using traditional `prototype` approach.
|
|
*
|
|
* 1. Methods or properties added dynamically to the class can be removed using `hydrate` method.
|
|
* 2. Can define singleton getters.
|
|
*/
|
|
class Macroable {
|
|
constructor() {
|
|
if (!this.constructor['macros'] || !this.constructor['getters']) {
|
|
throw new Error('Set static properties "macros = {}" and "getters = {}" on the class for the macroable to work.');
|
|
}
|
|
}
|
|
/**
|
|
* Add a macro to the class. This method is a better to manually adding
|
|
* to `class.prototype.method`.
|
|
*
|
|
* Also macros added using `Macroable.macro` can be cleared anytime
|
|
*
|
|
* @example
|
|
* ```js
|
|
* Macroable.macro('getUsername', function () {
|
|
* return 'virk'
|
|
* })
|
|
* ```
|
|
*/
|
|
static macro(name, callback) {
|
|
const self = this;
|
|
self.macros[name] = callback;
|
|
this.prototype[name] = callback;
|
|
}
|
|
/**
|
|
* Return the existing macro or null if it doesn't exists
|
|
*/
|
|
static getMacro(name) {
|
|
return this.macros[name];
|
|
}
|
|
/**
|
|
* Returns a boolean telling if a macro exists
|
|
*/
|
|
static hasMacro(name) {
|
|
return !!this.getMacro(name);
|
|
}
|
|
/**
|
|
* Define a getter, which is invoked everytime the value is accessed. This method
|
|
* also allows adding single getters, whose value is cached after first time
|
|
*
|
|
* @example
|
|
* ```js
|
|
* Macroable.getter('time', function () {
|
|
* return new Date().getTime()
|
|
* })
|
|
*
|
|
* console.log(new Macroable().time)
|
|
*
|
|
* // Singletons
|
|
* Macroable.getter('time', function () {
|
|
* return new Date().getTime()
|
|
* }, true)
|
|
*
|
|
* console.log(new Macroable().time)
|
|
* ```
|
|
*/
|
|
static getter(name, callback, singleton = false) {
|
|
const wrappedCallback = singleton
|
|
? function wrappedCallback() {
|
|
const value = callback.bind(this)();
|
|
Object.defineProperty(this, name, { value, configurable: true });
|
|
return value;
|
|
}
|
|
: callback;
|
|
const self = this;
|
|
self.getters[name] = wrappedCallback;
|
|
Object.defineProperty(this.prototype, name, {
|
|
get: wrappedCallback,
|
|
configurable: true,
|
|
enumerable: true,
|
|
});
|
|
}
|
|
/**
|
|
* Return the existing getter or null if it doesn't exists
|
|
*/
|
|
static getGetter(name) {
|
|
return this.getters[name];
|
|
}
|
|
/**
|
|
* Returns a boolean telling if a getter exists
|
|
*/
|
|
static hasGetter(name) {
|
|
return !!this.getGetter(name);
|
|
}
|
|
/**
|
|
* Cleanup getters and macros from the class
|
|
*/
|
|
static hydrate() {
|
|
Object.keys(this.macros).forEach((key) => Reflect.deleteProperty(this.prototype, key));
|
|
Object.keys(this.getters).forEach((key) => Reflect.deleteProperty(this.prototype, key));
|
|
this.macros = {};
|
|
this.getters = {};
|
|
}
|
|
}
|
|
exports.Macroable = Macroable;
|