Socket
Socket
Sign inDemoInstall

to-aop

Package Overview
Dependencies
0
Maintainers
1
Versions
30
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

    to-aop

AOP(aspect-oriented programming) library or creating hooks for debug and monkey patch function using ES6 Proxy|Class Prototype.


Version published
Weekly downloads
3.2K
increased by1.95%
Maintainers
1
Install size
63.0 kB
Created
Weekly downloads
 

Changelog

Source

0.5.4 (2021-10-06)

Bug Fixes

  • error property of undefined (62beec3)

Features

  • console: turn off console warnings for static getters (f59fce4)

Readme

Source

to-aop

Build Status Coverage Status NPM package version code style: prettier

The to-aop module help you with applying Aspect Oriented Programming to JavaScript. It use under the hood ES Proxy for object same as other similar modules. It allow you hook class without creating new instance as well. It use javascript prototype for that.

For example I am using it for adding hooks to production code where all debug code is missing. I don't have got access to instance but I have only class constructor. But usage is unlimited.

More articles about AOP:

  1. https://blog.mgechev.com/2015/07/29/aspect-oriented-programming-javascript-aop-js/
  2. https://hackernoon.com/aspect-oriented-programming-in-javascript-es5-typescript-d751dda576d0

Examples:

  1. https://github.com/mjancarik/shallow-with-context/blob/master/src/shallowWithContext.js
  2. https://github.com/seznam/ima/blob/master/packages/devtools/src/services/defaultSettings.json

Installation

npm i to-aop --save

Usage

Easy example for native Date.now method.

import { aop, hookName, createHook } from 'to-aop';

const nowHook = createHook(hookName.aroundMethod, 'now', (args) => {
    return 1;
});

aop(Date, nowHook);

Date.now() // returns 1

Other example with more hooks for your defined class.

// a.js
export default class A {
  constructor(variable) {
    this.variable = variable;
  }

  method() {
    return this.variable;
  }

  notHookedMethod() {
    return 'not hook';
  }    
}
Applying AOP to class

You can use it for creating hook to your favorite framework or your own application without modification source code.

import { aop, hookName, createHook, unAop } from 'to-aop';
import A from './a';

const classHookBefore = createHook(
  hookName.beforeMethod,
  /^(method)$/,
  ({ target, object, property, context, args, meta }) => {
    //call your own hook
    meta.startTime = performance.now();
    console.log(
      `Instance of ${target.name} call "${property}"
with arguments ${args && args.length ? args : '[]'}.`
    );
  }
);

const classHookAfter = createHook(
  hookName.afterMethod,
  /^(method)$/,
  ({ target, object, property, context, args, payload, meta }) => {
    //call your own hook
    console.log(
      `Instance of ${target.name} call "${property}"
with arguments ${args && args.length ? args : '[]'}
and return value is "${payload}" took ${performance.now() - meta.startTime}.`
    );
  }
);

const hooks = Object.assign({}, classHookBefore, classHookAfter);

aop(
  A,
  hooks
); // bind hook to class
const a = new A('my hook');

a.method(); // log: 'Instance of A call "method" with arguments [] and return value is "my hook".', returns: 'my hook'
a.notHookedClassMethod(); // returns: 'not hook'

unAop(A);
a.method(); // returns: 'my hook'
a.notHookedClassMethod(); // returns: 'not hook'

Applying AOP to instance or object
import { aop, hookName, createHook, unAop } from 'to-aop';
import A from './a';

const instanceHook = createHook(
  hookName.afterMethod,
  /^(method)$/,
  ({ target, object, property, context, args, payload, meta }) => {
    console.log(
      `Instance of ${object.constructor.name} call "${property}"
with arguments ${args && args.length ? args : '[]'}
and return value is "${payload}".`
    );
  }
);

const a = new A('my hook');
const hookedInstance = aop(a, instanceHook); // bind hook to instance

hookedInstance.method(); // log: 'Instance of A call "method" with arguments [] and return value is "my hook.', returns: 'my hook'
hookedInstance.notHookedClassMethod(); // returns: 'not hook'

unAop(a);
a.method(); // returns: 'my hook'
a.notHookedClassMethod(); // returns: 'not hook'

Documentation

createHook(hookName, regular, callbackHook)

  • (string) hookName - set of hooks
  • (string, regexp, Array, function) regular - condition for filtering
  • (function) callbackHook - your defined action

aop(target, pattern, settings)

  • (class, object) - target for hooks
  • (Object<string, Array>) - pattern of hooks
  • {Object} settings
  • {booelan} [settings.constructor=false] - allow hook class constructor

unAop(target)

  • (class, object) - target for hooks

Hooks API

We implemented base set of hooks which you can use for AOP.

  1. beforeMethod
  2. afterMethod
  3. aroundMethod
  4. beforeGetter
  5. afterGetter
  6. aroundGetter
  7. beforeSetter
  8. afterSetter
  9. aroundSetter
import { hookName } from 'to-aop';

// hookName.(beforeMethod|afterMethod|...)

Keywords

FAQs

Last updated on 06 Oct 2021

Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

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

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc