inngest-js icon indicating copy to clipboard operation
inngest-js copied to clipboard

[Feature] Autodetect functions

Open charanjit-singh opened this issue 2 years ago • 2 comments

Autodetect created functions in inngest.

For now, I've created a utility command that's working fine for me but we'd love not to register the functions manually.

const fs = require("fs");
const BASE_PATH = "src/lib/inngest/functions";

// Read all the files and folders recursively in the given path and create a list of all the files
const getFilesRecursively = (path) => {
  const files = fs.readdirSync(path);
  let fileList = [];

  files.forEach((file) => {
    if (fs.statSync(`${path}/${file}`).isDirectory()) {
      fileList = [...fileList, ...getFilesRecursively(`${path}/${file}`)];
    } else {
      fileList.push(`${path}/${file}`);
    }
  });

  return fileList;
};

const isFileValid = (filePath) => {
  // Check if file contains inngest.createFunction
  const fileContent = fs.readFileSync(filePath, "utf8");
  if (!fileContent.includes("inngest.createFunction")) {
    return false;
  }
  return true;
};

// Remove base path from the file path
const files = getFilesRecursively(BASE_PATH)
  .filter((file) => isFileValid(file))
  .map((file) => file.replace(`${BASE_PATH}/`, ""));

// Open BASE_PATH/../index.ts and write the import statements for all the files
const content = `
// Generated file. Do not edit manually. Run 'node scripts/register-inngest-functions.js' to regenerate this file.
const functions = [
${files
      .map(
        (file) => `    require("./functions/${file.replace(".ts", "")}").default`
      )
      .join(",\n")}
];
export default functions;
`;

fs.writeFileSync(`${BASE_PATH}/../index.ts`, content);

// Print warning message for invalid files in yellow color
const invalidFiles = getFilesRecursively(BASE_PATH).filter(
  (file) => !isFileValid(file)
);
if (invalidFiles.length > 0) {
  console.log(
    `\x1b[33m${invalidFiles.length} files are invalid and not registered.\x1b[0m`
  );
  invalidFiles.forEach((file, index) => {
    console.log(`\x1b[33m${index + 1}. ${file}\x1b[0m`);
  }
  );
}

// Print success message with number of functions registered in green color
console.log(
  `\x1b[32m${files.length} functions registered successfully.\x1b[0m`
);

In route.ts

import { serve } from "inngest/next";
import { inngest } from "@/lib/inngest/client";
import functions from "@/lib/inngest";

// Create an API that serves zero functions
export const { GET, POST, PUT } = serve(inngest, functions);

charanjit-singh avatar Aug 19 '23 13:08 charanjit-singh

This could be done programmatically at runtime as we are using the inngest client to create function. It could make sense that the client store each created function within itself. This will simplify the serve function signature.

elbalexandre avatar Dec 22 '23 10:12 elbalexandre

This could be done programmatically at runtime as we are using the inngest client to create function. It could make sense that the client store each created function within itself. This will simplify the serve function signature.

How can we do this in production? I mean create dynamic functions ? Like user defined cron jobs

octalpixel avatar Aug 22 '24 06:08 octalpixel