File System
File System
The File System API offers a way to organize and query file-system data in renoun. It is a powerful tool that allows you to define a schema for file exports and query those exports using a simple API.
To get started with the File System API, instantiate the Directory
class to target a set of files and directories from the file system. You can then use the getEntry
/ getDirectory
/ getFile
methods to query a specific descendant file or directory:
import { Directory } from 'renoun/file-system'
const posts = new Directory({
path: 'posts',
loaders: {
mdx: (path) => import(`./posts/${path}.mdx`),
},
})
Here we are creating a new Directory
instance that targets the posts
directory relative to the working directory. We are also specifying a loader for the mdx
file extension that will be used to load the file contents using the bundler.
Querying file system entries
import { Directory } from 'renoun/file-system'
const posts = new Directory({
path: 'posts',
loaders: {
mdx: (path) => import(`./posts/${path}.mdx`),
},
})
export default async function Page({ slug }: { slug: string }) {
const post = await posts.getFile(slug, 'mdx')
const Content = await post.getExportValue('default')
return <Content />
}
You can query the entries within the directory to help with generating navigations and index pages. For example, we can include only mdx
file extensions to generate an index page of links to all posts using the getEntries
method:
import { Directory, withSchema } from 'renoun/file-system'
interface PostType {
frontmatter: {
title: string
date: Date
}
}
const posts = new Directory({
path: 'posts',
include: '*.mdx',
loaders: {
mdx: withSchema<PostType>((path) => import(`./posts/${path}.mdx`)),
},
})
export default async function Page() {
const allPosts = await posts.getEntries()
return (
<>
<h1>Blog</h1>
<ul>
{allPosts.map(async (post) => {
const path = post.getPath()
const frontmatter = await post.getExportValue('frontmatter')
return (
<li key={path}>
<a href={path}>{frontmatter.title}</a>
</li>
)
})}
</ul>
</>
)
}
Type checking file exports
To improve type safety, you can utilize the withSchema
helper to specify the schema for the file’s exports:
import { Directory, withSchema } from 'renoun/file-system'
interface PostType {
frontmatter: {
title: string
date: Date
}
}
const posts = new Directory({
path: 'posts',
loaders: {
mdx: withSchema<PostType>((path) => import(`./posts/${path}.mdx`)),
},
})
Now when we call JavaScript#getExportValue
and JavaScriptExport#getRuntimeValue
we will have stronger type checking and autocomplete.
Schema Validation
You can also apply schema validation using libraries that follow the Standard Schema Spect like Zod, Valibot, or Arktype to ensure file exports conform to a specific schema:
import { Directory, withSchema } from 'renoun/file-system'
import { z } from 'zod'
const posts = new Directory({
path: 'posts',
loaders: {
mdx: withSchema(
{
frontmatter: z.object({
title: z.string(),
date: z.date(),
}),
},
(path) => import(`./posts/${path}.mdx`)
),
},
})
Alternatively, you can define a schema yourself using both TypeScript types and custom validation functions:
import { Directory, withSchema } from 'renoun/file-system'
interface PostType {
frontmatter: {
title: string
date: Date
}
}
const posts = new Directory({
path: 'posts',
loaders: {
mdx: withSchema<PostType>(
{
frontmatter: (value) => {
if (typeof value.title !== 'string') {
throw new Error('Title is required')
}
if (!(value.date instanceof Date)) {
throw new Error('Date is required')
}
return value
},
},
(path) => import(`./posts/${path}.mdx`)
),
},
})
The file system utilities are not limited to MDX files and can be used with any file type. By organizing content and source code into structured collections, you can easily generate static pages and manage complex routing and navigations. For a more in-depth look at the file system utilities, visit the docs site.
API Reference
withSchema
{ <Types extends ModuleExports>(): ModuleLoaderWithSchema<Types>; <Types extends ModuleExports>(runtime: ModuleRuntimeLoader<NoInfer<Types>>): ModuleLoaderWithSchema<Types, true>; <Types extends ModuleExports = never, Schema extends ModuleExports = ModuleExports<any>>(schema: IsNever<Types> extends true ? Schema : Partial<ModuleExportValidators<NoInfer<Types>>>, runtime: ModuleRuntimeLoader<IsNever<Types> extends true ? NoInfer<Schema> : NoInfer<Types>>): ModuleLoaderWithSchema<IsNever<Types> extends true ? Schema : ModuleExportValidators<NoInfer<Types>>>; }
Signatures
Returns
ModuleLoaderWithSchema<Types, false>Parameters
runtime *
ModuleRuntimeLoader<NoInfer<Types>>
path *
string
file *
JavaScriptFile<Types, Path, Extension>
Returns
ModuleLoaderWithSchema<Types, true>Parameters
schema *
ModuleExports<any> | Partial<ModuleExportValidators<NoInfer<Types>>>
runtime *
ModuleRuntimeLoader<IsNever<Types> extends true ? NoInfer<Schema> : NoInfer<Types>>
path *
string
file *
JavaScriptFile<any, string, string>
Returns
ModuleLoaderWithSchema<IsNever<Types> extends true ? Schema : ModuleExportValidators<NoInfer<Types>>, false>isDirectory
<Types extends Record<string, any>>(entry: FileSystemEntry<Types> | undefined) => entry is Directory<Types>
Determines if a FileSystemEntry
is a Directory
.
Parameters
entry *
FileSystemEntry<Types> | undefined
Returns
booleanisFile
<Types extends Record<string, any>, const Extension extends StringUnion<keyof Types> | StringUnion<keyof Types>[]>(entry: FileSystemEntry<Types> | undefined, extension?: Extension) => entry is Extension extends undefined ? File<Types> : Extension extends string ? FileWithExtension<Types, Extension> : FileWithExtension<Types, Extension[number]>
Determines if a FileSystemEntry
is a File
and optionally narrows the
result based on the provided extensions.
Parameters
entry *
FileSystemEntry<Types> | undefined
extension
Extension | undefined
Returns
booleanisJavaScriptFile
<Types extends Record<string, any>>(entry: FileSystemEntry<Types> | undefined) => entry is JavaScriptFile<Types>
Determines if a FileSystemEntry
is a JavaScriptFile
.
Parameters
entry *
FileSystemEntry<Types> | undefined
Returns
booleanFileSystem
FileSystem
Constructors
(options: FileSystemOptions) => FileSystem
Methods
getProjectOptions
() => ProjectOptions
getAbsolutePath
(path: string) => string
getRelativePath
(path: string) => string
getRelativePathToWorkspace
(path: string) => string
getPath
(path: string, options?: { basePath?: string; }) => string
readDirectorySync
(path?: string, options?: { recursive?: boolean; }) => DirectoryEntry[]
readDirectory
(path?: string, options?: { recursive?: boolean; }) => Promise<DirectoryEntry[]>
readFileSync
(path: string) => string
readFile
(path: string) => Promise<string>
isFilePathExcludedFromTsConfig
(filePath: string, isDirectory?: boolean) => boolean
isFilePathGitIgnored
(filePath: string) => boolean
getFileExports
(filePath: string) => Promise<Array<FileExport>>
getFileExportMetadata
(name: string, filePath: string, position: number, kind: SyntaxKind) => Promise<{ name: string; environment: string; jsDocMetadata: { description?: string; tags?: { tagName: string; text?: string; }[]; } | undefined; location: DeclarationLocation; text: string; }>
resolveTypeAtLocation
(filePath: string, position: number, kind: SyntaxKind, filter?: SymbolFilter) => Promise<ResolvedType | undefined>
MemoryFileSystem
MemoryFileSystem
A file system that stores files in memory.
Constructors
() => MemoryFileSystem
Methods
getProjectOptions
() => ProjectOptions
transpileFile
(path: string) => Promise<string>
getAbsolutePath
(path: string) => string
getFiles
() => Map<string, string>
readDirectorySync
(path?: string) => DirectoryEntry[]
readDirectory
(path?: string) => Promise<DirectoryEntry[]>
readFileSync
(path: string) => string
readFile
(path: string) => Promise<string>
isFilePathGitIgnored
(filePath: string) => boolean
NodeFileSystem
NodeFileSystem
Constructors
(options: FileSystemOptions) => NodeFileSystem
Methods
getProjectOptions
() => { tsConfigFilePath: string; }
getAbsolutePath
(path: string) => string
readDirectorySync
(path?: string) => DirectoryEntry[]
readDirectory
(path?: string) => Promise<DirectoryEntry[]>
readFileSync
(path: string) => string
readFile
(path: string) => Promise<string>
isFilePathGitIgnored
(filePath: string) => boolean
Repository
Repository
Constructors
(repository: string | RepositoryConfig) => Repository
Methods
getIssueUrl
(options: GetIssueUrlOptions) => string
Constructs a new issue URL for the repository.
getFileUrl
(options: GetFileUrlOptions) => string
Constructs a URL for a file in the repository.
getDirectoryUrl
(options: GetDirectoryUrlOptions) => string
Constructs a URL for a directory in the repository.
InferModuleExports
InferModuleExports<Exports>
Utility type that infers the schema output from validator functions or a Standard Schema.
InferModuleExports<Exports>
InferModuleLoadersTypes
InferModuleLoadersTypes<Loaders>
Infer extension types for all loaders in a module.
InferModuleLoadersTypes<Loaders>
FileNotFoundError
FileNotFoundError
Error for when a file is not found.
Constructors
(path: string | Array<string>, extension?: any) => FileNotFoundError
FileSystemEntry
FileSystemEntry<Types>
A directory or file entry.
Directory
Directory<Types, LoaderTypes, Loaders, Include>
A directory containing files and subdirectories in the file system.
File
File<Types, Path, Extension>
A file in the file system.
FileOptions
FileOptions<Types, Path>
Options for a file in the file system.
Properties
path *
Path
pathCasing
SlugCasings | undefined
depth
number | undefined
directory
Directory<Types, WithDefaultTypes<Types>, ModuleLoaders, EntryInclude<FileSystemEntry<Types>, Types>> | undefined
File
File<Types, Path, Extension>
A file in the file system.
Constructors
<undefined, undefined, undefined>(options: FileOptions<Types, Path>) => File<Types, Path, Extension>
Methods
getName
() => string
The intrinsic name of the file.
getBaseName
() => string
The file name without the extension.
getTitle
() => string
The file name formatted as a title.
getOrder
() => string | undefined
The order of the file if defined.
getModifier
() => string | undefined
The modifier of the file if defined.
getExtension
() => Extension
The extension of the file if defined.
getDepth
() => number
Get the depth of the file starting from the root directory.
getSlug
() => string
Get the slug of the file.
getPath
(options?: { includeBasePath?: boolean; includeDuplicateSegments?: boolean; }) => string
Get the path of the file excluding the file extension and order prefix.
The configured pathCasing
option will be used format the path segments.
getPathSegments
(options?: { includeBasePath?: boolean; includeDuplicateSegments?: boolean; }) => Array<string>
Get the path segments of the file.
getRelativePath
() => string
Get the file path relative to the root directory.
getRelativePathToWorkspace
() => string
Get the file path relative to the workspace root.
getAbsolutePath
() => string
Get the absolute file system path.
getBlameUrl
(options?: Pick<GetFileUrlOptions, "ref">) => string
Get the URL to the file git blame for the configured git repository.
getEditUrl
(options?: Pick<GetFileUrlOptions, "ref" | "line">) => string
Get the edit URL to the file source for the configured git repository.
getHistoryUrl
(options?: Pick<GetFileUrlOptions, "ref">) => string
Get the URL to the file history for the configured git repository.
getRawUrl
(options?: Pick<GetFileUrlOptions, "ref">) => string
Get the URL to the raw file contents for the configured git repository.
getSourceUrl
(options?: Pick<GetFileUrlOptions, "ref" | "line">) => string
Get the URL to the file source for the configured git repository.
getEditorUri
() => string
Get the URI to the file source code for the configured editor.
getFirstCommitDate
() => Promise<Date | undefined>
Get the first local git commit date of the file.
getLastCommitDate
() => Promise<Date | undefined>
Get the last local git commit date of the file.
getAuthors
() => Promise<Array<GitAuthor>>
Get the local git authors of the file.
getParent
() => Directory<Types, WithDefaultTypes<Types>, ModuleLoaders, EntryInclude<FileSystemEntry<WithDefaultTypes<Types>>, WithDefaultTypes<Types>>>
Get the directory containing this file.
getSiblings
<GroupTypes extends Record<string, any> = Types>(options?: { entryGroup?: EntryGroup<GroupTypes, FileSystemEntry<any>[]>; includeDuplicateSegments?: boolean; }) => Promise<[FileSystemEntry<Types> | undefined, FileSystemEntry<Types> | undefined]>
Get the previous and next sibling entries (files or directories) of the parent directory. If the file is an index or readme file, the siblings will be retrieved from the parent directory.
getText
() => Promise<string>
Get the source text of the file.
FileExportNotFoundError
FileExportNotFoundError
Error for when a file export is not found.
Constructors
(path: string, name: string) => FileExportNotFoundError
JavaScriptFileExport
JavaScriptFileExport<Value>
A JavaScript file export.
Constructors
<Value>(name: string, file: JavaScriptFile<any, string, string>, loader?: ModuleLoader<any> | undefined) => JavaScriptFileExport<Value>
Methods
init
<Value>(name: string, file: JavaScriptFile<any>, loader?: ModuleLoader<any>) => Promise<JavaScriptFileExport<Value>>
getStaticMetadata
() => Promise<{ name: string; environment: string; jsDocMetadata: { description?: string; tags?: { tagName: string; text?: string; }[]; } | undefined; location: DeclarationLocation; text: string; } | undefined>
getSlug
() => string
Get the slug of the file export.
getName
() => string
Get the name of the export. Default exports will use the file name or declaration name if available.
getTitle
() => string
The export name formatted as a title.
getDescription
() => string | undefined
Get the JS Doc description of the export.
getTags
() => Array<{ tagName: string; text?: string; }> | undefined
Get the JS Doc tags of the export.
getEnvironment
() => string | undefined
Get the environment of the export.
getText
() => string | undefined
Get the source text of the export.
getPosition
() => DeclarationPosition | undefined
Get the start and end position of the export in the file system.
getEditUrl
(options?: Pick<GetFileUrlOptions, "ref">) => string
Get the edit URL to the file export source for the configured git repository.
getSourceUrl
(options?: Pick<GetFileUrlOptions, "ref">) => string
Get the URL to the file export source for the configured git repository.
getEditorUri
() => string
Get the URI to the file export source code for the configured editor.
getType
(filter?: SymbolFilter) => Promise<ResolvedType | undefined>
Get the resolved type of the export.
getRuntimeValue
() => Promise<Value>
Get the runtime value of the export. An error will be thrown if the export is not found or the configured schema validation for this file extension fails.
JavaScriptFileOptions
JavaScriptFileOptions<Types, Path>
Options for a JavaScript file in the file system.
Properties
loader
ModuleLoader<Types> | undefined
path *
Path
pathCasing
SlugCasings | undefined
depth
number | undefined
directory
Directory<Types, WithDefaultTypes<Types>, ModuleLoaders, EntryInclude<FileSystemEntry<Types>, Types>> | undefined
JavaScriptFile
JavaScriptFile<Types, Path, Extension>
A JavaScript file in the file system.
Constructors
<undefined, undefined, undefined>(JavaScriptFileOptions<Types, Path>) => JavaScriptFile<Types, Path, Extension>
Methods
parseExportValue
(name: string, value: any) => any
Parse and validate an export value using the configured schema if available.
getExports
() => Promise<Array<JavaScriptFileExport<Types[Extract<keyof Types, string>]>>>
Get all exports from the JavaScript file.
getExport
<ExportName extends Extract<keyof Types, string>>(name: ExportName) => Promise<JavaScriptFileExport<Types[ExportName]>>
Get a JavaScript file export by name.
getExportLocation
(name: string) => Promise<FileExport | undefined>
Get the start position of an export in the JavaScript file.
getExportValue
<ExportName extends Extract<keyof Types, string>>(name: ExportName) => Promise<Types[ExportName]>
Get the runtime value of an export in the JavaScript file.
hasExport
(name: string) => Promise<boolean>
Check if an export exists in the JavaScript file.
EntryInclude
EntryInclude<Entry, Types>
string
(entry: FileSystemEntry<Types>) => entry is Entry
entry *
FileSystemEntry<Types>
(entry: FileSystemEntry<Types>) => Promise<boolean> | boolean
entry *
FileSystemEntry<Types>
IncludedEntry
IncludedEntry<Types, DirectoryFilter>
Directory
Directory<Types, LoaderTypes, Loaders, Include>
A directory containing files and subdirectories in the file system.
File
File<Types, Path, Extension>
A file in the file system.
Directory
Directory<Types, LoaderTypes, Loaders, Include>
A directory containing files and subdirectories in the file system.
Constructors
<undefined, undefined, undefined, undefined>(options?: DirectoryOptions<Types, LoaderTypes, Loaders, Include> | undefined) => Directory<Types, LoaderTypes, Loaders, Include>
Methods
getFileSystem
() => FileSystem
Get the file system for this directory.
getRepository
() => Repository
Get the Repository
for this directory.
getDepth
() => number
Get the depth of the directory starting from the root directory.
getFile
{ <const Path extends string, Extension extends ExtractFileExtension<Path> = ExtractFileExtension<Path>>(path: Path): Promise<Extension extends string ? IsJavaScriptLikeExtension<Extension> extends true ? JavaScriptFile<LoaderTypes[Extension], string, Extension> : File<LoaderTypes, Path, Extension> : File<LoaderTypes>>; <ExtensionType extends keyof LoaderTypes | string, const Extension extends ExtensionType | Extension[]>(path: string | string[], extension?: Extension | Extension[]): Promise<Extension extends string ? IsJavaScriptLikeExtension<Extension> extends true ? JavaScriptFile<LoaderTypes[Extension], string, Extension> : File<LoaderTypes, Extension> : File<LoaderTypes>>; }
getDirectory
(path: string | string[]) => Promise<Directory<LoaderTypes>>
Get a directory at the specified path
.
getEntry
(path: string | string[]) => Promise<FileSystemEntry<LoaderTypes>>
Get a file or directory at the specified path
. Files will be prioritized over directories.
getEntries
(options?: { recursive?: boolean; includeIndexAndReadme?: boolean; includeDuplicates?: boolean; includeGitIgnoredFiles?: boolean; includeTsConfigIgnoredFiles?: boolean; }) => Promise<Include extends string ? FileWithExtension<LoaderTypes, ExtractFileExtension<Include>>[] : Include extends EntryInclude<infer FilteredEntry, LoaderTypes> ? FilteredEntry[] : FileSystemEntry<LoaderTypes>[]>
Retrieves all entries (files and directories) within the current directory
that are not excluded by Git ignore rules or the closest tsconfig
file.
Additionally, index
and readme
files are excluded by default.
getParent
() => Directory<any, any, any, EntryInclude<FileSystemEntry<any>, any>>
Get the directory containing this directory.
getSiblings
<GroupTypes extends Record<string, any> = LoaderTypes>(options?: { entryGroup?: EntryGroup<GroupTypes, FileSystemEntry<any>[]>; }) => Promise<[FileSystemEntry<LoaderTypes> | undefined, FileSystemEntry<LoaderTypes> | undefined]>
Get the previous and next sibling entries (files or directories) of the parent directory.
getSlug
() => string
Get the slug of the directory.
getName
() => string
Get the base name of the directory.
getBaseName
() => string
Get the base name of the directory.
getTitle
() => string
The directory name formatted as a title.
getPath
(options?: { includeBasePath?: boolean; }) => string
Get a URL-friendly path to the directory.
getPathSegments
(options?: { includeBasePath?: boolean; }) => Array<string>
Get the path segments to the directory.
getBasePath
() => string | undefined
Get the configured base path of the directory.
getRelativePath
() => string
Get the relative path of the directory.
getRelativePathToWorkspace
() => string
Get the relative path of the directory to the workspace.
getAbsolutePath
() => string
Get the absolute path of the directory.
getHistoryUrl
(options?: Pick<GetFileUrlOptions, "ref">) => string
Get the URL to the directory history for the configured git repository.
getSourceUrl
(options?: Pick<GetFileUrlOptions, "ref">) => string
Get the URL to the directory source for the configured git repository.
getEditorUri
() => string
Get the URI to the directory source code for the configured editor.
getFirstCommitDate
() => Promise<Date | undefined>
Get the first local git commit date of the directory.
getLastCommitDate
() => Promise<Date | undefined>
Get the last local git commit date of the directory.
getAuthors
() => Promise<Array<GitAuthor>>
Get the local git authors of the directory.
hasEntry
(entry: FileSystemEntry<any> | undefined) => entry is FileSystemEntry<LoaderTypes>
Checks if this directory contains the provided entry.
hasFile
<ExtensionType extends keyof LoaderTypes | string, const Extension extends ExtensionType | Extension[]>(entry: FileSystemEntry<any> | undefined, extension?: Extension | Extension[]) => entry is FileWithExtension<LoaderTypes, Extension>
Checks if this directory contains the provided file.
EntryGroupOptions
EntryGroupOptions<Entries>
Options for an EntryGroup
.
Properties
entries *
Entries
EntryGroup
EntryGroup<Types, Entries, Loaders>
A group of file system entries.
Constructors
<Types, Entries extends Array<FileSystemEntry<any>>, Loaders extends ModuleLoaders>(options: EntryGroupOptions<Entries>) => EntryGroup<Types, Entries, Loaders>
Methods
getEntries
(options?: { recursive?: boolean; includeIndexAndReadme?: boolean; }) => Promise<Entries>
Get all entries in the group.
getEntry
(path: string | string[]) => Promise<FileSystemEntry<Types>>
Get an entry in the group by its path.
getFile
<const Extension extends string | undefined = undefined>(path: string | string[], extension?: Extension | Extension[]) => Promise<Extension extends string ? IsJavaScriptLikeExtension<Extension> extends true ? JavaScriptFile<Types[Extension]> : File<Types> : File<Types>>
Get a file at the specified path and optional extension(s).
getDirectory
(path: string | string[]) => Promise<Directory<Types>>
Get a directory at the specified path.
FileWithExtension
FileWithExtension<Types, Extension>
Determines the type of a FileSystemEntry
based on its extension.
File
File<Types, Path, Extension>
A file in the file system.
JavaScriptFile
JavaScriptFile<Types, Path, Extension>
A JavaScript file in the file system.