Releases: souporserious/renoun
[email protected]
Minor Changes
-
0f069c5: Implements
<JavaScriptFile>.getExport
as an async method that now resolves the metadata of the export when it is initialized. This removes the need toawait
all methods likegetName
,getDescription
, andgetTags
. Additionally, this adds a new<JavaScriptFile>.hasExport
method for checking if the file has a specific export. -
9cf4499: Deprecates
Collection
,CompositeCollection
,isExportSource
,isFileSystemSource
, andisCollectionSource
. These will be removed in the next major version.Updating to File System utilities
The
Collection
andCompositeCollection
classes have been deprecated in favor of the newrenoun/file-system
utilities. TheisExportSource
,isFileSystemSource
, andisCollectionSource
functions have also been deprecated.To update your code, replace any instances of
Collection
withDirectory
andCompositeCollection
withEntryGroup
. For example, the following code:import { Collection, CompositeCollection } from 'renoun/collections' const docs = new Collection({ filePattern: '*.mdx', baseDirectory: 'docs', }) const components = new Collection({ filePattern: '*.{ts,tsx}', baseDirectory: 'src/components', }) const compositeCollection = new CompositeCollection(docs, components)
should be replaced with:
import { Directory, EntryGroup, isFile } from 'renoun/file-system' const docs = new Directory({ path: 'docs' }).filter((entry) => isFile(entry, 'mdx') ) const components = new Directory({ path: 'src/components' }).filter((entry) => isFile(entry, ['ts', 'tsx']) ) const entryGroup = new EntryGroup({ entries: [docs, components] })
-
95e56e2: Adds
includeDuplicates
option to<Directory>.getEntries
that is set tofalse
by default. This option allows control over deduplicating entries with the same base name e.g.Button.mdx
andButton.tsx
. -
7d56e9a: Adds
getSlug
method toDirectory
,File
, andJavaScriptExport
. -
3419623: Adds
getExportValue
andgetExportValueOrThrow
methods toJavaScriptFile
as a shortcut to getting an export's runtime value since this is a common use case. -
91d9b51: Removes
isFileWithExtension
and reimplements it withinisFile
which now allows an optional secondextension
argument.Breaking Changes
To upgrade, replace all instances of
isFileWithExtension
withisFile
. Previous usage ofisFile
will still work as expected. -
4279d19: Adds
includeDuplicateSegments
configuration option for<File>.getPath
method that is set tofalse
by default. This option allows including consecutive duplicate segments in the returned path. -
92c5dee: Enables passing
tsConfigPath
option toDirectory
. -
4f843e4: Adds
isJavaScriptFile
andisJavaScriptFileWithRuntime
type guards for JavaScript-like files. -
50e094b: Adds
getPosition
andgetText
methods toJavaScriptExport
. -
c4d274c: Moves the
Directory
getImport
option to<Directory>.withModule
. This provides stronger types for inferring thegetRuntimeValue
method.Breaking Changes
Update the
getImport
option towithModule
:export const posts = new Directory<{ mdx: PostType }>({ path: 'posts', schema: { mdx: { frontmatter: frontmatterSchema.parse } }, -- getImport: (path) => import(`./posts/${path}`), }) ++ .withModule((path) => import(`./posts/${path}`))
-
87ce75d: Moves the
Directory
schema
option to<Directory>.withSchema
. This aligns with the other recent refactor ofDirectory
options.Breaking Changes
Update the
schema
option towithSchema
:export const posts = new Directory<{ mdx: PostType }>({ path: 'posts', -- schema: { mdx: { frontmatter: frontmatterSchema.parse } }, }) ++ .withSchema('mdx', { frontmatter: frontmatterSchema.parse })
-
46f0807: Moves the
Directory
basePath
option to<Directory>.withBasePath
. This aligns with the recent refactor of otherDirectory
options.Breaking Changes
Update the
basePath
option towithBasePath
:export const posts = new Directory<{ mdx: PostType }>({ path: 'posts', -- basePath: 'blog', }) ++ .withBasePath('blog')
-
8252c4b: Adds
getTitle
method toDirectory
andFileName
classes. -
2e7f458: Adds an
EntryGroup
utility torenoun/file-system
that provides an interface for querying and navigating a group of entries:import { Directory, EntryGroup } from 'renoun/file-system' interface FrontMatter { title: string description?: string date: string tags?: string[] } interface MDXType { frontmatter: FrontMatter } const posts = new Directory<{ mdx: MDXType }>({ path: 'posts', }) const docs = new Directory<{ mdx: MDXType }>({ path: 'docs', }) const group = new EntryGroup({ entries: [posts, docs], }) const entries = await group.getEntries()
Sibling entries can be queried using the
getSiblings
method and passing theEntryGroup
instance to get the siblings for. This is useful for querying siblings across sets of entries:const entry = await group.getEntryOrThrow('Button') const siblings = await entry.getSiblings({ entryGroup: group })
This also adds
hasEntry
andhasFile
methods toDirectory
which can be used to check if an entry or file exists in anEntryGroup
:type MDXTypes = { metadata: { title: string } } type TSXTypes = { title: string } const directoryA = new Directory<{ mdx: MDXTypes }>({ fileSystem: new VirtualFileSystem({ 'Button.mdx': '' }), }) const directoryB = new Directory<{ tsx: TSXTypes }>({ path: 'fixtures/components', }) const group = new EntryGroup({ entries: [directoryA, directoryB], }) const entry = await group.getEntryOrThrow('Button') if (directoryA.hasFile(entry, 'mdx')) { entry // JavaScriptFile<MDXTypes> }
-
da0ca4a: Adds
getDepth
method toDirectory
andFile
. -
1d62855: Fixes ts config exclude paths not being respected when using a relative path.
-
be4c6ae: Normalizes the
<File>.getDirectory
method to return an async value similar toDirectory
. -
155f2e7: Renames file system methods
filter
towithFilter
andsort
towithSort
for better clarity since they are not immediately applied.Breaking Changes
<Directory>.filter
method is now<Directory>.withFilter
<Directory>.sort
method is now<Directory>.withSort
-
6e599bb: Adds
includeGitIgnoredFiles
andincludeTsConfigIgnoredFiles
options to<Directory>.getEntries
. These options allow you to include files that are ignored by.gitignore
andtsconfig.json
respectively. -
66f8289: Adds the ability to specify only the
path
when initializing aDirectory
instance since this is the most common use case:import { Directory } from 'renoun/file-system' const directory = new Directory('path/to/directory')
For more advanced use cases, you can still specify the
options
:import { Directory, MemoryFileSystem } from 'renoun/file-system' const fileSystem = new MemoryFileSystem({ 'Button.tsx': 'export const Button = () => {}', }) const directory = new Directory({ path: 'path/to/directory', fileSystem, })
Patch Changes
-
20d3bc5: Fixes an issue in the
<Directory>.getFile
method where theentry
variable was not reset in each iteration of the while loop. This caused incorrect file resolutions when searching for nested files. -
c29192b: Fixes nested files being ordered before directory when using
<Directory>.getEntries
. Now the directory will be ordered first by default before its descendants. -
ce32d36: Fixes analyzing barrel file exports.
-
bb20d7e: Fixes duplicate file exports being returned. This was specifically happening when a file export attached a member to the function implementation:
export function CodeBlock() { // ... } CodeBlock.displayName = 'CodeBlock' // This caused the file to be exported twice
-
76b2c80: Fixes package import error if
prettier
is not installed. -
23aba08: Fixes
Directory
andFile
getSiblings
method not using a unique identifier to find a matching entry. -
97799b3: Fixes
<Directory>.getFile
not considering extensions. -
f2326fd: Fixes
<Directory>.getFile
not considering extension when provided and matching a directory. -
50d8760: Fixes
VirtualFileSystem
not respecting provided files order. -
f011668: Fixes
isDirectory
type guard inference. -
3da8602: Fixes not being able to set tsconfig
compilerOptions
to useverbatimModuleSyntax
. -
c160fba: Fixes filtering of
Directory
entries based on tsconfigexclude
field.
[email protected]
Minor Changes
- a1aa042: Removes managing of auto-generated dynamic imports for collections as this was causing issues with build processes.
Patch Changes
[email protected]
Minor Changes
-
0c67c7c: Removes
isJavaScriptFile
type guard in favor ofisFileWithExtension
that narrows types better. -
bf56af0: Adds support for passing
JavaScriptFile
andJavaScriptFileExport
to theAPIReference
component. -
4fc9781: Returns a
JavaScriptExport
instance now fromgetExports
to align withgetExport
. -
73bb769: Adds Fast Refresh to
<JavaScriptExport>.getRuntimeValue
for Next.js. -
3eec7ff: Removes
getDirectories
andgetFiles
fromDirectory
now that thefilter
method is available:import { Directory, isFileWithExtension } from 'renoun/file-system' const directory = new Directory() const files = directory .filter((entry) => isFileWithExtension(entry, ['ts', 'tsx'])) .getEntries()
-
5390b16: Removes
<File>.hasExtension
method in favor of theisFileWithExtension
type guard to consolidate the API.
Patch Changes
- 8d2b7f3: Fixes the
<Directory>.getEntries
methodrecursive
option not considering nested entries.
[email protected]
Minor Changes
-
abb441d: Improves error handling for the
CodeBlock
component when falsey values are provided. -
0b6e426: Adds
sort
method toDirectory
to allow sorting all entries within each directory:import { Directory, isFileWithExtension } from 'renoun' type PostType = { frontmatter: { title: string } } const posts = new Directory<{ mdx: PostType }>({ path: 'posts' }) .filter((entry) => isFileWithExtension(entry, 'mdx')) .sort(async (a, b) => { const aFrontmatter = await a.getExport('frontmatter').getRuntimeValue() const bFrontmatter = await b.getExport('frontmatter').getRuntimeValue() return aFrontmatter.title.localeCompare(bFrontmatter.title) }) const files = await posts.getEntries() // JavaScriptFile<PostType>[] sorted by front matter title
-
cac71c1: Improves
<VirtualFileSystem>.transpileFile
error handling. -
2c55b51: Adds
filter
method toDirectory
to allow filtering all entries within each directory:import { Directory, isFileWithExtension } from 'renoun' type PostType = { frontmatter: { title: string } } const posts = new Directory<{ mdx: PostType }>({ path: 'posts' }).filter( (entry) => isFileWithExtension(entry, 'mdx') ) const files = await posts.getEntries() // JavaScriptFile<PostType>[]
-
40c6cdd: Scopes
VirtualFileSystem
using aprojectId
added to the baseFileSystem
class. This ensures the TypeScript project is unique to the virtual file system it is instantiated with.
Patch Changes
- 1c77620: Fixes the
<Directory>.getEntries
methodrecursive
option to only recurse ingetEntries
instead of the file system.
[email protected]
Minor Changes
-
e71de2f: Adds
shouldFormat
prop toCodeBlock
component to allow disabling code formatting. This is useful for MDX code blocks that are already formatted by an IDE or CI environment.export function useMDXComponents() { return { pre: (props) => { return <CodeBlock shouldFormat={false} {...restProps} /> }, } }
-
f44b9c5: Adds support for passing an array to
isFileWithExtension
and<File>.hasExtension
.
Patch Changes
[email protected]
[email protected]
Minor Changes
-
9d67bdf: Add
getFiles
andgetDirectories
toDirectory
. -
1bd1de3: Adds
hasExtension
method toFile
to help constrain the type:import { Directory } from 'renoun/file-system' const posts = new Directory<{ mdx: { frontmatter: { title: string } } }>({ path: 'posts', }) const mdxFiles = await posts .getFiles() .filter((post) => post.hasExtension('mdx'))
-
4d263fe: Add
includeIndexAndReadme
option togetEntries
for controlling default filtering ofindex
andreadme
files. -
e09a837: Adds
isFileWithExtension
utility:const fileSystem = new VirtualFileSystem({ 'Button.tsx': '', }) const directory = new Directory<{ tsx: { metadata: {} } }>({ fileSystem, }) const file = await directory.getFileOrThrow('Button') if (isFileWithExtension(file, 'tsx')) { // file is typed as File<{ tsx: { metadata: {} } }> }
-
a36058f: Add
getEditPath
method toJavaScriptFileExport
.
[email protected]
Minor Changes
-
16a475f: Adds javascript file export metadata to
renoun/file-system
:import { VirtualFileSystem, Directory } from 'renoun/file-system' const fileSystem = new VirtualFileSystem({ 'index.ts': `/**\n * Say hello.\n * @category greetings\n */\nexport default function hello() {}`, }) const directory = new Directory({ fileSystem }) const file = await directory.getFileOrThrow('index', 'ts') const fileExport = file.getExport('default') await fileExport.getName() // 'hello' await fileExport.getDescription() // 'Say hello.' await fileExport.getTags() // [{ name: 'category', value: 'greetings' }]
Patch Changes
- e1b908e: Removes
async
modifier forCodeInline
component to prevent type errors.
[email protected]
Major Changes
-
90bbe5b: Simplifies how
baseDirectory
works forCollection
. This was from a legacy implementation that was not well thought out and caused confusion. This change makes it more explicit and easier to understand.Breaking Changes
The
baseDirectory
option forCollection
is now required to be separate fromfilePattern
:import { Collection } from 'renoun/collections' const components = new Collection({ -- filePattern: 'src/components/**/*.ts', ++ filePattern: '**/*.ts', -- baseDirectory: 'components', ++ baseDirectory: 'src/components', })
-
93da61f: Introduces more performant, type-safe file system from utilities exported from
renoun/file-system
to replace therenoun/collections
API, which will be removed in a future major release.- New Classes:
NodeFileSystem
,VirtualFileSystem
,Directory
,File
,JavaScriptFile
, andJavaScriptFileExport
.
- Improvements:
- Optimized performance, stronger TypeScript support, and in-memory support with
VirtualFileSystem
.
- Optimized performance, stronger TypeScript support, and in-memory support with
Migration Example
Before:
const collection = new Collection({ filePattern: 'src/**/*.{ts,tsx}', baseDirectory: 'src', }) const sources = await collection.getSources()
After:
const directory = new Directory({ path: 'src' }) const entries = await directory.getEntries()
The new file system utilities offer clearer APIs, better performance, and improved developer experience. This is still experimental and API parity with the old collections API is still in progress. Please report any issues you encounter.
- New Classes:
-
7cbb112: Updates the
<Collection>.getSource
method to be asynchronous and return aPromise
that resolves to the source. This allows for more flexibility for a source to communicate with the web socket server.Breaking Changes
The
getSource
method for aCollection
andCompositeCollection
now returns aPromise
that resolves to the source. This means that you will need toawait
the result when calling this method:import { Collection } from 'renoun/collections' const posts = new Collection({ filePattern: 'posts/*.mdx', }) export default async function Page({ params }: { params: Promise<{ slug: string }> }) { -- const post = posts.getSource(params.slug) ++ const post = await posts.getSource(params.slug) if (!post) { return <div>Post not found</div> } const Content = await post.getExport('default').getValue() return <Content /> }
Minor Changes
-
b2ba1e4: Adds
renoun/server
export for more control of running the WebSocket server. For example, in Next.js this can be used with theinstrumentation.ts
file:import { createServer } from 'renoun/server' export async function register() { if ( process.env.NODE_ENV === 'development' && process.env.NEXT_RUNTIME === 'nodejs' ) { createServer() } }
Patch Changes
- 359e5e7: Fixes
APIReference
component not allowingFileSystemSource
. - ef4448e: Fixes client and server collections getting out of sync causing an error when resolving types from updated files.
- 7020585: Updates all dependencies to latest version.
- Updated dependencies [7020585]
- @renoun/[email protected]
@renoun/[email protected]
Patch Changes
- 7020585: Updates all dependencies to latest version.