Files
supabase/apps/studio/lib/api/self-hosted/functions/fileSystemStore.ts
T
1862b71745 feat(studio-local): functions management api - list functions (#40690)
## What is the current behaviour?

Functions page on self-hosted differs from Platform

## What is the new behaviour?

Adds the possibility to see a list of edge-functions in Self-Host
version.

## Summary by CodeRabbit

* **New Features**
* Added self-hosted edge functions support with filesystem-based
artifact listing and a new API endpoint to list local functions.
* Improved functions UI: unified view, enhanced search and adjacent sort
controls, and clearer local-hosting guidance.

* **Chores**
* Added environment configuration and docker volume for edge functions
management.
* Updated build/task config to pass through edge functions env and
include contentlayer outputs.

Co-authored-by: Ali Waseem <waseema393@gmail.com>
Co-authored-by: Charis Lam <26616127+charislam@users.noreply.github.com>
Co-authored-by: Terry Sutton <saltcod@gmail.com>
2026-01-30 08:00:21 +08:00

42 lines
1.3 KiB
TypeScript

import type { Dirent } from 'node:fs'
import { readdir, stat } from 'node:fs/promises'
import path from 'node:path'
import { pathToFileURL } from 'node:url'
import { FunctionArtifact } from './types'
export class FileSystemFunctionsArtifactStore {
constructor(private folderPath: string) {}
async getFunctions(): Promise<FunctionArtifact[]> {
const dirEntries = await readdir(this.folderPath, { withFileTypes: true })
const functionsFolders = dirEntries.filter((dir) => dir.isDirectory() && dir.name !== 'main')
const functionsArtifacts = await Promise.all(
functionsFolders.map(parseFolderToFunctionArtifact)
)
return functionsArtifacts.filter((f) => f !== undefined)
}
}
async function parseFolderToFunctionArtifact(
folder: Dirent
): Promise<FunctionArtifact | undefined> {
const folderPath = path.join(folder.parentPath, folder.name)
const files = await readdir(folderPath, { withFileTypes: true })
const entrypoint = files.find((file) => file.isFile() && file.name.startsWith('index'))
if (!entrypoint) return
const entrypointPath = path.join(folderPath, entrypoint.name)
const entrypointStat = await stat(entrypointPath)
return {
slug: folder.name,
entrypoint_path: pathToFileURL(entrypointPath).href,
created_at: entrypointStat.birthtimeMs,
updated_at: entrypointStat.mtimeMs,
}
}