Skip to content

Commit 0d5fa0d

Browse files
committed
Add hooks api docs
1 parent 0b8bf72 commit 0d5fa0d

File tree

7 files changed

+479
-1
lines changed

7 files changed

+479
-1
lines changed

_includes/docs-content.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{% include header.html %}
22
<div class="docs">
33
{% include breadcrumbs.html %}
4-
<div class="grid">
4+
<div class="grid" style="padding-bottom: 50px">
55
{% if page.toc %}
66
<div id="toc-column" class="col-3-12">
77
{% include {{ page.toc }} %}

_includes/toc-api-hooks.html

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<ul class="toc">
2+
<li class="toc-expander">V</li>
3+
<li class="tocheader">
4+
<ul>
5+
<li class="{% if page.url == "/docs/api/hooks/" %} active{% endif %}"><a href="/docs/api/hooks/">Runtime Hooks API</a>
6+
<li><a style="text-decoration: none !important; font-weight: bold">Hooks</a></li>
7+
<li {% if page.url contains "/docs/api/hooks/messaging" %}class="active"{% endif %}><a href="/docs/api/hooks/messaging">Messaging</a>
8+
<li {% if page.url contains "/docs/api/hooks/install" %}class="active"{% endif %}><a href="/docs/api/hooks/install">Node Install</a>
9+
</ul>
10+
</li>
11+
</ul>
12+
<script>
13+
$(function() {
14+
var pageToc = $("<ul></ul>").appendTo(".toc li.active:not(.toctitle)");
15+
$(".docs-content h3,.docs-content h4").each(function() {
16+
17+
if ($(this)[0].nodeName === 'H3') {
18+
$('<li id="toc-item-'+$(this).attr('id')+'"><a style="font-size: 0.95em; padding-left: 45px;" href="#'+$(this).attr('id')+'">'+$(this).text()+'</a></li>').appendTo(pageToc)
19+
} else {
20+
$('<li id="toc-item-'+$(this).attr('id')+'"><a style="font-size: 0.9em; padding-left: 55px;" href="#'+$(this).attr('id')+'">'+$(this).text()+'</a></li>').appendTo(pageToc)
21+
}
22+
})
23+
})
24+
</script>

docs/api/hooks/index.md

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
---
2+
layout: docs-api
3+
toc: toc-api-hooks.html
4+
title: Hooks API
5+
slug: hooks
6+
---
7+
8+
The Hooks API provides a way to insert custom code into certain key points of
9+
the runtime operation.
10+
11+
*Note: there is also a hooks api in the editor, but it is less mature so
12+
not currently documented for general use.*
13+
14+
15+
- [`RED.hooks` API](#redhooks-api)
16+
- [`RED.hooks.add( hookName, handlerFunction )`](#methods-add)
17+
- [`RED.hooks.remove( hookName )`](#methods-remove)
18+
19+
- [Messaging Hooks](messaging) - add code to the message routing path.
20+
- [Node Install Hooks](install) - how modules are installed (or uninstalled) by the runtime.
21+
22+
23+
### `RED.hooks` API
24+
25+
#### <a href="#methods-add" name="methods-add">RED.hooks.add( hookName, handlerFunction )</a>
26+
27+
Register a new hook handler.
28+
29+
The `hookName` is the name of the hook to register the handler for.
30+
31+
It can be optionally suffixed with a label for the hook - `onSend.my-hooks`.
32+
That label can then be used with `RED.hooks.remove` to remove the handler.
33+
34+
35+
When invoked, the hook handler will be called with a single payload object - the details
36+
of which will be specific to the hook.
37+
38+
The handler can take an optional second argument - a callback function to call
39+
when the handler has finished its work.
40+
41+
When the handler finishes its work it must either:
42+
- return normally
43+
- call the callback function with no arguments
44+
- return a promise that resolves
45+
46+
Any modifications it has made to the payload object will be passed on.
47+
48+
If the handler wants to stop further processing of the event (for example, it does
49+
would not want a message to be passed to the next node in a flow), it must either:
50+
- return `false` (strictly `false` - not a false-like value)
51+
- call the callback function with `false`
52+
- return a promise that resolves with the value `false`.
53+
54+
If the handler encounters an error that should be logged it must either:
55+
- throw an Error
56+
- call the callback function with the Error
57+
- return a promise that rejects with the Error
58+
59+
If a function is defined as the two-argument version (accepting the callback function),
60+
it *must* use that callback - any value it returns will be ignored.
61+
62+
```javascript
63+
RED.hooks.add("preDeliver.my-hooks", (sendEvent) => {
64+
console.log(`About to deliver to ${sendEvent.destination.id}`);
65+
});
66+
```
67+
68+
#### <a href="#methods-remove" name="methods-remove">RED.hooks.remove( hookName )</a>
69+
70+
Remove a hook handler.
71+
72+
Only handlers that were registered with a labelled name (for example `onSend.my-hooks`) can be removed.
73+
74+
To remove all hooks with a given label, `*.my-hooks` can be used.
75+
76+
77+
```javascript
78+
RED.hooks.remove("*.my-hooks");
79+
```

docs/api/hooks/install/index.md

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
---
2+
layout: docs-api
3+
toc: toc-api-hooks.html
4+
title: Node Install Hooks
5+
slug:
6+
- url: "/docs/api/hooks"
7+
label: "hooks"
8+
- 'install'
9+
---
10+
11+
The Node Install Hooks allow custom code to be added around the installation of
12+
new npm modules - for both Nodes and External modules.
13+
14+
- Hooks
15+
- [preInstall](#preinstall)
16+
- [postInstall](#postinstall)
17+
- [preUninstall](#preuninstall)
18+
- [postUninstall](#postuninstall)
19+
- Event Objects
20+
- [InstallEvent](#installevent-object)
21+
- [UninstallEvent](#uninstallevent-object)
22+
23+
### Hooks
24+
25+
#### `preInstall`
26+
27+
Called before running `npm install` to install an npm module.
28+
29+
The hook is passed an `InstallEvent` object that contains information about the
30+
module to be installed.
31+
32+
```json
33+
{
34+
"module": "<npm module name>",
35+
"version": "<version to be installed>",
36+
"url": "<optional url to install from>",
37+
"dir": "<directory to run the install in>",
38+
"isExisting": "<boolean> this is a module we already know about",
39+
"isUpgrade": "<boolean> this is an upgrade rather than new install",
40+
"args": [ "an array", "of the args", "that will be passed to npm"]
41+
}
42+
```
43+
44+
The hook can modify the InstallEvent to change how npm is run. For example,
45+
the `args` array can be modified to change what arguments are passed to `npm`.
46+
47+
If the hook returns `false`, the `npm install` will be skipped and the processing
48+
continue as if it had been run. This would allow some alternative mechanism
49+
to be used - as long as it results in the module being installed under the expected
50+
`node_modules` directory.
51+
52+
If the hook throws an error, the install will be cleanly failed.
53+
54+
```javascript
55+
RED.hooks.add("preInstall", (installEvent) => {
56+
console.log(`About to install ${installEvent.module}@${installEvent.version}`);
57+
});
58+
```
59+
60+
#### `postInstall`
61+
62+
Called after `npm install` finishes installing an npm module.
63+
64+
*Note* if a `preInstall` hook returned `false`, `npm install` will not have been
65+
run, but this hook will still get invoked.
66+
67+
This hook can be used to run any post-install activity needed.
68+
69+
For example, when running in an Electron environment, it is necessary to rebuild
70+
the module:
71+
72+
```javascript
73+
RED.hooks.add("postInstall", (installEvent, done) => {
74+
child_process.exec("npm run rebuild " + installEvent.module,
75+
{cwd: installEvent.dir},
76+
(err, stdout, stderr) => {
77+
done();
78+
}
79+
);
80+
});
81+
```
82+
83+
If the hook throws an error, the install will be cleanly failed.
84+
85+
If the preceding `npm install` returned an error, this hook will not be invoked.
86+
87+
88+
#### `preUninstall`
89+
90+
Called before running `npm remove` to uninstall an npm module.
91+
92+
The hook is passed an `UninstallEvent` object that contains information about the
93+
module to be removed.
94+
95+
```json
96+
{
97+
"module": "<npm module name>",
98+
"dir": "<directory to run the remove in>",
99+
"args": [ "an array", "of the args" , "we will pass to npm"]
100+
}
101+
```
102+
103+
The hook can modify the UninstallEvent to change how npm is run. For example,
104+
the `args` array can be modified to change what arguments are passed to `npm`.
105+
106+
If the hook returns `false`, the `npm remove` will be skipped and the processing
107+
continue as if it had been run. This would allow some alternative mechanism
108+
to be used.
109+
110+
If the hook throws an error, the uninstall will be cleanly failed.
111+
112+
113+
```javascript
114+
RED.hooks.add("preUninstall", (uninstallEvent) => {
115+
console.log(`About to remove ${uninstallEvent.module}`);
116+
});
117+
```
118+
119+
#### `postUninstall`
120+
121+
Called after `npm remove` finishes removing an npm module.
122+
123+
*Note* if a `preUninstall` hook returned `false`, `npm remove` will not have been
124+
run, but this hook will still get invoked.
125+
126+
This hook can be used to run any post-uninstall activity needed.
127+
128+
If the hook throws an error, it will be logged, but the uninstall will complete
129+
cleanly as we cannot rollback an `npm remove` after it has completed.
130+
131+
132+
```javascript
133+
RED.hooks.add("postUninstall", (uninstallEvent) => {
134+
console.log(`Removed ${uninstallEvent.module}`);
135+
});
136+
```
137+
138+
### Event Objects
139+
140+
#### `InstallEvent` object
141+
142+
```json
143+
{
144+
"module": "<npm module name>",
145+
"version": "<version to be installed>",
146+
"url": "<optional url to install from>",
147+
"dir": "<directory to run the install in>",
148+
"isExisting": "<boolean> this is a module we already know about",
149+
"isUpgrade": "<boolean> this is an upgrade rather than new install",
150+
"args": [ "an array", "of the args", "we will pass to npm"]
151+
}
152+
```
153+
154+
#### `UninstallEvent` object
155+
156+
```json
157+
{
158+
"module": "<npm module name>",
159+
"dir": "<directory to run the remove in>",
160+
"args": [ "an array", "of the args", "we will pass to npm"]
161+
}
162+
```

0 commit comments

Comments
 (0)