Security News
Cloudflare Adds Security.txt Setup Wizard
Cloudflare has launched a setup wizard allowing users to easily create and manage a security.txt file for vulnerability disclosure on their websites.
@poppinss/hooks
Advanced tools
A no brainer module to execute lifecycle hooks in sequence.
I find myself re-writing the code for hooks in multiple packages, so decided to extract it to it's own module, that can be re-used by other modules of AdonisJS.
before
and after
calls with cleanup functions
The hooks class exposes the API to register
, remove
and exec
lifecycle hooks for any number of actions or events. The class API is meant to be used internally and not by the user facing code and this gives you the chance to improve the hooks DX.
For example: The Luciod models uses this internally and exposes the API to register lifecycle hooks around model actions like creating
, created
, deleting
, deleted
and so on.
Install the package from npm registry as follows:
npm i @poppinss/hooks@next
# yarn
yarn add @poppinss/hooks@next
Use it as follows
import { Hooks } from '@poppinss/hooks'
const hooks = new Hooks()
hooks.add('creating', function () {})
hooks.add('created', function () {})
const runner = hooks.runner('creating')
try {
await runner.run() // pass data here
} finally {
await runner.cleaup() // pass data here
}
before
and after
calls with cleanup functionsUsually hooks are modeled around before
and after
events. Also, the previous versions of this package also allowed registering before and after lifecycle hooks. However, I have recently removed support for that because of the following reasons.
The before
and after
lifecycle hooks will always be prone to errors. Let's consider the following scanerio.
We have the following before
hooks.
hooks.add('before', 'save', function () {
createTemporaryResource()
})
hooks.add('before', 'save', function () {
createAnotherTemporaryResource()
})
hooks.add('after', 'save', function () {
removeFirstTemporaryResource()
})
hooks.add('after', 'save', function () {
removeSecondTemporaryResource()
})
Now let's save the operation around which the lifecycle hooks were registered fails. Should we fire the after
hooks?
However, what happens if the second before hook fails? Now should we call all the after
hooks or not?
removeSecondTemporaryResource
may error out since its before
action was never completed.before
hook.As I mentioned earlier, the before
and after
hooks have no direct relationship and hence there is no correct way to call only the after
hooks for which the before
hooks completed successfully.
Therefore, by removing the concept of before
and after
and using cleanup functions, we will be able to design a more robust hooks system.
Now, in the following API, the hooks themselves are responsible for returning the cleanup functions.
If the second hook fails, then we will only call the cleanup function for the first hook.
hooks.add('save', function () {
createTemporaryResource()
return removeFirstTemporaryResource
})
hooks.add('save', function () {
createAnotherTemporaryResource()
return removeSecondTemporaryResource
})
You can pass data to hooks at the time of running the run
and the cleanup
functions. For example.
import { Hooks } from '@poppinss/hooks'
const hooks = new Hooks()
hooks.add('creating', function (arg1, arg2, arg3) {})
hooks.add('creating', function (arg1, arg2, arg3) {})
hooks.add('creating', function (arg1, arg2, arg3) {})
const runner = hooks.runner('creating')
await runner.run('arg1', 'arg2', 'arg3')
It is usually helpful to inform the cleanup functions if there was an error or not. Maybe some cleanup functions may not to run only in case of errors.
const hooks = new Hooks()
hooks.add('creating', function (model) {
const file = await saveFileToDisk()
model.filePath = file
return (error, model) => {
if (error) {
await removeFileFromDisk(model.filePath)
}
}
})
const runner = hooks.runner('creating')
try {
// Run hooks
await runner.run(model)
// Run the actual action
await model.save()
} catch (error) {
// During error
await runner.cleaup(error, model)
}
/**
* During success
*/
if (runner.isCleanupPending) {
await runner.cleaup(null, model)
}
FAQs
A no brainer hooks module for execute before/after lifecycle hooks
The npm package @poppinss/hooks receives a total of 40,372 weekly downloads. As such, @poppinss/hooks popularity was classified as popular.
We found that @poppinss/hooks demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
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.
Security News
Cloudflare has launched a setup wizard allowing users to easily create and manage a security.txt file for vulnerability disclosure on their websites.
Security News
The Socket Research team breaks down a malicious npm package targeting the legitimate DOMPurify library. It uses obfuscated code to hide that it is exfiltrating browser and crypto wallet data.
Security News
ENISA’s 2024 report highlights the EU’s top cybersecurity threats, including rising DDoS attacks, ransomware, supply chain vulnerabilities, and weaponized AI.