Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support passing AwilixContainer explicitly #126

Merged
merged 2 commits into from
Feb 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 10 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
[![NPM Version][npm-image]][npm-url]
[![Build Status](https://github.com/fastify/fastify-awilix/workflows/ci/badge.svg)](https://github.com/fastify/fastify-awilix/actions)

Dependency injection support for fastify framework, using [awilix](https://github.com/jeffijoe/awilix)
Dependency injection support for fastify framework, using [awilix](https://github.com/jeffijoe/awilix).

## Getting started

Expand All @@ -26,7 +26,11 @@ app.register(fastifyAwilixPlugin, { disposeOnClose: true, disposeOnResponse: tru
Then, register some modules for injection:

```js
const { diContainer } = require('@fastify/awilix')
const {
diContainer, // this is an alias for diContainerProxy
diContainerClassic, // this instance will be used for `injectionMode = 'CLASSIC'`
diContainerProxy // this instance will be used by default
} = require('@fastify/awilix')
const { asClass, asFunction, Lifetime } = require('awilix')

// Code from the previous example goes here
Expand Down Expand Up @@ -74,6 +78,10 @@ app.post('/', async (req, res) => {

## Plugin options

`injectionMode` - whether to use PROXY or CLASSIC injection mode. See [awilix documentation](https://www.npmjs.com/package/awilix#injection-modes) for details. Default is 'PROXY'.

`container` - pre-created AwilixContainer instance that should be used by the plugin. By default plugin uses its own instance. Note that you can't specify both `injectionMode` and `container` parameters at the same time.

`disposeOnClose` - automatically invoke configured `dispose` for app-level `diContainer` hooks when the fastify instance is closed.
Disposal is triggered within `onClose` fastify hook.
Default value is `true`
Expand Down Expand Up @@ -178,18 +186,6 @@ await app.register(fastifyAwilixPlugin, { asyncInit: true, asyncDispose: true, e
await app.ready()
```

## Using classic injection mode

If you prefer [classic injection](https://github.com/jeffijoe/awilix#injection-modes), you can use it like this:

```javascript
const { fastifyAwilixPlugin } = require('@fastify/awilix/lib/classic')
const fastify = require('fastify')

app = fastify({ logger: true })
app.register(fastifyAwilixPlugin, { disposeOnClose: true, disposeOnResponse: true })
```

## Advanced DI configuration

For more advanced use-cases, check the official [awilix documentation](https://github.com/jeffijoe/awilix)
Expand Down
1 change: 0 additions & 1 deletion lib/classic/index.d.ts

This file was deleted.

70 changes: 0 additions & 70 deletions lib/classic/index.js

This file was deleted.

30 changes: 25 additions & 5 deletions lib/fastifyAwilixPlugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,31 @@ const awilix = require('awilix')
const { AwilixManager } = require('awilix-manager')
const fp = require('fastify-plugin')

const diContainer = awilix.createContainer({
const diContainerProxy = awilix.createContainer({
injectionMode: 'PROXY',
})

const diContainerClassic = awilix.createContainer({
injectionMode: 'CLASSIC',
})

function plugin(fastify, opts, next) {
if (opts.container && opts.injectionMode) {
return next(
new Error(
'If you are passing pre-created container explicitly, you cannot specify injection mode',
),
)
}

const resolvedContainer = opts.container
? opts.container
: opts.injectionMode === 'CLASSIC'
? diContainerClassic
: diContainerProxy

const awilixManager = new AwilixManager({
diContainer,
diContainer: resolvedContainer,
asyncDispose: opts.asyncDispose,
asyncInit: opts.asyncInit,
eagerInject: opts.eagerInject,
Expand All @@ -19,11 +37,11 @@ function plugin(fastify, opts, next) {
const disposeOnClose = opts.disposeOnClose === true || opts.disposeOnClose === undefined

fastify.decorate('awilixManager', awilixManager)
fastify.decorate('diContainer', diContainer)
fastify.decorate('diContainer', resolvedContainer)
fastify.decorateRequest('diScope', null)

fastify.addHook('onRequest', (request, reply, done) => {
request.diScope = diContainer.createScope()
request.diScope = resolvedContainer.createScope()
done()
})

Expand Down Expand Up @@ -65,6 +83,8 @@ const fastifyAwilixPlugin = fp(plugin, {
})

module.exports = {
diContainer,
diContainer: diContainerProxy,
diContainerProxy,
diContainerClassic,
fastifyAwilixPlugin,
}
4 changes: 4 additions & 0 deletions lib/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ declare module 'fastify' {
export type FastifyAwilixOptions = {
disposeOnResponse?: boolean
disposeOnClose?: boolean
injectionMode?: 'PROXY' | 'CLASSIC'
container?: AwilixContainer<Cradle>
asyncInit?: boolean
asyncDispose?: boolean
eagerInject?: boolean
Expand All @@ -28,3 +30,5 @@ export type FastifyAwilixOptions = {
export const fastifyAwilixPlugin: FastifyPluginCallback<NonNullable<FastifyAwilixOptions>>

export const diContainer: AwilixContainer<Cradle>
export const diContainerClassic: AwilixContainer<Cradle>
export const diContainerProxy: AwilixContainer<Cradle>
9 changes: 8 additions & 1 deletion lib/index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
'use strict'

const { diContainer, fastifyAwilixPlugin } = require('./fastifyAwilixPlugin')
const {
diContainer,
fastifyAwilixPlugin,
diContainerProxy,
diContainerClassic,
} = require('./fastifyAwilixPlugin')

module.exports = {
diContainer,
diContainerClassic,
diContainerProxy,
fastifyAwilixPlugin,
}
8 changes: 6 additions & 2 deletions lib/index.test-d.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import { asValue, AwilixContainer } from 'awilix'
import fastify, { FastifyInstance } from 'fastify'
import { diContainer, FastifyAwilixOptions, fastifyAwilixPlugin, Cradle, RequestCradle } from './index'
import { diContainer as diContainerClassic } from './classic'
import { diContainer, diContainerClassic, FastifyAwilixOptions, fastifyAwilixPlugin, Cradle, RequestCradle } from './index'

import { expectAssignable, expectNotType, expectType } from 'tsd'

expectAssignable<FastifyAwilixOptions>({})
expectAssignable<FastifyAwilixOptions>({ disposeOnClose: false })
expectAssignable<FastifyAwilixOptions>({ container: diContainer })
expectAssignable<FastifyAwilixOptions>({ container: diContainerClassic })
expectAssignable<FastifyAwilixOptions>({ injectionMode: 'CLASSIC' })
expectAssignable<FastifyAwilixOptions>({ injectionMode: 'PROXY' })

expectAssignable<FastifyAwilixOptions>({ disposeOnResponse: false })
expectAssignable<FastifyAwilixOptions>({ asyncInit: false, asyncDispose: false })
expectAssignable<FastifyAwilixOptions>({ asyncInit: true, asyncDispose: true })
Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,11 @@
"@types/node": "^20.8.6",
"awilix": "^10.0.1",
"eslint": "^8.51.0",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-prettier": "^5.0.1",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.1.3",
"fastify": "^4.24.2",
"jest": "^29.7.0",
"prettier": "^3.0.3",
"prettier": "^3.2.5",
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

new prettier formats nested ternaries in a nicer way

"tsd": "^0.30.0"
},
"homepage": "http://github.com/fastify/fastify-awilix",
Expand Down
36 changes: 19 additions & 17 deletions test/awilixManager.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,7 @@

const { asClass } = require('awilix')
const fastify = require('fastify')
const { diContainer, fastifyAwilixPlugin } = require('../lib')

const {
diContainer: diContainerClassic,
fastifyAwilixPlugin: fastifyAwilixPluginClassic,
} = require('../lib/classic')
const { diContainer, diContainerClassic, fastifyAwilixPlugin } = require('../lib')

let isInittedGlobal = false
let isDisposedGlobal = false
Expand All @@ -32,20 +27,18 @@ class AsyncInitSetClass {

const variations = [
{
name: 'PROXY',
plugin: fastifyAwilixPlugin,
injectionMode: 'PROXY',
container: diContainer,
},
{
name: 'CLASSIC',
plugin: fastifyAwilixPluginClassic,
injectionMode: 'CLASSIC',
container: diContainerClassic,
},
]

describe('awilixManager', () => {
variations.forEach((variation) => {
describe(variation.name, () => {
describe(variation.injectionMode, () => {
let app
beforeEach(() => {
isInittedGlobal = false
Expand All @@ -66,10 +59,13 @@ describe('awilixManager', () => {
asClass(InitSetClass, {
lifetime: 'SINGLETON',
eagerInject: true,
})
}),
)
app = fastify({ logger: false })
await app.register(variation.plugin, { eagerInject: true })
await app.register(fastifyAwilixPlugin, {
eagerInject: true,
injectionMode: variation.injectionMode,
})
await app.ready()

expect(isInittedGlobal).toBe(true)
Expand All @@ -81,10 +77,13 @@ describe('awilixManager', () => {
asClass(AsyncInitSetClass, {
lifetime: 'SINGLETON',
asyncInit: 'init',
})
}),
)
app = fastify({ logger: false })
await app.register(variation.plugin, { asyncInit: true })
await app.register(fastifyAwilixPlugin, {
asyncInit: true,
injectionMode: variation.injectionMode,
})
await app.ready()

expect(isInittedGlobal).toBe(true)
Expand All @@ -96,10 +95,13 @@ describe('awilixManager', () => {
asClass(AsyncInitSetClass, {
lifetime: 'SINGLETON',
asyncDispose: 'dispose',
})
}),
)
app = fastify({ logger: false })
await app.register(variation.plugin, { asyncDispose: true })
await app.register(fastifyAwilixPlugin, {
asyncDispose: true,
injectionMode: variation.injectionMode,
})
await app.ready()
await app.close()

Expand Down
Loading
Loading