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

@foundryapp/foundry-backend

v2.0.0

Published

Foundry Node.js SDK

Readme

Foundry Node.js SDK

This SDK lets you write

Table of contents

Installation

$ npm install --save @foundryapp/foundry-backend

Example

  1. Add Foundry backend SDK to your Cloud Functions project
const functions = require('firebase-functions');
const admin = require('firebase-admin');
// Import Foundry
const foundry = require('@foundryapp/foundry-backend').firebase;

admin.initializeApp();

// Fill in the emulated auth users
foundry.users.add([
  {
    id: 'user-id-1',
    data: { email: '[email protected]' },
  },
]);

// Fill in the emulated Firestore
foundry.firestore.collection('posts').addDocs([
  {
    id: 'post-doc-id-1',
    data: {
      ownerId: 'user-id-1',
      content: 'Hello World!',
    },
  },
]);

/////////

// Register 'myCloudFunc' with Foundry
// The name under which your cloud function is registered
// with Foundry must be the same under which you export
// your cloud function
const createPost = foundry.functions.httpsCallable.register('createPost');

// Now specify how Foundry should trigger your function
createPost.triggerAsUser('user-id-1').onCall({ 
  data: {
    content: 'Content of a new post',    
  },
});

// Cloud Function for creating posts
exports.createPost = functions.https.onCall(async (data, context) => {
  if (!context.auth) {
    throw new functions.https.HttpsError('permission-denied', 'User isn\'t authenticted');
  }
  
  const { uid } = context.auth;
  await admin.firestore().collection('posts').add({
    ownerId: uid,
    content: data.content,
  });
});

/////////

const getPosts = foundry.functions.httpsCallable.register('getPosts');
getPosts.triggerAsUser('user-id-1').onCall();

// Cloud Function for retrieving all user's posts
exports.getPosts = functions.https.onCall(async (data, context) => {
  if (!context.auth) {
    throw new functions.https.HttpsError('permission-denied', 'User isn\'t authenticted');
  }
  
  const { uid } = context.auth;
  const posts = await admin.firestore().collection('posts').where('ownerId', '==', uid).get();
  return posts.docs.map(d => d.data());
});
  1. Start Foundry CLI in the same directory where are your Cloud Functions
$ foundry go

Now every time you save your local code files Foundry will trigger your cloud functions as you specified in the code. The output from Foundry in your terminal will look like this:

[1] createPost
response => {
  data: null,
  status: 200,
  statusText: 'OK'
}

[1] getPosts
response => {
  data: [
    {
      ownerId: 'user-id-1',
      content: 'Content of a new post'
    },
    {
      ownerId: 'user-id-1',
      content: 'Hello World!'
    }
  ],
  status: 200,
  statusText: 'OK'
}

Usage

Fill in emulated Auth users

// Specify users explicitely
foundry.users.add([
  {
    id: 'user-id-1',
    data: { email: '[email protected]' },
  },
]);

// Copy the first 5 users from your production Firebase app
foundry.users.copyFromProdByCount(5);

// Copy users from your production Firebase app by their IDs
foundry.users.copyFromProdById(['user-prod-id-1', 'user-prod-id-2']);

Fill in emulated Firestore

// Specify documents explicitely
foundry.firestore.collection('posts').addDocs([
  {
    id: 'post-doc-id-1',
    data: {
      ownerId: 'user-id-1',
      content: 'Hello World!',
    },
  },
]);

// Copy documents from the production

// Takes the first 5 docs from collection 'posts' in the production
foundry.firestore.collection('posts').copyDocsFromProdByCount(5); 
// Copy docs from the production by their IDs
foundry.firestore.collection('posts').copyDocsFromProdById(['prod-doc-id-1', 'prod-doc-id-2']); 

Fill in emulated RealtimeDB

// Specify refs explicitely
foundry.database.ref('posts').addChildren([
  {
    key: 'post-1',
    data: {
      ownerId: 'user-id-1',
      content: 'Hello World!',
    },
  },
]);

// Copy directly from the production
foundry.database.ref('posts').copyAllChildrenFromProd();
foundry.database.ref('posts').copyChildrenFromProdByKey(['prod-key-1', 'prod-key-2']);

Register function

const funcFirestore = firebase.functions.firestore.register('funcFirestore');
const funcDatabase = firebase.functions.database.register('funcDatabase');
const funcAuth = firebase.functions.auth.register('funcAuth');
const funcHttps = firebase.functions.https.register('funcHttps');
const funcHttpsCallable = firebase.functions.httpsCallable.register('funcHttpsCallable');

// To get a reference of a previously registered function
const func = firebase.functions.firestore.get('functionName');

Describe function triggers

Firestore function

// New document will be created in the emulated Firestore that will trigger the function
funcFirestore.trigger().onCreate({
  collection: 'posts',
  id: 'post-doc-id-1',
  data: {
    content: 'My post content',
  },
});

// Document with the ID 'post-doc-id-1' in the collection 'posts' 
// will be deleted from the emulated Firestore
funcFirestore.trigger().onDelete('posts', 'post-doc-id-1');

// Specified document in the emulated Firestore will be updated
funcFirestore.trigger().onUpdate({
  collection: 'posts',
  id: 'post-doc-id-1',
  data: {
    content: 'New content',
  },
});

// Trigger the function by copying a specified document to the emulated Firestore
funcFirestore.triggerWithProdData().onCreate('posts', 'prod-post-doc-id');

RealtimeDB function

// Creates a new reference in the emulated RealtimeDB and triggers the function
funcDatabase.trigger().onCreate({
  refPath: 'ref/path',
  data: { ... },
});

// Deletes an existing reference in the emulated RealtimeDB and triggers the function
funcDatabase.trigger().onDelete('ref/path');

// Updates an existing reference in the emulated RealtimeDB and triggers the function
funcDatabase.trigger().onUpdate({
  refPath: 'ref/path',
  data: { ... },
});

// Copies a reference from the production to the emulated RealtimeDB and triggers the function
funcDatabase.triggerWithProdData().onCreate('re/path/in/production');

Auth function

// Creates a new user in the emulated Auth users and triggers the function
funcAuth.trigger().onCreate({
  uid: 'user-id-1',
  data: { email: '[email protected]' },
});

// Creates an existing user in the emulated Auth users and triggers the function
funcAuth.trigger().onDelete('user-id');

// Copies an existing user from the production to the emulated Auth users and triggers the function
funcAuth.triggerWithProdData().onCreate('prod-user-id');

Https function

// Send a GET http request to the function with the specified data in body
funcHttps.trigger().get({
  // Optional field to specify URL route, for example https://example.com/api/user
  // if not specified the value '/' is used
  route: '/api/user',
  data: { ... },
});

// Following HTTP methods are supported
funcHttps.trigger().post({ ... });
funcHttps.trigger().put({ ... });
funcHttps.trigger().delete({ ... });
funcHttps.trigger().options({ ... });

Https Callable function

// Triggers the function as an authenticated user 'user-id-1' with the specified payload
// User with the specified ID must be present in the emulated Auth
funcHttpsCallable.triggerAsUser('user-id-1').onCall({
  // Payload
});

// Triggers the function as an non-authenticated (!) user with the specified payload
funcHttpsCallable.trigger().onCall({
  // Payload
});