Socket
Socket
Sign inDemoInstall

macroable

Package Overview
Dependencies
Maintainers
1
Versions
27
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

macroable - npm Package Compare versions

Comparing version 3.0.0 to 4.0.0

68

build/index.d.ts

@@ -6,17 +6,75 @@ declare type MacroableFn<T> = (this: T, ...args: any[]) => any;

export interface MacroableConstructorContract<T extends any> {
macro(name: string, callback: MacroableFn<T>): any;
getter(name: string, callback: MacroableFn<T>, singleton?: boolean): any;
hydrate(): any;
macro(name: string, callback: MacroableFn<T>): void;
getter(name: string, callback: MacroableFn<T>, singleton?: boolean): void;
hydrate(): void;
}
/**
* 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.
*/
export declare abstract class Macroable {
protected static _macros: MacroableMap;
protected static _getters: MacroableMap;
protected static macros: MacroableMap;
protected static getters: MacroableMap;
constructor();
/**
* 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<T extends any = any>(name: string, callback: MacroableFn<T>): void;
/**
* Return the existing macro or null if it doesn't exists
*/
static getMacro(name: string): MacroableFn<any> | undefined;
/**
* Returns a boolean telling if a macro exists
*/
static hasMacro(name: string): boolean;
/**
* 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<T extends any = any>(name: string, callback: MacroableFn<T>, singleton?: boolean): void;
/**
* Return the existing getter or null if it doesn't exists
*/
static getGetter(name: string): MacroableFn<any> | undefined;
/**
* Returns a boolean telling if a getter exists
*/
static hasGetter(name: string): boolean;
/**
* Cleanup getters and macros from the class
*/
static hydrate(): void;
}
export {};
"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 });
/**
* 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.hasOwnProperty('macros') || !this.constructor.hasOwnProperty('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) {
this._macros[name] = callback;
this.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];
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) {

@@ -20,3 +81,3 @@ const wrappedCallback = singleton ? function wrappedCallback() {

} : callback;
this._getters[name] = wrappedCallback;
this.getters[name] = wrappedCallback;
Object.defineProperty(this.prototype, name, {

@@ -28,17 +89,26 @@ get: wrappedCallback,

}
/**
* Return the existing getter or null if it doesn't exists
*/
static getGetter(name) {
return this._getters[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 = {};
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;
Macroable._macros = {};
Macroable._getters = {};
Macroable.macros = {};
Macroable.getters = {};

38

package.json
{
"name": "macroable",
"version": "3.0.0",
"version": "4.0.0",
"description": "A simple ES6 class that can be extended to provide macros and getters functionality",
"main": "build/index.js",
"files": [
"build/index.js",
"build/index.d.ts"
"build/index.d.ts",
"build/index.js"
],

@@ -13,11 +13,11 @@ "scripts": {

"pretest": "npm run lint",
"test": "nyc node japaFile.js",
"lint": "tslint --project tsconfig.json",
"test": "node japaFile.js",
"clean": "del build",
"compile": "npm run lint && npm run clean && tsc",
"build": "npm run compile",
"coverage": "nyc report --reporter=text-lcov | coveralls",
"commit": "git-cz",
"release": "np",
"version": "npm run build"
"version": "npm run build",
"lint": "eslint . --ext=.ts",
"prepublishOnly": "npm run build"
},

@@ -30,24 +30,20 @@ "keywords": [

"devDependencies": {
"@adonisjs/mrm-preset": "^2.1.0",
"@types/node": "^12.12.11",
"@adonisjs/mrm-preset": "^2.2.3",
"@types/node": "^12.12.21",
"commitizen": "^4.0.3",
"coveralls": "^3.0.8",
"cz-conventional-changelog": "^3.0.2",
"del-cli": "^3.0.0",
"eslint": "^6.7.2",
"eslint-plugin-adonis": "^1.0.4",
"husky": "^3.1.0",
"japa": "^3.0.1",
"mrm": "^1.2.2",
"np": "^5.1.3",
"nyc": "^14.1.1",
"ts-node": "^8.5.2",
"tslint": "^5.20.1",
"tslint-eslint-rules": "^5.4.0",
"typescript": "^3.7.2"
"mrm": "^2.0.2",
"np": "^5.2.1",
"ts-node": "^8.5.4",
"typescript": "^3.7.3"
},
"dependencies": {
"node-exceptions": "^4.0.1"
},
"dependencies": {},
"nyc": {
"exclude": [
"test.ts"
"test"
],

@@ -54,0 +50,0 @@ "extension": [

@@ -0,12 +1,15 @@

<div align="center"><img src="https://res.cloudinary.com/adonisjs/image/upload/q_100/v1557762307/poppinss_iftxlt.jpg" width="600px"></div>
# Macroable
> Extend `class` prototype in style 😎
[![travis-image]][travis-url]
[![appveyor-image]][appveyor-url]
[![coveralls-image]][coveralls-url]
[![npm-image]][npm-url]
![](https://img.shields.io/badge/Uses-Typescript-294E80.svg?style=flat-square&colorA=ddd)
[![circleci-image]][circleci-url] [![typescript-image]][typescript-url] [![npm-image]][npm-url] [![license-image]][license-url]
Macroable is a simple class that your classes can extend in order to expose an API for extending the class. Let's see how a class can be extended without Macroable first.
Base class for exposing external API to extend the class prototype in a more declarative way.
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
## Traditional approach

@@ -35,3 +38,3 @@

## Using macroable it's simpler
## Using macroable

@@ -44,4 +47,4 @@ ```js

Foo._macros = {}
Foo._getters = {}
Foo.macros = {}
Foo.getters = {}

@@ -63,30 +66,16 @@ module.exports = Foo

You can see the API is simpler and less verbose. However, their are couple more benefits to using Macroable.
You can see the API is simpler and less verbose. However, there are couple of extra benefits of using Macroable.
1. You can add singleton getters, which are evaluated only once and then cached value is returned.
2. Cleanup all `macros` and `getters` added using Macroable.
### Defining singleton getters
Singleton getters are evaluated only once and then cached value is returned.
## Installation
```bash
npm i macroable
```
## Usage
```js
const { Macroable } from 'macroable'
class Foo extends Macroable {
}
Foo._macros = {}
Foo._getters = {}
module.exports = Foo
Foo.getter('baseUrl', function () {
return lazilyEvaluateAndReturnUrl()
}, true) 👈
```
## API
### Hydrating the class
Using the `hydrate` method, you can remove macros and getters added on a given class.
#### macro(name, callback) => void
Add a function to the prototype
```js

@@ -96,67 +85,22 @@ Foo.macro('greet', function (name) {

})
```
#### hasMacro(name) => boolean
Find if macro exists.
```js
Foo.hasMacro('greet')
```
#### getter(name, callback, isSingleton?) => void
Add getter to the prototype and optionally make it singleton.
```js
Foo.getter('username', function () {
return 'virk'
}, true)
```
})
#### hasGetter(name) => boolean
Find if getter exists.
```js
Foo.hasGetter('greet')
Foo.hydrate() 👈
Foo.greet // undefined
Foo.username // undefined
```
#### hydrate
Remove all macros and getters added using `Macroable`.
[circleci-image]: https://img.shields.io/circleci/project/github/poppinss/macroable/master.svg?style=for-the-badge&logo=circleci
[circleci-url]: https://circleci.com/gh/poppinss/macroable "circleci"
```js
Foo.getter('username', function () {
return 'virk'
}, true)
[typescript-image]: https://img.shields.io/badge/Typescript-294E80.svg?style=for-the-badge&logo=typescript
[typescript-url]: "typescript"
Foo.hydrate()
[npm-image]: https://img.shields.io/npm/v/macroable.svg?style=for-the-badge&logo=npm
[npm-url]: https://npmjs.org/package/macroable "npm"
Foo.hasGetter('username') // false
```
## Change log
The change log can be found in the [CHANGELOG.md](CHANGELOG.md) file.
## Contributing
Everyone is welcome to contribute. Please go through the following guides, before getting started.
1. [Contributing](https://adonisjs.com/contributing)
2. [Code of conduct](https://adonisjs.com/code-of-conduct)
## Authors & License
[thetutlage](https://github.com/thetutlage) and [contributors](https://github.com/poppinss/macroable/graphs/contributors).
MIT License, see the included [MIT](LICENSE.md) file.
[travis-image]: https://img.shields.io/travis/poppinss/macroable/master.svg?style=flat-square&logo=travis
[travis-url]: https://travis-ci.org/poppinss/macroable "travis"
[appveyor-image]: https://img.shields.io/appveyor/ci/thetutlage/macroable/master.svg?style=flat-square&logo=appveyor
[appveyor-url]: https://ci.appveyor.com/project/thetutlage/macroable "appveyor"
[coveralls-image]: https://img.shields.io/coveralls/poppinss/macroable/master.svg?style=flat-square
[coveralls-url]: https://coveralls.io/github/poppinss/macroable "coveralls"
[npm-image]: https://img.shields.io/npm/v/macroable.svg?style=flat-square&logo=npm
[npm-url]: https://npmjs.org/package/macroable "npm"
[license-image]: https://img.shields.io/npm/l/macroable?color=blueviolet&style=for-the-badge
[license-url]: LICENSE.md "license"
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc