Skip to content

Releases: souporserious/renoun

[email protected]

30 Dec 22:24
3eff7f9
Compare
Choose a tag to compare

Minor Changes

  • 3022d63: Renames Directory and File getParentDirectory methods to getParent to better align with getSiblings. This also aligns more closely with the web File System API's getParent method.

    Breaking Changes

    • Directory.getParentDirectory is now Directory.getParent
    • File.getParentDirectory is now File.getParent
  • ba2d5e1: Adds pathCasing option to Directory 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 to MDXRenderer. This was causing confusion with the MDXContent type exported from renoun/mdx and better reflects the purpose of the component.

    Breaking Changes

    • Rename any MDXContent component references from renoun/components to MDXRenderer.
  • 4149b39: Refactors the Directory builder pattern to move back to an object configuration with the addition of a new withSchema 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 a loaders option.
    • withFilter has been replaced by an include 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 file default exports.
    • Internally, the JavaScriptFileWithRuntime class was collapsed into JavaScriptFile. 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 new withSchema helper. This change is breaking for any existing code that uses the Directory builder pattern. The withSchema 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 for EntryGroup which no longer requires a new instance to be created.

  • 1f6603d: Removes getEditPath in favor of getEditUrl and getEditorUri for a more explicit API. Prior, the getEditPath 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. Use getEditUrl and getEditorUri instead.

    To get the same behavior as getEditPath you can use both getEditUrl and getEditorUri 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 to MDXHeadings. This adds better clarity and consistency with the other MDX prefixed types.

    Breaking Changes

    • Rename any Headings references from @renoun/mdx to MDXHeadings.

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 over Button.examples.tsx.

  • Updated dependencies [ece3cc2]

  • Updated dependencies [97bc268]

  • Updated dependencies [df4d29d]

@renoun/[email protected]

30 Dec 22:24
3eff7f9
Compare
Choose a tag to compare

Minor Changes

  • 97bc268: Renames @renoun/mdx Headings type to MDXHeadings. This adds better clarity and consistency with the other MDX prefixed types.

    Breaking Changes

    • Rename any Headings references from @renoun/mdx to MDXHeadings.

Patch Changes

  • ece3cc2: Fixes inline code language inference by considering language aliases.
  • df4d29d: Removes mdast dependency. This was added by mistake and is not needed since @types/mdast is already a dependency.

[email protected]

06 Dec 19:47
7a8780f
Compare
Choose a tag to compare

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 to await all methods like getName, getDescription, and getTags. Additionally, this adds a new <JavaScriptFile>.hasExport method for checking if the file has a specific export.

  • 9cf4499: Deprecates Collection, CompositeCollection, isExportSource, isFileSystemSource, and isCollectionSource. These will be removed in the next major version.

    Updating to File System utilities

    The Collection and CompositeCollection classes have been deprecated in favor of the new renoun/file-system utilities. The isExportSource, isFileSystemSource, and isCollectionSource functions have also been deprecated.

    To update your code, replace any instances of Collection with Directory and CompositeCollection with EntryGroup. 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 to false by default. This option allows control over deduplicating entries with the same base name e.g. Button.mdx and Button.tsx.

  • 7d56e9a: Adds getSlug method to Directory, File, and JavaScriptExport.

  • 3419623: Adds getExportValue and getExportValueOrThrow methods to JavaScriptFile as a shortcut to getting an export's runtime value since this is a common use case.

  • 91d9b51: Removes isFileWithExtension and reimplements it within isFile which now allows an optional second extension argument.

    Breaking Changes

    To upgrade, replace all instances of isFileWithExtension with isFile. Previous usage of isFile will still work as expected.

  • 4279d19: Adds includeDuplicateSegments configuration option for <File>.getPath method that is set to false by default. This option allows including consecutive duplicate segments in the returned path.

  • 92c5dee: Enables passing tsConfigPath option to Directory.

  • 4f843e4: Adds isJavaScriptFile and isJavaScriptFileWithRuntime type guards for JavaScript-like files.

  • 50e094b: Adds getPosition and getText methods to JavaScriptExport.

  • c4d274c: Moves the Directory getImport option to <Directory>.withModule. This provides stronger types for inferring the getRuntimeValue method.

    Breaking Changes

    Update the getImport option to withModule:

    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 of Directory options.

    Breaking Changes

    Update the schema option to withSchema:

    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 other Directory options.

    Breaking Changes

    Update the basePath option to withBasePath:

    export const posts = new Directory<{ mdx: PostType }>({
        path: 'posts',
    --    basePath: 'blog',
    })
    ++  .withBasePath('blog')
  • 8252c4b: Adds getTitle method to Directory and FileName classes.

  • 2e7f458: Adds an EntryGroup utility to renoun/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 the EntryGroup 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 and hasFile methods to Directory which can be used to check if an entry or file exists in an EntryGroup:

    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 to Directory and File.

  • 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 to Directory.

  • 155f2e7: Renames file system methods filter to withFilter and sort to withSort 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 and includeTsConfigIgnoredFiles options to <Directory>.getEntries. These options allow you to include files that are ignored by .gitignore and tsconfig.json respectively.

  • 66f8289: Adds the ability to specify only the path when initializing a Directory 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 the entry 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 and File 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 use verbatimModuleSyntax.

  • c160fba: Fixes filtering of Directory entries based on tsconfig exclude field.

[email protected]

21 Nov 23:36
1c715a5
Compare
Choose a tag to compare

Minor Changes

  • a1aa042: Removes managing of auto-generated dynamic imports for collections as this was causing issues with build processes.

Patch Changes

  • f2e5608: Fixes getAbsolutePath and getEditPath for Directory.
  • c59cd9c: Normalizes pathSegments to remove order prefix.
  • 784945a: Normalizes incoming path for readDirectory in VirtualFileSystem to match Node.js behavior.

[email protected]

20 Nov 18:20
Compare
Choose a tag to compare

Minor Changes

  • 0c67c7c: Removes isJavaScriptFile type guard in favor of isFileWithExtension that narrows types better.

  • bf56af0: Adds support for passing JavaScriptFile and JavaScriptFileExport to the APIReference component.

  • 4fc9781: Returns a JavaScriptExport instance now from getExports to align with getExport.

  • 73bb769: Adds Fast Refresh to <JavaScriptExport>.getRuntimeValue for Next.js.

  • 3eec7ff: Removes getDirectories and getFiles from Directory now that the filter 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 the isFileWithExtension type guard to consolidate the API.

Patch Changes

  • 8d2b7f3: Fixes the <Directory>.getEntries method recursive option not considering nested entries.

[email protected]

19 Nov 20:14
49d875d
Compare
Choose a tag to compare

Minor Changes

  • abb441d: Improves error handling for the CodeBlock component when falsey values are provided.

  • 0b6e426: Adds sort method to Directory 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 to Directory 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 a projectId added to the base FileSystem class. This ensures the TypeScript project is unique to the virtual file system it is instantiated with.

Patch Changes

  • 1c77620: Fixes the <Directory>.getEntries method recursive option to only recurse in getEntries instead of the file system.

[email protected]

18 Nov 20:13
8f463b2
Compare
Choose a tag to compare

Minor Changes

  • e71de2f: Adds shouldFormat prop to CodeBlock 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

  • bf0c510: Fixes File System recursive options not calculating the appropriate relative paths.
  • eab583f: Explicitly sets the prettier parser option instead of relying on inference from filepath to avoid false-positive errors when parsing code blocks without a provided filename.

[email protected]

16 Nov 23:51
6fec13d
Compare
Choose a tag to compare

Minor Changes

  • 4c1f7d5: Adds recursive option to getEntries, getDirectories, and getFiles.
  • ff8d9ae: Implements getType for JavaScriptFileExport.

Patch Changes

  • 51506d8: Fixes internal resolveType utility trimming the filePath in getType incorrectly.
  • d83d265: Fixes order prefixes being added to File System getPath methods.

[email protected]

16 Nov 10:26
a8cf202
Compare
Choose a tag to compare

Minor Changes

  • 9d67bdf: Add getFiles and getDirectories to Directory.

  • 1bd1de3: Adds hasExtension method to File 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 to getEntries for controlling default filtering of index and readme 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 to JavaScriptFileExport.

[email protected]

16 Nov 02:00
589e36a
Compare
Choose a tag to compare

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 for CodeInline component to prevent type errors.