# make-it-hookable

> Create hookable methods in typescript

Latest version **3.0.0** (published 2016-12-15) · MIT license · 0 weekly downloads

## Install

```sh
npm install make-it-hookable
pnpm add make-it-hookable
yarn add make-it-hookable
bun add make-it-hookable
```

## Health

**Score 25/100 (F)** — status: abandoned.

Positive: has types; no vulnerabilities; high quality score.

Warnings: low downloads; no esm support.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 3.0.0 |
| Published | 2016-12-15 |
| First published | 2016-07-26 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | CommonJS |
| Dependencies | 2 |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 0 |
| Author | MedSolve |
| Maintainers | medsolve |
| Keywords | NodeJS, typescript |

## Links

- npm: https://www.npmjs.com/package/make-it-hookable
- Repository: https://github.com/MedSolve/make-it-hookable
- Homepage: https://github.com/MedSolve/make-it-hookable#readme
- Issues: https://github.com/MedSolve/make-it-hookalbe/issues
- npm.io page: https://npm.io/package/make-it-hookable

## Dependencies (2)

- [async](https://npm.io/package/async.md) ^2.1.4
- [es6-promise](https://npm.io/package/es6-promise.md) ^3.2.1

## Alternatives

- [@openai/codex-sdk](https://npm.io/package/@openai/codex-sdk.md) — 731.4K weekly downloads
- [babel-plugin-transform-react-jsx](https://npm.io/package/babel-plugin-transform-react-jsx.md) — 565.0K weekly downloads
- [babel-helper-remove-or-void](https://npm.io/package/babel-helper-remove-or-void.md) — 508.5K weekly downloads
- [@pnpm/store-controller-types](https://npm.io/package/@pnpm/store-controller-types.md) — 186.9K weekly downloads
- [react-native-signature-canvas](https://npm.io/package/react-native-signature-canvas.md) — 155.6K weekly downloads

## Recent versions

- 3.0.0 (latest) — 2016-12-15
- 1.3.1 — 2016-07-29
- 1.3.0 — 2016-07-29
- 1.2.0 — 2016-07-28
- 1.1.1 — 2016-07-28
- 1.1.0 — 2016-07-26
- 1.0.0 — 2016-07-26

## README

# Introduction: make-it-hookable
Create hookable methods in classes in TypeScript using this static _HookableComponent_ class.
There are four types of [generic](https://www.typescriptlang.org/docs/handbook/generics.html) hookables:

* Argumentable
* ArgumentableAll
* Returnable
* ReturnableAll

One should notice that the hookables is separated into: _Argumentable_ vs _Returnable_ and _All_ appended to their name or nothing appended to their name.

# The types of hookables
The aforementioned appendence are further described here. For the _All_ type it is possible to add three types of hooks: _pre_, _actor_ and _post_. When _nothing_ is added, only the _actor_ are. 

| Type        | Definition                                                          |
| ----------  | ----------------------------------------------                      |
| pre         | Manipulate the input parameters to the actors                       |
| actor       | Actors carrying out the intended functionality of a hookable method |
| post        | Manipulate the output of the actors                                 |

Notice that multiple pre and post hooks can be added for Returnable. Multiple pre, actor and post hooks can be added for Argumentable.

# Usage
To use this in your project and save it in the package.json file do:
`npm install make-it-hookable --save`

Please be aware that we use [semantic versioning](http://semver.org). This means that you should be able to safely subscribe to updates on this module for versions 1.x.x or 2.x.x etc. Major versions for example from 1.x.x to 2.x.x is not safe as the module API might change.

# The component
In order to create hookable method the static methods from the _HookableComponent_ should be used. These methods are described in the table below. Please notice something about the naming. Method _returnable_ returns a _Returnable_ model, _argumentableAll_ returns a _ArgumentableAll_ mode and so on.

| Method                | Returned model        |
| --------------------  | ------------------    | 
| returnable<T, U>      | Returnable<T,U>       |
| returnableAll<T, U>   | ReturnableAll<T,U>    |
| argumentable<T, U>    | Argumentable<T,U>     |
| argumentableAll<T, U> | ArgumentableAll<T,U>  |

Notice this about the generics, T and U:
* T: Type of input prams to hookable method
* U: Type of output from hookable method

All models in this project is exposed in _HookableModels_ in this module use as needed. 

# The returnable hookable model
The returnable model will return a es6-promise [Promise](https://github.com/stefanpenner/es6-promise) that is resolved once all hooks has been fired or rejected if anything goes wrong. 

## Models involved in returnable hooks
Here the models are described involving hookables that are returnable. Returnable hooks a asynchronous, so they should call a next function with some parameters when they are done and they want the next hook to be fired. The parameters for the hooks are here described and then the the parameters that should be given to the next functions are described.

| Hook Model           | Type  | Called with                                    | Returns    |
| -------------------- | ----- |----------------------------------------------- | ---------- |
| Returnable<T,U>      | actor | arg1 : T, next: ReturnableActorParams          | Promise<U> |
| ReturnableAll<T,U>   | pre   | arg1 : T, next: ReturnablePreParams            | Promise<U> |
|                      | actor | arg1 : T, next: ReturnableActorParams          |            |
|                      | post  | arg1 : T, arg2: U, next: ReturnablePostParams  |            |

The contents of the next functions are as follows:

| Next function               | Called with      |
| --------------------        | ---------------- | 
| ReturnableActorParams<T>    | arg1: T          |
| ReturnablePreParams<T>      | arg1: T          |
| ReturnableActorParams<T, U> | arg1: T, arg2: U |

## Example of returnable hooks

```typescript
import {HookableComponent, HookableModels}  from    'make-it-hookable';

/**
* Some class that has a hookable method
*/
class SomeHookableClass {
    /**
    * Create a hookable method that returns the number of a given animal
    * Output should here be a number and input should be a string
    */
    public hm: HookableModels.ReturnableAll<String, Number> = HookableComponent.returnableAll();
}

// create instance of class
let instance = new SomeHookableClass();

// create a pre hook
instance.hm.push((input: String, next: ReturnablePreParams<String>) => {
    
    // change value of input to allways be goat
    next('goat');
});

// create an actor
instance.hm.actor = (input: String, next: ReturnablePostParams<String, Number>) => {
    
    // change value of input to allways be goat
    next(input, 10);
};

// create an post hook
instance.hm.post.push((input: String, next: ReturnablePostParams<String, Number>) => {
    
    // increase the number to 20
    next(input, 20);
});

// run the method (async)
instance.hm('Cow').then((result: Number) => {

    // the content is returned here. (20 goats)
    console.log('There are: ' + result);
});

```

# The argumentable hookable model
The reason for this model to exists is to support the ability of creating hooks that can used with [express](http://expressjs.com). The basic idea here is that the type of the input and output are either some kind of objects or arrays.

## Models involved in argumentable hooks
When an argumentable hookable is used an initial array or object like variable is created and passed along the call to the hookable along with a callback _ArgumentableCb_ that is called once the all hooks are done. 

| Hook Model           | Type  | Called with                                    |
| -------------------- | ----- |----------------------------------------------- |
| Argumentable<T,U>    | actor | input : T, output: U, next: ArgumentableCb     |
| ArugmentableAll<T,U> | pre   | input : T, output: U, next: ArgumentableCb     |
|                      | actor | input : T, output: U, next: ArgumentableCb     |
|                      | post  | input : T, output: U, next: ArgumentableCb     |

The callback do not need any parameters as both the input and output are passed along the hooks as references (therefore object like or array like data types of these). It does however accept one input argument. This is to be understand as an error by the [express] framework and therefore also in this component.

## Example of argumentable hooks

```typescript
import {HookableComponent, HookableModels}  from    'make-it-hookable';
import * as express                         from    'express';

/**
* Some class that has a hookable method
*/
class SomeHookableClass {
    /**
    * Create a hookable method for express
    * Params should be objects or arrays
    */
    public hm: HookableModels.Argumentable<express.Request, express.Response> = HookableComponent.argumentable();
}

// create instance of class
let instance = new SomeHookableClass();

// create an actor
instance.hm.actor.push((req: express.Request, res: express.Response, cb: HookableModels.ArgumentableCb) => {
    
    // set some prop of response
    res.params.goat = true;

    // no errors is made
    cb();
});

// this would in express normally be invoked by an express router
let req: express.Request = {};
let res: express.Response = {};

instance.hm(req, res, (err: any) => {

    // do something about err if any?

    // otherwise perform action
    console.log('There are goats?: ' + res.params.goat);
});

```

# License
The MIT License (MIT)

---
_Source: https://npm.io/package/make-it-hookable · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
