module

Noir::ServerlessLayout

File-system layout rules shared by the file-routed serverless platforms (Cloudflare Pages functions/, Vercel api/, Netlify netlify/functions/). Detectors and analyzers both need to know which directory a route is relative to, so the rule lives here rather than in either layer.

Constants

NETLIFY_FUNCTION_DIRS = {"functions", "edge-functions"}
PROJECT_MARKERS = {"package.json", "vercel.json", "now.json", "netlify.toml", "wrangler.toml", "wrangler.json", "wrangler.jsonc"}

Files that mark a directory as a deployable project root.

VERCEL_CONFIGS = {"vercel.json", "now.json"}
VERCEL_IMPORT = /(?:\bfrom\s*|\brequire\s*\(\s*|\bimport\s*\(\s*)['"]@vercel\/(?:node|functions)['"]/

A module importing the Vercel runtime types marks itself as a function.

VERCEL_PACKAGE_MARKERS = {"\"@vercel/node\"", "\"@vercel/functions\""}

Instance methods

ancestor(path : String, levels : Int32) : String

File.dirname applied levels times.

Source
netlify_default_remainder(relative : String) : Tuple(String, Array(String)) | Nil

Netlify's default function directories: netlify/functions/ and netlify/edge-functions/ under the site's base directory. Returns {kind, segments_below_it} where kind is functions or edge-functions.

Source
netlify_function_name(segments : Array(String)) : String | Nil

A Netlify function's name from its path below the functions directory: hello.mts, hello/hello.mts and hello/index.mts are all hello. Anything deeper, or a sibling module in a function's own directory, is a helper and not a function.

Source
non_handler_file?(path : String) : Bool

Colocated tests (x.test.ts, x.spec.js) and type declarations are not deployed handlers.

Source
private_segment?(segments : Array(String)) : Bool

Hidden (.x) and private (_x) entries, which Vercel does not deploy.

Source
project_root?(dir : String) : Bool
Source
routing_remainder(path : String, relative : String, dir_name : String) : Tuple(String, Array(String)) | Nil

Locate the routing directory for path: the first dir_name segment of its scan-base-relative form (relative, rooted with /) that sits at the scan root or directly inside a project root. Returns the absolute project root plus the path segments below the routing dir.

Anchoring on a project root is what keeps src/pages/api/x.ts (Next.js) or server/api/x.ts (Nuxt) from being read as a Vercel api/ dir, and netlify/functions/x.ts from being read as Cloudflare functions/.

Source
stem(file : String) : String

File name without its last extension.

Source
vercel_project?(root : String) : Bool

Whether root is a Vercel project: it carries a vercel.json / now.json, or its package.json depends on the Vercel runtime types.

Source