Releases: souporserious/renoun
renoun@8.1.0
Minor Changes
- 339ef75: Aligns
CodeBlock
scroll container styles withCodeInline
.
Patch Changes
- 5390d03: Fixes Standard Schema types not working by copying them directly into the project.
- 94f53da: Fixes
CodeBlock
fallback layout shift during development. - 5a641b3: Fixes collapsed right padding for
CodeInline
when container is scrolled to the end. - ca25cd3: Fixes missing bottom padding for
CodeInline
in iOS Safari.
renoun@8.0.0
Major Changes
-
02facb1: Removes
renoun/collections
package export and all related types and utilities that were deprecated in v7.8.0.Breaking Changes
The
renoun/collections
package was removed. To upgrade, move to therenoun/file-system
package and use theDirectory
class instead. In most cases, you can replaceCollection
withDirectory
andCompositeCollection
withEntryGroup
.Before
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)
After
import { Directory, EntryGroup } from 'renoun/file-system' const docs = new Directory({ path: 'docs', include: '*.mdx', }) const components = new Directory({ path: 'src/components', include: '*.{ts,tsx}', }) const entryGroup = new EntryGroup({ entries: [docs, components], })
-
eda5977: Removes all
*OrThrow
methods fromDirectory
andEntryGroup
. This also exports two new custom errors,FileNotFoundError
andFileExportNotFoundError
to handle missing files and exports.Breaking Changes
Directory
andEntryGroup
no longer have*OrThrow
methods, use the respective methods instead. To get the same functionality as before, you can catch the error and handle it accordingly:import { Directory, FileNotFoundError } from 'renoun/file-system' const posts = new Directory({ path: 'posts' }) posts.getFile('hello-world', 'mdx').catch((error) => { if (error instanceof FileNotFoundError) { return undefined } throw error })
Minor Changes
-
fcd11af: Now
Directory#getParent
throws when called for the root directory. This makes the method easier to work with and aligns better withFile#getParent
always returning aDirectory
instance. -
71aa01f: Adds a default
mdx
loader toJavaScriptFile
that uses theMDXRenderer
component. This allows MDX files without imports to be rendered easily:import { Directory } from 'renoun/file-system' const posts = new Directory({ path: 'posts' }) export default async function Page({ params, }: { params: Promise<{ slug: string }> }) { const slug = (await params).slug const post = await posts.getFile(slug, 'mdx') const Content = await post.getExportValue('default') return <Content /> }
-
21a952a: Adds
File#getText
method for retrieving the text contents of the file. -
e107c2f: Allows instantiating
File
andJavaScriptFile
more easily using only apath
:import { JavaScriptFile } from 'renoun/file-system' const indexFile = new JavaScriptFile({ path: 'src/index.ts' }) const indexFileExports = await indexFile.getExports()
-
3298b6b: Refactors
Generic
kind that can be returned fromJavaScriptFileExport#getType
into two separateUtility
andUtilityReference
kinds. This is more explicit in how types are resolved based on where the type resolution starts from.// "Partial" is resolved as a "Utility" kind when starting from the type alias type Partial<Type> = { [Key in keyof Type]?: Type[Key] } // Whereas "Partial" here is resolved as a "UtilityReference" kind when resolved from within a type interface Props<Type> { options: Partial<Type> }
-
a470c98: Adds an overload to
Directory#getFile
that allows for querying files by their path including the extension instead of needing to provide the extension separately:const rootDirectory = new Directory() const file = await rootDirectory.getFile('tsconfig.json')
-
919b73d: Configures the JavaScript RegExp Engine for
shiki
. -
eb6a7f2: The WebSocket server now uses
.gitignore
to ignore watching files instead of a hardcoded array. -
213cc11: Adds an option for specifying the
port
number when usingcreateServer
fromrenoun/server
:import { createServer } from 'renoun/server' createServer({ port: 3001 })
-
b82df87: Allows File System type guards (
isDirectory
,isFile
,isJavaScriptFile
) to acceptundefined
. This saves from having to check if a file exists before checking its type. -
37cb7bb: Fixes running multiple renoun WebSocket servers by setting the port to
0
by default. This allows the OS to assign an available port. -
446effc: Exports
FileSystem
,MemoryFileSystem
, andNodeFileSystem
classes for creating custom file systems as well asRepository
for normalizing git providers.import { Directory, MemoryFileSystem } from 'renoun/file-system' const fileSystem = new MemoryFileSystem({ 'index.mdx': '# Hello, World!', }) const directory = new Directory({ fileSystem })
Patch Changes
- 8f64055: Fixes error when adding a file at a previously deleted path by flushing the file deletion immediately.
- 334f859: Fixes duplicate unions appearing in
JavaScriptFileExport#getType
. - 438dc94: Avoids creating duplicate watchers for the same directory.
- 1cc52b8: Fixes Webpack cache warning from dynamic prettier import by moving to require.
- ce751f1: Fixes non-exported types not being resolved.
- 7b90440: Fixes
getType
erroring when inferring a re-exported type. - 54eeb9e: Fixes duplicate exports when there are overloads.
- Updated dependencies [c394b9c]
- @renoun/mdx@1.3.1
@renoun/mdx@1.3.1
Patch Changes
- c394b9c: Moves
shiki
to dynamic import to avoid ESM require errors.
renoun@7.9.0
Minor Changes
-
3022d63: Renames
Directory
andFile
getParentDirectory
methods togetParent
to better align withgetSiblings
. This also aligns more closely with the web File System API's getParent method.Breaking Changes
Directory.getParentDirectory
is nowDirectory.getParent
File.getParentDirectory
is nowFile.getParent
-
ba2d5e1: Adds
pathCasing
option toDirectory
for setting the casing of all path methods. This is useful for ensuring that all paths are in a consistent casing, regardless of the underlying file system.import { Directory } from 'renoun/file-system' const directory = new Directory({ path: 'components', pathCasing: 'kebab', }) const file = await directory.getFileOrThrow('button') file.getPath() // '/button' const directory = await directory.getDirectoryOrThrow('card') directory.getPath() // '/card'
-
87e380b: Renames the
MDXContent
component toMDXRenderer
. This was causing confusion with theMDXContent
type exported fromrenoun/mdx
and better reflects the purpose of the component.Breaking Changes
- Rename any
MDXContent
component references fromrenoun/components
toMDXRenderer
.
- Rename any
-
4149b39: Refactors the
Directory
builder pattern to move back to an object configuration with the addition of a newwithSchema
helper, allowing strong type inference and colocated file export type definitions:import { Directory, withSchema } from 'renoun/file-system' import { z } from 'zod' export const Posts = new Directory({ path: 'posts', include: '*.mdx', loaders: { mdx: withSchema( { frontmatter: z.object({ title: z.string(), description: z.string(), date: z.date(), tags: z.array(z.string()).optional(), }), }, (path) => import(`@/posts/${path}.mdx`) ), }, })
Note, some additional changes have also been made:
withModule
has been replaced in favor of aloaders
option.withFilter
has been replaced by aninclude
option to better align with TypeScript's configuration naming.- The new
include
filter now also accepts a string glob file pattern e.g.*.mdx
. - An extension must be provided for loaders, this ensures that arbitrary file extensions are not loaded by mistake.
- Standard Schema is now used to automatically infer types from libraries that adhere to the spec (Zod, Valibot, Arktype).
- The
MDXContent
type is now included by default for MDX filedefault
exports. - Internally, the
JavaScriptFileWithRuntime
class was collapsed intoJavaScriptFile
. This was originally added to provide strong types when a runtime loader was or was not available, but caused too much complexity. In the future, a runtime loader will be added automatically if not explicitly defined.
Breaking Changes
The builder pattern configuration for
Directory
has been refactored to use an object configuration with the addition of a newwithSchema
helper. This change is breaking for any existing code that uses theDirectory
builder pattern. ThewithSchema
helper is now required to provide strong type inference and colocated file export type definitions.Before
import { Directory } from 'renoun/file-system' interface PostTypes { mdx: { default: MDXContent } } const posts = new Directory<PostTypes>('posts').withModule( (path) => import(`./posts/${path}`) )
After
import { Directory } from 'renoun/file-system' const posts = new Directory({ path: 'posts', loaders: { mdx: (path) => import(`./posts/${path}.mdx`), }, })
-
80ae7f2: Marks the
Directory#duplicate
method as private since this was previously only exposed forEntryGroup
which no longer requires a new instance to be created. -
1f6603d: Removes
getEditPath
in favor ofgetEditUrl
andgetEditorUri
for a more explicit API. Prior, thegetEditPath
method switched between the editor and the git provider source based on the environment. This was confusing and not always the desired behavior. Now you can explicitly choose the behavior you want.Breaking Changes
The
getEditPath
method has been removed. UsegetEditUrl
andgetEditorUri
instead.To get the same behavior as
getEditPath
you can use bothgetEditUrl
andgetEditorUri
together:import { Directory } from 'renoun/file-system' const directory = new Directory('src/components') const file = directory.getFileOrThrow('Button', 'tsx') const editUrl = process.env.NODE_ENV === 'development' ? file.getEditorUri() : file.getEditUrl()
-
97bc268: Renames
@renoun/mdx
Headings
type toMDXHeadings
. This adds better clarity and consistency with the otherMDX
prefixed types.Breaking Changes
- Rename any
Headings
references from@renoun/mdx
toMDXHeadings
.
- Rename any
Patch Changes
-
5d8bd25: Fixes nested ordered files not using a unique key causing them to be filtered.
-
dc323ab: Closes WebSocket connections with a code allowing the Node process to properly exit. More info here.
-
679da2c: Fixes
Directory#getFile
not considering file name modifiers.const directory = new Directory({ path: 'components' }) const file = await directory.getFileOrThrow(['APIReference', 'examples']) file.getAbsolutePath() // '/APIReference.examples.tsx'
-
5b558c1: Fixes
Directory#getFile
not prioritizing base files over files with modifiers e.g.Button.tsx
overButton.examples.tsx
. -
Updated dependencies [ece3cc2]
-
Updated dependencies [97bc268]
-
Updated dependencies [df4d29d]
- @renoun/mdx@1.3.0
@renoun/mdx@1.3.0
Minor Changes
-
97bc268: Renames
@renoun/mdx
Headings
type toMDXHeadings
. This adds better clarity and consistency with the otherMDX
prefixed types.Breaking Changes
- Rename any
Headings
references from@renoun/mdx
toMDXHeadings
.
- Rename any
Patch Changes
renoun@7.8.0
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.
renoun@7.7.0
Minor Changes
- a1aa042: Removes managing of auto-generated dynamic imports for collections as this was causing issues with build processes.
Patch Changes
renoun@7.6.0
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.
renoun@7.5.0
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.
renoun@7.4.0
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
.