npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@autotelic/fastify-injector

v0.3.0

Published

A testing util for injecting Fastify plugin dependencies.

Downloads

809

Readme

Fastify Injector

A testing util for injecting plugin dependencies into a Fastify app.

Contents

Usage

npm i --save-dev @autotelic/fastify-injector
const { test } = require('tap')
const fastifyInjector = require('@autotelic/fastify-injector')

const rootPlugin = require('../index.js')

test('root plugin', async ({ is }) => {
  const injectFoo = () => 'bar'
  const app = fastifyInjector({ requestDecorators: { foo: injectFoo } })
  // If the rootPlugin, or one of its child plugins adds a requestDecorator with the
  // name 'foo', injectFoo will be added in place of the original decorator value.
  app.register(rootPlugin)
  await app.ready()
  const result = await app.inject({
    method: 'GET',
    url: '/'
  })
  is(result.statusCode, 200)
})

API

fastifyInjector

fastifyInjector is a function that accepts an options object and a Fastify instance (optional - defaults to require('fastify')()). It returns a proxied Fastify instance that will inject the specified decorators and plugins if/when their targets are added to the instance.

Options

The fastifyInjector options object contains the following properties:

  • decorators: { [decoratorName]: decorator } - An object containing all decorators to be injected. The keys for each decorator must match the name of the decorator to be replaced.

  • requestDecorators: { [requestDecoratorName]: requestDecorator } - An object containing all request decorators to be injected. The keys for each request decorator must match the name of the request decorator to be replaced.

  • replyDecorators: { [replyDecoratorName]: replyDecorator } - An object containing all reply decorators to be injected. The keys for each reply decorator must match the name of the reply decorator to be replaced.

  • plugins: { [pluginName]: plugin } - An object containing all plugins to be injected. The keys for each plugin must match the name of the plugin to be replaced. For this to work, the original plugin must either have the Symbol.for('fastify.display-name') property (ie. use fastify-plugin and provide a name) or be a named function (ie. have the Function.name property) - if the plugin has both, Symbol.for('fastify.display-name') will be used.

Decorators

loadFixtures

The Fastify instance returned by fastifyInjector provides access to a loadFixtures decorator. This can be used to autoload one or more plugin directories. It accepts a string path or a fastify-autoload config, or an Array containing either/both.

const app = fastifyInjector({ replyDecorators: { myDecorator: myDecoratorStub } })

app.register(myPlugin)

app.loadFixtures([
  path.join(__dirname, '../fixtures/routes'),
  {
    dir: path.join(__dirname, 'plugins'),
    maxDepth: 2
  }
])

await app.ready()

// Test stuff...

Features

Passthrough Functionality

All injected decorator functions and plugins are provided access to the function they are replacing. The original functions are added to their replacements as the Symbol.for('call-original') property.

const { test } = require('tap')
const fastifyInjector = require('@autotelic/fastify-injector')

const rootPlugin = require('../index.js')

test('root plugin', async ({ is }) => {
  const fooCalls = []

  function injectFoo (...args) {
    fooCalls.push(args)
    // Note: if the original decorator uses `this` to access the request/reply/instance
    // you will need to bind it -> `injectFoo[Symbol.for('call-original')].bind(this)`
    const originalFoo = injectFoo[Symbol.for('call-original')]
    return originalFoo(...args)
  }

  const app = fastifyInjector({ requestDecorators: { foo: injectFoo } })
  app.register(rootPlugin)
  await app.ready()
  const result = await app.inject({
    method: 'GET',
    url: '/'
  })
  is(fooCalls.length, 3)
})
Plugin Properties

When injecting plugins - if the original plugin's Symbol.for('skip-override') property is true, then that property along with any other property added by fastify-plugin will be applied to the injected plugin.

Plugin Encapsulation

If an app uses the same plugin or decorator names across multiple encapsulation contexts, then only the first occurrence of that plugin/decorator will be injected. If possible, we recommend testing each context in isolation.