Skip to content

Commit

Permalink
[nextra] sort defaultMeta by frontMatter.date, if missing by `fro…
Browse files Browse the repository at this point in the history
…ntMatter.title` and after by capitalized page name + TESTS 🧪 (#894)

* sort `defaultMeta` by `frontMatter.date`, if missing by `frontMatter.title` and after by page name

* refactor to have less code

* Update .changeset/tender-papayas-walk.md

* Apply suggestions from code review

* capitalize sidebar's folders names if item is missing in `_meta.json` (#895)
  • Loading branch information
dimaMachina committed Oct 20, 2022
1 parent 21c8320 commit 094fdec
Show file tree
Hide file tree
Showing 6 changed files with 130 additions and 10 deletions.
5 changes: 5 additions & 0 deletions .changeset/tender-papayas-walk.md
@@ -0,0 +1,5 @@
---
'nextra': patch
---

sort `defaultMeta` by `frontMatter.date`, if missing by `frontMatter.title` and after by capitalized page name
5 changes: 5 additions & 0 deletions .changeset/wet-trainers-sleep.md
@@ -0,0 +1,5 @@
---
'nextra': patch
---

capitalize sidebar's folders names if item is missing in `_meta.json`
6 changes: 6 additions & 0 deletions packages/nextra/__test__/__snapshots__/page-map.test.ts.snap
Expand Up @@ -560,6 +560,10 @@ exports[`Page Process > pageMap en-US 1`] = `
"data": {
"404": "404",
"500": "500",
"about": "About",
"blog": "Blog",
"docs": "Docs",
"examples": "Examples",
},
"kind": "Meta",
},
Expand All @@ -574,6 +578,7 @@ exports[`Page Process > pageMap zh-CN 1`] = `
[
{
"data": {
"about": "About",
"blog": {
"title": "博客",
"type": "page",
Expand Down Expand Up @@ -693,6 +698,7 @@ exports[`Page Process > pageMap zh-CN 1`] = `
"data": {
"cache": "缓存",
"file-name.with.DOTS": "带点的文件名",
"more": "More",
"performance": "性能",
"react-native": "React Native",
},
Expand Down
71 changes: 71 additions & 0 deletions packages/nextra/__test__/sort-pages.test.ts
@@ -0,0 +1,71 @@
import { describe, expect, it } from 'vitest'
import { sortPages } from '../src/utils'

const kind = 'MdxPage'

describe('sortPages()', () => {
it('should sort by date', () => {
const data = sortPages([
{ kind, name: 'baz', frontMatter: { date: new Date('1995-10-21') } },
{ kind, name: 'foo', frontMatter: { date: new Date('1992-10-21') } },
{ kind, name: 'quz', frontMatter: { date: new Date('1998-10-21') } }
])
expect(data).toEqual([
['quz', 'Quz'],
['baz', 'Baz'],
['foo', 'Foo']
])
})

it('should sort by date first and after by title', () => {
const data = sortPages([
{ kind, name: 'quz' },
{ kind, name: 'foo', frontMatter: { date: new Date('1992-10-21') } },
{ kind, name: 'baz' }
])
expect(data).toEqual([
['foo', 'Foo'],
['baz', 'Baz'],
['quz', 'Quz']
])
})

it('should take priority `frontMatter.title` over name', () => {
const data = sortPages([
{ kind, name: 'baz' },
{ kind, name: 'foo', frontMatter: { title: 'abc' } },
{ kind, name: 'quz' }
])
expect(data).toEqual([
['foo', 'abc'],
['baz', 'Baz'],
['quz', 'Quz']
])
})

it('should sort numeric', () => {
const data = sortPages([
{ kind, name: '10-baz' },
{ kind, name: '0-foo' },
{ kind, name: '2.5-quz' }
])
expect(data).toEqual([
['0-foo', '0 Foo'],
['2.5-quz', '2.5 Quz'],
['10-baz', '10 Baz']
])
})

it('should capitalize `Folder`', () => {
const data = sortPages([
{ kind, name: 'quz' },
{ kind: 'Folder', name: 'foo' },
{ kind, name: 'baz' }
])
expect(data).toEqual([
['baz', 'Baz'],
['foo', 'Foo'],
['quz', 'Quz']
])
})
})
19 changes: 10 additions & 9 deletions packages/nextra/src/plugin.ts
Expand Up @@ -10,7 +10,7 @@ import {
} from './types'
import fs from 'graceful-fs'
import { promisify } from 'node:util'
import { parseFileName, parseJsonFile, truthy } from './utils'
import { parseFileName, parseJsonFile, sortPages, truthy } from './utils'
import path from 'node:path'
import slash from 'slash'
import grayMatter from 'gray-matter'
Expand Down Expand Up @@ -98,23 +98,24 @@ export async function collectFiles(
const items = (await Promise.all(promises)).filter(truthy)

const mdxPages = items.filter(
(item): item is MdxFile => item.kind === 'MdxPage'
(item): item is MdxFile | Folder =>
item.kind === 'MdxPage' || item.kind === 'Folder'
)
const locales = mdxPages.map(item => item.locale)
const locales = mdxPages
.filter((item): item is MdxFile => item.kind === 'MdxPage')
.map(item => item.locale)

for (const locale of locales) {
const metaIndex = items.findIndex(
item => item.kind === 'Meta' && item.locale === locale
)
const defaultMeta: [string, string][] = mdxPages
.filter(item => item.locale === locale)
.map(item => [
item.name,
item.frontMatter?.title || title(item.name.replace(/[-_]/g, ' '))
])

const defaultMeta = sortPages(mdxPages, locale)

const metaFilename = locale
? META_FILENAME.replace('.', `.${locale}.`)
: META_FILENAME

const metaPath = path.join(dir, metaFilename) as MetaJsonPath

if (metaIndex === -1) {
Expand Down
34 changes: 33 additions & 1 deletion packages/nextra/src/utils.ts
@@ -1,6 +1,7 @@
import path from 'node:path'
import title from 'title'
import { LOCALE_REGEX } from './constants'
import { Meta } from './types'
import { Folder, MdxFile, Meta } from './types'

export function parseFileName(filePath: string): {
name: string
Expand Down Expand Up @@ -41,3 +42,34 @@ export function truthy<T>(value: T): value is Truthy<T> {
export function normalizeMeta(meta: Meta): Exclude<Meta, string> {
return typeof meta === 'string' ? { title: meta } : meta
}

export function sortPages(
pages: (
| Pick<MdxFile, 'kind' | 'name' | 'frontMatter' | 'locale'>
| Pick<Folder, 'kind' | 'name'>
)[],
locale?: string
): [string, string][] {
return pages
.filter(item => item.kind === 'Folder' || item.locale === locale)
.map(item => ({
name: item.name,
date: 'frontMatter' in item && item.frontMatter?.date,
title:
('frontMatter' in item && item.frontMatter?.title) ||
title(item.name.replace(/[-_]/g, ' '))
}))
.sort((a, b) => {
if (a.date && b.date) {
return new Date(b.date).getTime() - new Date(a.date).getTime()
}
if (a.date) {
return -1 // sort a before b
}
if (b.date) {
return 1 // sort a after b
}
return a.title.localeCompare(b.title, locale, { numeric: true })
})
.map(item => [item.name, item.title])
}

0 comments on commit 094fdec

Please sign in to comment.