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 🙏

© 2025 – Pkg Stats / Ryan Hefner

azure-functions-essentials

v1.0.3

Published

Essential utilities for Azure Functions

Readme

⚡ Azure Functions Essentials

Your go to library for building Azure Functions with TypeScript!

A magical TypeScript utility belt for Azure Functions developers who are tired of writing the same boilerplate code over and over again. This library will make your functions more readable, maintainable, and less prone to "It works on my machine" syndrome.

🚀 Installation

npm install azure-functions-essentials

or if you're feeling yarn-ish

yarn add azure-functions-essentials

✨ Features

🔗 Function Chains

Chain your function logic like a boss. Found a guard or an input that should be reused in other functions? Declare as a const and reuse the logic!

import { startChain, guard, funcResult, inputFactory } from 'azure-functions-essentials';

// Create an input binding for user lookup with your fancy database call
const userLookup = inputFactory<string, User>('user', userId => getUserFromDatabase(userId));

// Make sure they have the magic password
const keyGuard = guard(req => req.headers.get('x-api-key') === 'secret' || funcResult('Forbidden', 'Nice try, hacker!'));

// Make sure the user is a ninja (Guard functor pattern)
const ninjaGuard = (user: User) => guard(() => user.isNinja || funcResult('Forbidden', 'Only 🥷s are allowed!'));

app.post('super-secret-endpoint', {
  handler: startChain()
    .useGuard(keyGuard) // Use a guard (or several?)
    .parseBody(myZodSchema) // Parse the body and (optionally) validate with Zod
    .useInputBinding(({ body }) => userLookup.create(body.user.id)) // Initialize the input
    .useGuard(({ context }) => ninjaGuard(userLookup.get(context))) // Use input results in the chain
    // Handle the request with all goodies available
    .handle((req, body, ctx) => {
      const user = userLookup.get(ctx); // Get the user from our input

      // Your incredibly important business logic here

      // Return a result with the funcResult helper
      return funcResult('OK', {
        message: `You're in ${user.name}! Here's your cookie 🍪`,
        userData: user,
        requestData: body,
      });
    }),
});

🛡️ Guards

For more details and the list of built-in guards, check out the Guards Documentation.

Keep the bad guys out:

const isAdminGuard = guard((req, ctx) => {
  const user = ctx.extraInputs.get('user');
  return user.role === 'admin' || funcResult('Forbidden', 'You shall not pass! 🧙‍♂️');
});

🎯 Input Bindings

Because more inputs means more fun:

const userLookup = inputFactory<string, User>('user', async userId => {
  // Imagine some fancy database call here
  return { id: userId, name: 'Function Fanatic', role: 'wizard' };
});

// Later in your chain...
.useInputBinding(({ request }) => userLookup.create(request.params.userId))

🧩 Query Parameters

Parse query params without pulling your hair out:

import { getQuery, getQueryFlag } from 'azure-functions-essentials';

const limit = getQuery(request, 'limit'); // Will throw if missing
const page = getQuery(request, 'page', true); // Optional, returns null if missing
const includeDeleted = getQueryFlag(request, 'includeDeleted'); // Boolean flags made easy

🤔 Why Use This Library?

  1. Less Code: Why write 100 lines when 10 will do?
  2. Type Safety: TypeScript all the things!
  3. Testability: Every component is designed to be easily testable
  4. Chain of Responsibility: Handle authentication, validation, and business logic in a clean, readable way
  5. Consistent Responses: No more forgetting to set the right status code

📚 Documentation

For more examples of our wizardry, check out these magical spells:

Creating Guards

Regular Guards

Guards can directly check headers, query parameters, or any request property:

// Simple header-based authentication guard
const apiKeyGuard = guard((req, ctx) => {
  const apiKey = req.headers.get('x-api-key');
  return apiKey === process.env.API_KEY || funcResult('Unauthorized', 'Invalid API key');
});

// Usage in chain
startChain()
  .useGuard(apiKeyGuard)
  .handle((req, ctx) => {
    // Only executed if API key is valid
    return funcResult('OK', 'Access granted!');
  });

Functor Pattern Guards

Guards can also be created on-the-fly with the functor pattern, allowing you to pass in parameters:

type BodyType = { name: string; age: number };

// Guard factory that validates a specific property in the body
const validateBody = (body: BodyType) => guard((req, ctx) => body.age < 18 || funcResult('BadRequest', `Age must be at least 18 years old`));

// Usage with parsed body
startChain()
  .parseBody<BodyType>()
  .useGuard(({ body }) => validateBody(body)) // Pass the body to validateBody
  .handle((req, body, ctx) => {
    // Only executed if the body validator is passed
    return funcResult('OK', `Welcome, ${body.name}!`);
  });

Combined Guards with useAnyGuard

In some scenarios, it is enough for just one of the guards to pass. For example, admins are allowed to edit any resource, while regular users can only edit their own resources.

const combinedGuard = anyGuard(isAdminGuard, hasPermissionGuard('CAN_EDIT'), isResourceOwnerGuard);

Body Validation with Zod

const userSchema = z.object({
  name: z.string().min(2),
  email: z.string().email("That doesn't look like an email to me 🤨"),
  age: z.number().min(18).optional(),
});

startChain()
  .parseBody(userSchema)
  .handle((req, body, ctx) => {
    // body is typed and validated!
  });

🤝 Contributing

Pull requests are welcome! Fork it and PR away!

📝 License

MIT License - Use it, abuse it, but please give credit where it's due.