diff --git a/astro.config.mjs b/astro.config.mjs index 1fa06c2..bbb379f 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -1,25 +1,25 @@ -import { defineConfig } from 'astro/config'; +import { defineConfig } from "astro/config"; -import rehypeSanitize from 'rehype-sanitize'; -import rehypeStringify from 'rehype-stringify'; -import rehypeRaw from 'rehype-raw'; -import remarkParse from 'remark-parse'; -import remarkRehype from 'remark-rehype'; +import rehypeSanitize from "rehype-sanitize"; +import rehypeStringify from "rehype-stringify"; +import rehypeRaw from "rehype-raw"; +import remarkParse from "remark-parse"; +import remarkRehype from "remark-rehype"; // https://astro.build/config export default defineConfig({ - markdown: { - remarkRehype: { - allowDangerousHtml: true - // This is fine because we are using rehypeSanitize to sanitize XSS. - // See https://github.com/remarkjs/remark-rehype?tab=readme-ov-file#example-supporting-html-in-markdown-properly - }, - remarkPlugins: [ - remarkParse, - remarkRehype, - rehypeRaw, - rehypeSanitize, - rehypeStringify, - ] - } + markdown: { + remarkRehype: { + allowDangerousHtml: true, + // This is fine because we are using rehypeSanitize to sanitize XSS. + // See https://github.com/remarkjs/remark-rehype?tab=readme-ov-file#example-supporting-html-in-markdown-properly + }, + remarkPlugins: [ + remarkParse, + remarkRehype, + rehypeRaw, + rehypeSanitize, + rehypeStringify, + ], + }, }); diff --git a/flake.nix b/flake.nix index acd0a04..49360a5 100644 --- a/flake.nix +++ b/flake.nix @@ -28,11 +28,14 @@ namespace = "auxolotl--docs-site"; }; - outputs-builder = channels: let - treefmt = inputs.treefmt-nix.lib.evalModule channels.nixpkgs ./treefmt.nix; - in { - formatter = treefmt.config.build.wrapper; - checks.formatting = treefmt.config.build.check inputs.self; - }; + outputs-builder = + channels: + let + treefmt = inputs.treefmt-nix.lib.evalModule channels.nixpkgs ./treefmt.nix; + in + { + formatter = treefmt.config.build.wrapper; + checks.formatting = treefmt.config.build.check inputs.self; + }; }; } diff --git a/src/components/Renderer.astro b/src/components/Renderer.astro index 4726331..fa2ce1c 100644 --- a/src/components/Renderer.astro +++ b/src/components/Renderer.astro @@ -13,4 +13,4 @@ const { Content } = await post.render();
-
\ No newline at end of file +s diff --git a/src/lib/pagePaths.test.ts b/src/lib/pagePaths.test.ts index 64a6d29..be52d6f 100644 --- a/src/lib/pagePaths.test.ts +++ b/src/lib/pagePaths.test.ts @@ -1,1384 +1,1405 @@ import { it, expect, describe } from "vitest"; -import { allPageAndDirectoryPaths, relativePagePaths, type PageLinkData } from "./pagePaths"; +import { + allPageAndDirectoryPaths, + relativePagePaths, + type PageLinkData, +} from "./pagePaths"; import type { CollectionEntry } from "astro:content"; describe("relativePagePaths", () => { - it("returns the current page when it does not exist in the set", () => { - // Act - const result = relativePagePaths([], "current"); + it("returns the current page when it does not exist in the set", () => { + // Act + const result = relativePagePaths([], "current"); - // Assert - const currentPage: PageLinkData = { - id: "current", - data: { title: "current" } - }; - expect(result.currentPage).toMatchObject(currentPage); + // Assert + const currentPage: PageLinkData = { + id: "current", + data: { title: "current" }, + }; + expect(result.currentPage).toMatchObject(currentPage); + }); + + it("returns the current page when it exists in the set", () => { + // Arrange + const currentPage: PageLinkData = { + id: "current", + data: { title: "Current Page" }, + }; + + // Act + const result = relativePagePaths([currentPage], "current"); + + // Assert + expect(result.currentPage).toMatchObject(currentPage); + }); + + it("returns the current page when it exists in the set and there are other pages in the set", () => { + // Arrange + const currentPage: PageLinkData = { + id: "current", + data: { title: "Current Page" }, + }; + const otherPage: PageLinkData = { + id: "notcurrent", + data: { title: "Should not be the current page" }, + }; + + // Act + const result = relativePagePaths( + [otherPage, currentPage, otherPage, otherPage], + "current", + ); + + // Assert + expect(result.currentPage).toMatchObject(currentPage); + }); + + it("returns the current page when it does not exist in the set but there are other pages in the set", () => { + // Arrange + const otherPage: PageLinkData = { + id: "notcurrent", + data: { title: "Should not be the current page" }, + }; + + // Act + const result = relativePagePaths( + [otherPage, otherPage, otherPage], + "current", + ); + + // Assert + const currentPage: PageLinkData = { + id: "current", + data: { title: "current" }, + }; + expect(result.currentPage).toMatchObject(currentPage); + }); + + it("returns pages in the same directory as siblingPages when the directory is /", () => { + // Arrange + const currentPage: PageLinkData = { + id: "current", + data: { title: "Current Page" }, + }; + const otherPages: PageLinkData[] = [ + { + id: "notcurrent", + data: { title: "Should not be the current page" }, + }, + { + id: "alsonotcurrent", + data: { title: "Should also not be the current page" }, + }, + { + id: "notcurrent2", + data: { title: "Should still not be the current page" }, + }, + ]; + + // Act + const result = relativePagePaths([currentPage, ...otherPages], "current"); + + // Assert + expect(result.siblingPages).toEqual(expect.arrayContaining(otherPages)); + expect(result.siblingPages).toHaveLength(otherPages.length); + }); + + it("returns pages in the same directory as siblingPages when the directory is not /", () => { + // Arrange + const currentPage: PageLinkData = { + id: "thisdir/current", + data: { title: "Current Page" }, + }; + const otherPages: PageLinkData[] = [ + { + id: "thisdir/notcurrent", + data: { title: "Should not be the current page" }, + }, + { + id: "thisdir/alsonotcurrent", + data: { title: "Should also not be the current page" }, + }, + { + id: "thisdir/notcurrent2", + data: { title: "Should still not be the current page" }, + }, + ]; + + // Act + const result = relativePagePaths( + [currentPage, ...otherPages], + "thisdir/current", + ); + + // Assert + expect(result.siblingPages).toEqual(expect.arrayContaining(otherPages)); + expect(result.siblingPages).toHaveLength(otherPages.length); + }); + + it("does not return pages in different directories as siblingPages when the directory is /", () => { + // Arrange + const currentPage: PageLinkData = { + id: "current", + data: { title: "Current Page" }, + }; + const otherPages: PageLinkData[] = [ + { + id: "otherdir/notcurrent", + data: { title: "Should not be the current page" }, + }, + { + id: "current/child", + data: { title: "Not a sibling!" }, + }, + { + id: "thisdir/lowerdown/notcurrent2", + data: { title: "Should still not be the current page" }, + }, + ]; + + // Act + const result = relativePagePaths([currentPage, ...otherPages], "current"); + + // Assert + expect(result.siblingPages).toEqual([]); + }); + + it("does not return pages in different directories as siblingPages when the directory is not /", () => { + // Arrange + const currentPage: PageLinkData = { + id: "thisdir/current", + data: { title: "Current Page" }, + }; + const otherPages: PageLinkData[] = [ + { + id: "otherdir/notcurrent", + data: { title: "Should not be the current page" }, + }, + { + id: "alsonotcurrent", + data: { title: "Should also not be the current page" }, + }, + { + id: "thisdir/current/child", + data: { title: "Not a sibling!" }, + }, + { + id: "thisdir/lowerdown/notcurrent2", + data: { title: "Should still not be the current page" }, + }, + ]; + + // Act + const result = relativePagePaths( + [currentPage, ...otherPages], + "thisdir/current", + ); + + // Assert + expect(result.siblingPages).toEqual([]); + }); + + it("returns exclusively pages which are direct children when dir is /", () => { + // Arrange + const currentPage: PageLinkData = { + id: "current", + data: { title: "Current Page" }, + }; + const otherPages: PageLinkData[] = [ + { + id: "otherdir/notcurrent", + data: { title: "Should not be the current page" }, + }, + { + id: "alsonotcurrent", + data: { title: "Should also not be the current page" }, + }, + { + id: "somedir/lowerdown/notcurrent2", + data: { title: "Should still not be the current page" }, + }, + { + id: "current/child2/level2", + data: { title: "A 2nd-level child!" }, + }, + ]; + const childPages: PageLinkData[] = [ + { + id: "current/child", + data: { title: "A child!" }, + }, + ]; + + // Act + const result = relativePagePaths( + [currentPage, ...otherPages, ...childPages], + "current", + ); + + // Assert + expect(result.childPages).toEqual(expect.arrayContaining(childPages)); + expect(result.childPages).toHaveLength(childPages.length); + }); + + it("returns exclusively pages which are direct children when dir is not /", () => { + // Arrange + const currentPage: PageLinkData = { + id: "thisdir/current", + data: { title: "Current Page" }, + }; + const otherPages: PageLinkData[] = [ + { + id: "otherdir/notcurrent", + data: { title: "Should not be the current page" }, + }, + { + id: "alsonotcurrent", + data: { title: "Should also not be the current page" }, + }, + { + id: "thisdir/lowerdown/notcurrent2", + data: { title: "Should still not be the current page" }, + }, + { + id: "thisdir/current/child2/level2", + data: { title: "A 2nd-level child!" }, + }, + ]; + const childPages: PageLinkData[] = [ + { + id: "thisdir/current/child", + data: { title: "A child!" }, + }, + ]; + + // Act + const result = relativePagePaths( + [currentPage, ...otherPages, ...childPages], + "thisdir/current", + ); + + // Assert + expect(result.childPages).toEqual(expect.arrayContaining(childPages)); + expect(result.childPages).toHaveLength(childPages.length); + }); + + it("returns nonempty directories which are direct children when dir is not /", () => { + // Arrange + const pages: PageLinkData[] = [ + { + id: "thisdir/current/child/level2.1", + data: { title: "level2.1" }, + }, + { + id: "thisdir/current/child/level2.2", + data: { title: "level2.2" }, + }, + { + id: "thisdir/current/child/level2/level3", + data: { title: "level3.1" }, + }, + { + id: "thisdir/current/child2/level2/level3", + data: { title: "level3.2" }, + }, + { + id: "thisdir/current/child3", + data: { title: "just a child 3 page" }, + }, + { + id: "thisdir/current/child3/level2/level3", + data: { title: "level3.3" }, + }, + ]; + + // Act + const result = relativePagePaths(pages, "thisdir/current"); + + // Assert + const childDirectories: PageLinkData[] = [ + { + id: "thisdir/current/child", + data: { title: "child" }, + }, + { + id: "thisdir/current/child2", + data: { title: "child2" }, + }, + { + id: "thisdir/current/child3", + data: { title: "just a child 3 page" }, + }, + ]; + expect(result.childDirectories).toEqual( + expect.arrayContaining(childDirectories), + ); + expect(result.childDirectories).toHaveLength(childDirectories.length); + }); + + it("returns nonempty directories which are direct children when dir is /", () => { + // Arrange + const pages: PageLinkData[] = [ + { + id: "current/child/level2.1", + data: { title: "level2.1" }, + }, + { + id: "current/child/level2.2", + data: { title: "level2.2" }, + }, + { + id: "current/child/level2/level3", + data: { title: "level3.1" }, + }, + { + id: "current/child2/level2/level3", + data: { title: "level3.2" }, + }, + { + id: "current/child3", + data: { title: "just a child 3 page" }, + }, + { + id: "current/child3/level2/level3", + data: { title: "level3.3" }, + }, + { + id: "sibling/dir", + data: { title: "siblingdirpage" }, + }, + ]; + + // Act + const result = relativePagePaths(pages, "current"); + + // Assert + const childDirectories: PageLinkData[] = [ + { + id: "current/child", + data: { title: "child" }, + }, + { + id: "current/child2", + data: { title: "child2" }, + }, + { + id: "current/child3", + data: { title: "just a child 3 page" }, + }, + ]; + expect(result.childDirectories).toEqual( + expect.arrayContaining(childDirectories), + ); + expect(result.childDirectories).toHaveLength(childDirectories.length); + }); + + it("returns sibling directories when dir is not /", () => { + // Arrange + const pages: PageLinkData[] = [ + { + id: "dir/sibling/level2.1", + data: { title: "level2.1" }, + }, + { + id: "dir/sibling/level2.2", + data: { title: "level2.2" }, + }, + { + id: "dir/sibling/level2/level3", + data: { title: "level3.1" }, + }, + { + id: "dir/sibling2/level2/level3", + data: { title: "level3.2" }, + }, + { + id: "dir/sibling3", + data: { title: "just a sibling 3 page" }, + }, + { + id: "dir/sibling3/level2/level3", + data: { title: "level3.3" }, + }, + ]; + + // Act + const result = relativePagePaths(pages, "dir/current"); + + // Assert + const siblingDirectories: PageLinkData[] = [ + { + id: "dir/sibling", + data: { title: "sibling" }, + }, + { + id: "dir/sibling2", + data: { title: "sibling2" }, + }, + { + id: "dir/sibling3", + data: { title: "just a sibling 3 page" }, + }, + ]; + expect(result.siblingDirectories).toEqual( + expect.arrayContaining(siblingDirectories), + ); + expect(result.siblingDirectories).toHaveLength(siblingDirectories.length); + }); + + it("returns sibling directories when dir is /", () => { + // Arrange + const pages: PageLinkData[] = [ + { + id: "sibling/level2.1", + data: { title: "level2.1" }, + }, + { + id: "sibling/level2.2", + data: { title: "level2.2" }, + }, + { + id: "sibling/level2/level3", + data: { title: "level3.1" }, + }, + { + id: "sibling2/level2/level3", + data: { title: "level3.2" }, + }, + { + id: "sibling3", + data: { title: "just a sibling 3 page" }, + }, + { + id: "sibling3/level2/level3", + data: { title: "level3.3" }, + }, + ]; + + // Act + const result = relativePagePaths(pages, "current"); + + // Assert + const siblingDirectories: PageLinkData[] = [ + { + id: "sibling", + data: { title: "sibling" }, + }, + { + id: "sibling2", + data: { title: "sibling2" }, + }, + { + id: "sibling3", + data: { title: "just a sibling 3 page" }, + }, + ]; + expect(result.siblingDirectories).toEqual( + expect.arrayContaining(siblingDirectories), + ); + expect(result.siblingDirectories).toHaveLength(siblingDirectories.length); + }); + + it("does not return siblingPages pages for directories on the same level", () => { + // Arrange + const pages: PageLinkData[] = [ + { + id: "sibling/level2.1", + data: { title: "level2.1" }, + }, + { + id: "sibling/level2.2", + data: { title: "level2.2" }, + }, + { + id: "sibling/level2/level3", + data: { title: "level3.1" }, + }, + { + id: "sibling2/level2/level3", + data: { title: "level3.2" }, + }, + { + id: "sibling3", + data: { title: "just a sibling 3 page" }, + }, + { + id: "sibling3/level2/level3", + data: { title: "level3.3" }, + }, + ]; + + // Act + const result = relativePagePaths(pages, "current"); + + // Assert + expect(result.siblingPages).toEqual([]); + }); + + it("does not return childPages pages for directories which are direct children", () => { + // Arrange + const pages: PageLinkData[] = [ + { + id: "thisdir/current/child/level2.1", + data: { title: "level2.1" }, + }, + { + id: "thisdir/current/child/level2.2", + data: { title: "level2.2" }, + }, + { + id: "thisdir/current/child/level2/level3", + data: { title: "level3.1" }, + }, + { + id: "thisdir/current/child2/level2/level3", + data: { title: "level3.2" }, + }, + { + id: "thisdir/current/child3", + data: { title: "just a child 3 page" }, + }, + { + id: "thisdir/current/child3/level2/level3", + data: { title: "level3.3" }, + }, + ]; + + // Act + const result = relativePagePaths(pages, "thisdir/current"); + + // Assert + expect(result.childPages).toEqual([]); + }); + + it("returns directories which are direct children but only have subdirectories", () => { + // Arrange + const pages: PageLinkData[] = [ + { + id: "current/child/subdirectory/second_subdirectory/page", + data: { title: "deeply nested page" }, + }, + ]; + + // Act + const result = relativePagePaths(pages, "current"); + + // Assert + const childDirectories: PageLinkData[] = [ + { + id: "current/child", + data: { title: "child" }, + }, + ]; + expect(result.childDirectories).toEqual( + expect.arrayContaining(childDirectories), + ); + expect(result.childDirectories).toHaveLength(childDirectories.length); + }); + + it("returns directories which are siblings but only have subdirectories", () => { + // Arrange + const pages: PageLinkData[] = [ + { + id: "sibling/subdirectory/second_subdirectory/page", + data: { title: "deeply nested page" }, + }, + ]; + + // Act + const result = relativePagePaths(pages, "current"); + + // Assert + const siblingDirectories: PageLinkData[] = [ + { + id: "sibling", + data: { title: "sibling" }, + }, + ]; + expect(result.siblingDirectories).toEqual( + expect.arrayContaining(siblingDirectories), + ); + expect(result.siblingDirectories).toHaveLength(siblingDirectories.length); + }); + + it("returns a generic parentDirectory if there is no page there", () => { + // Act + const result = relativePagePaths([], "some/dir/current"); + + // Assert + expect(result.parentDirectory).toEqual({ + id: "some/dir", + data: { title: "dir" }, }); + }); - it("returns the current page when it exists in the set", () => { - // Arrange - const currentPage: PageLinkData = { - id: "current", - data: { title: "Current Page" } - }; + it("returns a specific parent directory if there is a page there", () => { + // Arrange + const parentDirectory: PageLinkData = { + id: "some/dir", + data: { title: "A Parent Directory Page" }, + }; - // Act - const result = relativePagePaths([currentPage], "current"); + // Act + const result = relativePagePaths([parentDirectory], "some/dir/current"); - // Assert - expect(result.currentPage).toMatchObject(currentPage); + // Assert + expect(result.parentDirectory).toEqual(parentDirectory); + }); + + it("returns parentDirectory null if we are at the top directory", () => { + // Act + const result = relativePagePaths([], "current"); + + // Assert + expect(result.parentDirectory).toEqual(null); + }); + + it("(.md extensions) returns the current page when it exists in the set", () => { + // Arrange + const currentPage: PageLinkData = { + id: "current.md", + data: { title: "Current Page" }, + }; + + // Act + const result = relativePagePaths([currentPage], "current"); + + // Assert + expect(result.currentPage).toMatchObject(currentPage); + }); + + it("(.md extensions, .md currentPage) returns the current page when it exists in the set", () => { + // Arrange + const currentPage: PageLinkData = { + id: "current.md", + data: { title: "Current Page" }, + }; + + // Act + const result = relativePagePaths([currentPage], "current.md"); + + // Assert + expect(result.currentPage).toMatchObject(currentPage); + }); + + it("(.md currentPage only) returns the current page when it exists in the set", () => { + // Arrange + const currentPage: PageLinkData = { + id: "current", + data: { title: "Current Page" }, + }; + + // Act + const result = relativePagePaths([currentPage], "current.md"); + + // Assert + expect(result.currentPage).toMatchObject(currentPage); + }); + + it("(.md extensions) returns the current page when it exists in the set and there are other pages in the set", () => { + // Arrange + const currentPage: PageLinkData = { + id: "current.md", + data: { title: "Current Page" }, + }; + const otherPage: PageLinkData = { + id: "notcurrent.md", + data: { title: "Should not be the current page" }, + }; + + // Act + const result = relativePagePaths( + [otherPage, currentPage, otherPage, otherPage], + "current", + ); + + // Assert + expect(result.currentPage).toMatchObject(currentPage); + }); + + it("(.md extensions) returns the current page when it does not exist in the set but there are other pages in the set", () => { + // Arrange + const otherPage: PageLinkData = { + id: "notcurrent.md", + data: { title: "Should not be the current page" }, + }; + + // Act + const result = relativePagePaths( + [otherPage, otherPage, otherPage], + "current", + ); + + // Assert + const currentPage: PageLinkData = { + id: "current", + data: { title: "current" }, + }; + expect(result.currentPage).toMatchObject(currentPage); + }); + + it("(.md extensions) returns pages in the same directory as siblingPages when the directory is /", () => { + // Arrange + const currentPage: PageLinkData = { + id: "current.md", + data: { title: "Current Page" }, + }; + const otherPages: PageLinkData[] = [ + { + id: "notcurrent.md", + data: { title: "Should not be the current page" }, + }, + { + id: "alsonotcurrent.md", + data: { title: "Should also not be the current page" }, + }, + { + id: "notcurrent2.md", + data: { title: "Should still not be the current page" }, + }, + ]; + + // Act + const result = relativePagePaths([currentPage, ...otherPages], "current"); + + // Assert + expect(result.siblingPages).toEqual(expect.arrayContaining(otherPages)); + expect(result.siblingPages).toHaveLength(otherPages.length); + }); + + it("(.md extensions) returns pages in the same directory as siblingPages when the directory is not /", () => { + // Arrange + const currentPage: PageLinkData = { + id: "thisdir/current.md", + data: { title: "Current Page" }, + }; + const otherPages: PageLinkData[] = [ + { + id: "thisdir/notcurrent.md", + data: { title: "Should not be the current page" }, + }, + { + id: "thisdir/alsonotcurrent.md", + data: { title: "Should also not be the current page" }, + }, + { + id: "thisdir/notcurrent2.md", + data: { title: "Should still not be the current page" }, + }, + ]; + + // Act + const result = relativePagePaths( + [currentPage, ...otherPages], + "thisdir/current", + ); + + // Assert + expect(result.siblingPages).toEqual(expect.arrayContaining(otherPages)); + expect(result.siblingPages).toHaveLength(otherPages.length); + }); + + it("(.md extensions) does not return pages in different directories as siblingPages when the directory is /", () => { + // Arrange + const currentPage: PageLinkData = { + id: "current.md", + data: { title: "Current Page" }, + }; + const otherPages: PageLinkData[] = [ + { + id: "otherdir/notcurrent.md", + data: { title: "Should not be the current page" }, + }, + { + id: "current/child.md", + data: { title: "Not a sibling!" }, + }, + { + id: "thisdir/lowerdown/notcurrent2.md", + data: { title: "Should still not be the current page" }, + }, + ]; + + // Act + const result = relativePagePaths([currentPage, ...otherPages], "current"); + + // Assert + expect(result.siblingPages).toEqual([]); + }); + + it("(.md extensions) does not return pages in different directories as siblingPages when the directory is not /", () => { + // Arrange + const currentPage: PageLinkData = { + id: "thisdir/current.md", + data: { title: "Current Page" }, + }; + const otherPages: PageLinkData[] = [ + { + id: "otherdir/notcurrent.md", + data: { title: "Should not be the current page" }, + }, + { + id: "alsonotcurrent.md", + data: { title: "Should also not be the current page" }, + }, + { + id: "thisdir/current/child.md", + data: { title: "Not a sibling!" }, + }, + { + id: "thisdir/lowerdown/notcurrent2.md", + data: { title: "Should still not be the current page" }, + }, + ]; + + // Act + const result = relativePagePaths( + [currentPage, ...otherPages], + "thisdir/current", + ); + + // Assert + expect(result.siblingPages).toEqual([]); + }); + + it("(.md extensions) returns exclusively pages which are direct children when dir is /", () => { + // Arrange + const currentPage: PageLinkData = { + id: "current.md", + data: { title: "Current Page" }, + }; + const otherPages: PageLinkData[] = [ + { + id: "otherdir/notcurrent.md", + data: { title: "Should not be the current page" }, + }, + { + id: "alsonotcurrent.md", + data: { title: "Should also not be the current page" }, + }, + { + id: "somedir/lowerdown/notcurrent2.md", + data: { title: "Should still not be the current page" }, + }, + { + id: "current/child2/level2.md", + data: { title: "A 2nd-level child!" }, + }, + ]; + const childPages: PageLinkData[] = [ + { + id: "current/child.md", + data: { title: "A child!" }, + }, + ]; + + // Act + const result = relativePagePaths( + [currentPage, ...otherPages, ...childPages], + "current", + ); + + // Assert + expect(result.childPages).toEqual(expect.arrayContaining(childPages)); + expect(result.childPages).toHaveLength(childPages.length); + }); + + it("(.md extensions) returns exclusively pages which are direct children when dir is not /", () => { + // Arrange + const currentPage: PageLinkData = { + id: "thisdir/current.md", + data: { title: "Current Page" }, + }; + const otherPages: PageLinkData[] = [ + { + id: "otherdir/notcurrent.md", + data: { title: "Should not be the current page" }, + }, + { + id: "alsonotcurrent.md", + data: { title: "Should also not be the current page" }, + }, + { + id: "thisdir/lowerdown/notcurrent2.md", + data: { title: "Should still not be the current page" }, + }, + { + id: "thisdir/current/child2/level2.md", + data: { title: "A 2nd-level child!" }, + }, + ]; + const childPages: PageLinkData[] = [ + { + id: "thisdir/current/child.md", + data: { title: "A child!" }, + }, + ]; + + // Act + const result = relativePagePaths( + [currentPage, ...otherPages, ...childPages], + "thisdir/current", + ); + + // Assert + expect(result.childPages).toEqual(expect.arrayContaining(childPages)); + expect(result.childPages).toHaveLength(childPages.length); + }); + + it("(.md extensions) returns nonempty directories which are direct children when dir is not /", () => { + // Arrange + const pages: PageLinkData[] = [ + { + id: "thisdir/current/child/level2.1.md", + data: { title: "level2.1" }, + }, + { + id: "thisdir/current/child/level2.2.md", + data: { title: "level2.2" }, + }, + { + id: "thisdir/current/child/level2/level3.md", + data: { title: "level3.1" }, + }, + { + id: "thisdir/current/child2/level2/level3.md", + data: { title: "level3.2" }, + }, + { + id: "thisdir/current/child3.md", + data: { title: "just a child 3 page" }, + }, + { + id: "thisdir/current/child3/level2/level3.md", + data: { title: "level3.3" }, + }, + ]; + + // Act + const result = relativePagePaths(pages, "thisdir/current"); + + // Assert + const childDirectories: PageLinkData[] = [ + { + id: "thisdir/current/child", + data: { title: "child" }, + }, + { + id: "thisdir/current/child2", + data: { title: "child2" }, + }, + { + id: "thisdir/current/child3.md", + data: { title: "just a child 3 page" }, + }, + ]; + expect(result.childDirectories).toEqual( + expect.arrayContaining(childDirectories), + ); + expect(result.childDirectories).toHaveLength(childDirectories.length); + }); + + it("(.md extensions) returns nonempty directories which are direct children when dir is /", () => { + // Arrange + const pages: PageLinkData[] = [ + { + id: "current/child/level2.1.md", + data: { title: "level2.1" }, + }, + { + id: "current/child/level2.2.md", + data: { title: "level2.2" }, + }, + { + id: "current/child/level2/level3.md", + data: { title: "level3.1" }, + }, + { + id: "current/child2/level2/level3.md", + data: { title: "level3.2" }, + }, + { + id: "current/child3.md", + data: { title: "just a child 3 page" }, + }, + { + id: "current/child3/level2/level3.md", + data: { title: "level3.3" }, + }, + { + id: "sibling/dir.md", + data: { title: "siblingdirpage" }, + }, + ]; + + // Act + const result = relativePagePaths(pages, "current"); + + // Assert + const childDirectories: PageLinkData[] = [ + { + id: "current/child", + data: { title: "child" }, + }, + { + id: "current/child2", + data: { title: "child2" }, + }, + { + id: "current/child3.md", + data: { title: "just a child 3 page" }, + }, + ]; + expect(result.childDirectories).toEqual( + expect.arrayContaining(childDirectories), + ); + expect(result.childDirectories).toHaveLength(childDirectories.length); + }); + + it("(.md extensions) returns sibling directories when dir is not /", () => { + // Arrange + const pages: PageLinkData[] = [ + { + id: "dir/sibling/level2.1.md", + data: { title: "level2.1" }, + }, + { + id: "dir/sibling/level2.2.md", + data: { title: "level2.2" }, + }, + { + id: "dir/sibling/level2/level3.md", + data: { title: "level3.1" }, + }, + { + id: "dir/sibling2/level2/level3.md", + data: { title: "level3.2" }, + }, + { + id: "dir/sibling3.md", + data: { title: "just a sibling 3 page" }, + }, + { + id: "dir/sibling3/level2/level3.md", + data: { title: "level3.3" }, + }, + ]; + + // Act + const result = relativePagePaths(pages, "dir/current"); + + // Assert + const siblingDirectories: PageLinkData[] = [ + { + id: "dir/sibling", + data: { title: "sibling" }, + }, + { + id: "dir/sibling2", + data: { title: "sibling2" }, + }, + { + id: "dir/sibling3.md", + data: { title: "just a sibling 3 page" }, + }, + ]; + expect(result.siblingDirectories).toEqual( + expect.arrayContaining(siblingDirectories), + ); + expect(result.siblingDirectories).toHaveLength(siblingDirectories.length); + }); + + it("(.md extensions) returns sibling directories when dir is /", () => { + // Arrange + const pages: PageLinkData[] = [ + { + id: "sibling/level2.1.md", + data: { title: "level2.1" }, + }, + { + id: "sibling/level2.2.md", + data: { title: "level2.2" }, + }, + { + id: "sibling/level2/level3.md", + data: { title: "level3.1" }, + }, + { + id: "sibling2/level2/level3.md", + data: { title: "level3.2" }, + }, + { + id: "sibling3.md", + data: { title: "just a sibling 3 page" }, + }, + { + id: "sibling3/level2/level3.md", + data: { title: "level3.3" }, + }, + ]; + + // Act + const result = relativePagePaths(pages, "current"); + + // Assert + const siblingDirectories: PageLinkData[] = [ + { + id: "sibling", + data: { title: "sibling" }, + }, + { + id: "sibling2", + data: { title: "sibling2" }, + }, + { + id: "sibling3.md", + data: { title: "just a sibling 3 page" }, + }, + ]; + expect(result.siblingDirectories).toEqual( + expect.arrayContaining(siblingDirectories), + ); + expect(result.siblingDirectories).toHaveLength(siblingDirectories.length); + }); + + it("(.md extensions) does not return siblingPages pages for directories on the same level", () => { + // Arrange + const pages: PageLinkData[] = [ + { + id: "sibling/level2.1.md", + data: { title: "level2.1" }, + }, + { + id: "sibling/level2.2.md", + data: { title: "level2.2" }, + }, + { + id: "sibling/level2/level3.md", + data: { title: "level3.1" }, + }, + { + id: "sibling2/level2/level3.md", + data: { title: "level3.2" }, + }, + { + id: "sibling3.md", + data: { title: "just a sibling 3 page" }, + }, + { + id: "sibling3/level2/level3.md", + data: { title: "level3.3" }, + }, + ]; + + // Act + const result = relativePagePaths(pages, "current"); + + // Assert + expect(result.siblingPages).toEqual([]); + }); + + it("(.md extensions) does not return childPages pages for directories which are direct children", () => { + // Arrange + const pages: PageLinkData[] = [ + { + id: "thisdir/current/child/level2.1.md", + data: { title: "level2.1" }, + }, + { + id: "thisdir/current/child/level2.2.md", + data: { title: "level2.2" }, + }, + { + id: "thisdir/current/child/level2/level3.md", + data: { title: "level3.1" }, + }, + { + id: "thisdir/current/child2/level2/level3.md", + data: { title: "level3.2" }, + }, + { + id: "thisdir/current/child3.md", + data: { title: "just a child 3 page" }, + }, + { + id: "thisdir/current/child3/level2/level3.md", + data: { title: "level3.3" }, + }, + ]; + + // Act + const result = relativePagePaths(pages, "thisdir/current"); + + // Assert + expect(result.childPages).toEqual([]); + }); + + it("(.md extensions) returns directories which are direct children but only have subdirectories", () => { + // Arrange + const pages: PageLinkData[] = [ + { + id: "current/child/subdirectory/second_subdirectory/page.md", + data: { title: "deeply nested page" }, + }, + ]; + + // Act + const result = relativePagePaths(pages, "current"); + + // Assert + const childDirectories: PageLinkData[] = [ + { + id: "current/child", + data: { title: "child" }, + }, + ]; + expect(result.childDirectories).toEqual( + expect.arrayContaining(childDirectories), + ); + expect(result.childDirectories).toHaveLength(childDirectories.length); + }); + + it("(.md extensions) returns directories which are siblings but only have subdirectories", () => { + // Arrange + const pages: PageLinkData[] = [ + { + id: "sibling/subdirectory/second_subdirectory/page.md", + data: { title: "deeply nested page" }, + }, + ]; + + // Act + const result = relativePagePaths(pages, "current"); + + // Assert + const siblingDirectories: PageLinkData[] = [ + { + id: "sibling", + data: { title: "sibling" }, + }, + ]; + expect(result.siblingDirectories).toEqual( + expect.arrayContaining(siblingDirectories), + ); + expect(result.siblingDirectories).toHaveLength(siblingDirectories.length); + }); + + it("(.md extensions) returns a generic parentDirectory if there is no page there", () => { + // Act + const result = relativePagePaths([], "some/dir/current.md"); + + // Assert + expect(result.parentDirectory).toEqual({ + id: "some/dir", + data: { title: "dir" }, }); + }); - it("returns the current page when it exists in the set and there are other pages in the set", () => { - // Arrange - const currentPage: PageLinkData = { - id: "current", - data: { title: "Current Page" } - }; - const otherPage: PageLinkData = { - id: "notcurrent", - data: { title: "Should not be the current page" } - }; + it("(.md extensions) returns a specific parent directory if there is a page there", () => { + // Arrange + const parentDirectory: PageLinkData = { + id: "some/dir", + data: { title: "A Parent Directory Page.md" }, + }; - // Act - const result = relativePagePaths([ - otherPage, - currentPage, - otherPage, - otherPage - ], "current"); + // Act + const result = relativePagePaths([parentDirectory], "some/dir/current"); - // Assert - expect(result.currentPage).toMatchObject(currentPage); - }); - - it("returns the current page when it does not exist in the set but there are other pages in the set", () => { - // Arrange - const otherPage: PageLinkData = { - id: "notcurrent", - data: { title: "Should not be the current page" } - }; - - // Act - const result = relativePagePaths([ - otherPage, - otherPage, - otherPage - ], "current"); - - // Assert - const currentPage: PageLinkData = { - id: "current", - data: { title: "current" } - }; - expect(result.currentPage).toMatchObject(currentPage); - }); - - it("returns pages in the same directory as siblingPages when the directory is /", () => { - // Arrange - const currentPage: PageLinkData = { - id: "current", - data: { title: "Current Page" } - }; - const otherPages: PageLinkData[] = [ - { - id: "notcurrent", - data: { title: "Should not be the current page" } - }, - { - id: "alsonotcurrent", - data: { title: "Should also not be the current page" } - }, - { - id: "notcurrent2", - data: { title: "Should still not be the current page" } - } - ]; - - // Act - const result = relativePagePaths([ - currentPage, - ...otherPages - ], "current"); - - // Assert - expect(result.siblingPages).toEqual(expect.arrayContaining(otherPages)); - expect(result.siblingPages).toHaveLength(otherPages.length); - }); - - it("returns pages in the same directory as siblingPages when the directory is not /", () => { - // Arrange - const currentPage: PageLinkData = { - id: "thisdir/current", - data: { title: "Current Page" } - }; - const otherPages: PageLinkData[] = [ - { - id: "thisdir/notcurrent", - data: { title: "Should not be the current page" } - }, - { - id: "thisdir/alsonotcurrent", - data: { title: "Should also not be the current page" } - }, - { - id: "thisdir/notcurrent2", - data: { title: "Should still not be the current page" } - } - ]; - - // Act - const result = relativePagePaths([ - currentPage, - ...otherPages - ], "thisdir/current"); - - // Assert - expect(result.siblingPages).toEqual(expect.arrayContaining(otherPages)); - expect(result.siblingPages).toHaveLength(otherPages.length); - }); - - it("does not return pages in different directories as siblingPages when the directory is /", () => { - // Arrange - const currentPage: PageLinkData = { - id: "current", - data: { title: "Current Page" } - }; - const otherPages: PageLinkData[] = [ - { - id: "otherdir/notcurrent", - data: { title: "Should not be the current page" } - }, - { - id: "current/child", - data: { title: "Not a sibling!" } - }, - { - id: "thisdir/lowerdown/notcurrent2", - data: { title: "Should still not be the current page" } - } - ]; - - // Act - const result = relativePagePaths([ - currentPage, - ...otherPages - ], "current"); - - // Assert - expect(result.siblingPages).toEqual([]); - }); - - it("does not return pages in different directories as siblingPages when the directory is not /", () => { - // Arrange - const currentPage: PageLinkData = { - id: "thisdir/current", - data: { title: "Current Page" } - }; - const otherPages: PageLinkData[] = [ - { - id: "otherdir/notcurrent", - data: { title: "Should not be the current page" } - }, - { - id: "alsonotcurrent", - data: { title: "Should also not be the current page" } - }, - { - id: "thisdir/current/child", - data: { title: "Not a sibling!" } - }, - { - id: "thisdir/lowerdown/notcurrent2", - data: { title: "Should still not be the current page" } - } - ]; - - // Act - const result = relativePagePaths([ - currentPage, - ...otherPages - ], "thisdir/current"); - - // Assert - expect(result.siblingPages).toEqual([]); - }); - - it("returns exclusively pages which are direct children when dir is /", () => { - // Arrange - const currentPage: PageLinkData = { - id: "current", - data: { title: "Current Page" } - }; - const otherPages: PageLinkData[] = [ - { - id: "otherdir/notcurrent", - data: { title: "Should not be the current page" } - }, - { - id: "alsonotcurrent", - data: { title: "Should also not be the current page" } - }, - { - id: "somedir/lowerdown/notcurrent2", - data: { title: "Should still not be the current page" } - }, - { - id: "current/child2/level2", - data: { title: "A 2nd-level child!" } - }, - ]; - const childPages: PageLinkData[] = [ - { - id: "current/child", - data: { title: "A child!" } - }, - ]; - - // Act - const result = relativePagePaths([ - currentPage, - ...otherPages, - ...childPages - ], "current"); - - // Assert - expect(result.childPages).toEqual(expect.arrayContaining(childPages)); - expect(result.childPages).toHaveLength(childPages.length); - }); - - it("returns exclusively pages which are direct children when dir is not /", () => { - // Arrange - const currentPage: PageLinkData = { - id: "thisdir/current", - data: { title: "Current Page" } - }; - const otherPages: PageLinkData[] = [ - { - id: "otherdir/notcurrent", - data: { title: "Should not be the current page" } - }, - { - id: "alsonotcurrent", - data: { title: "Should also not be the current page" } - }, - { - id: "thisdir/lowerdown/notcurrent2", - data: { title: "Should still not be the current page" } - }, - { - id: "thisdir/current/child2/level2", - data: { title: "A 2nd-level child!" } - }, - ]; - const childPages: PageLinkData[] = [ - { - id: "thisdir/current/child", - data: { title: "A child!" } - }, - ]; - - // Act - const result = relativePagePaths([ - currentPage, - ...otherPages, - ...childPages - ], "thisdir/current"); - - // Assert - expect(result.childPages).toEqual(expect.arrayContaining(childPages)); - expect(result.childPages).toHaveLength(childPages.length); - }); - - it("returns nonempty directories which are direct children when dir is not /", () => { - // Arrange - const pages: PageLinkData[] = [ - { - id: "thisdir/current/child/level2.1", - data: { title: "level2.1" } - }, - { - id: "thisdir/current/child/level2.2", - data: { title: "level2.2" } - }, - { - id: "thisdir/current/child/level2/level3", - data: { title: "level3.1" } - }, - { - id: "thisdir/current/child2/level2/level3", - data: { title: "level3.2" } - }, - { - id: "thisdir/current/child3", - data: { title: "just a child 3 page" } - }, - { - id: "thisdir/current/child3/level2/level3", - data: { title: "level3.3" } - }, - ]; - - // Act - const result = relativePagePaths(pages, "thisdir/current"); - - // Assert - const childDirectories: PageLinkData[] = [ - { - id: "thisdir/current/child", - data: { title: "child" } - }, - { - id: "thisdir/current/child2", - data: { title: "child2" } - }, - { - id: "thisdir/current/child3", - data: { title: "just a child 3 page" } - }, - ]; - expect(result.childDirectories).toEqual(expect.arrayContaining(childDirectories)); - expect(result.childDirectories).toHaveLength(childDirectories.length); - }); - - it("returns nonempty directories which are direct children when dir is /", () => { - // Arrange - const pages: PageLinkData[] = [ - { - id: "current/child/level2.1", - data: { title: "level2.1" } - }, - { - id: "current/child/level2.2", - data: { title: "level2.2" } - }, - { - id: "current/child/level2/level3", - data: { title: "level3.1" } - }, - { - id: "current/child2/level2/level3", - data: { title: "level3.2" } - }, - { - id: "current/child3", - data: { title: "just a child 3 page" } - }, - { - id: "current/child3/level2/level3", - data: { title: "level3.3" } - }, - { - id: "sibling/dir", - data: { title: "siblingdirpage" } - }, - ]; - - // Act - const result = relativePagePaths(pages, "current"); - - // Assert - const childDirectories: PageLinkData[] = [ - { - id: "current/child", - data: { title: "child" } - }, - { - id: "current/child2", - data: { title: "child2" } - }, - { - id: "current/child3", - data: { title: "just a child 3 page" } - }, - ]; - expect(result.childDirectories).toEqual(expect.arrayContaining(childDirectories)); - expect(result.childDirectories).toHaveLength(childDirectories.length); - }); - - it("returns sibling directories when dir is not /", () => { - // Arrange - const pages: PageLinkData[] = [ - { - id: "dir/sibling/level2.1", - data: { title: "level2.1" } - }, - { - id: "dir/sibling/level2.2", - data: { title: "level2.2" } - }, - { - id: "dir/sibling/level2/level3", - data: { title: "level3.1" } - }, - { - id: "dir/sibling2/level2/level3", - data: { title: "level3.2" } - }, - { - id: "dir/sibling3", - data: { title: "just a sibling 3 page" } - }, - { - id: "dir/sibling3/level2/level3", - data: { title: "level3.3" } - }, - ]; - - // Act - const result = relativePagePaths(pages, "dir/current"); - - // Assert - const siblingDirectories: PageLinkData[] = [ - { - id: "dir/sibling", - data: { title: "sibling" } - }, - { - id: "dir/sibling2", - data: { title: "sibling2" } - }, - { - id: "dir/sibling3", - data: { title: "just a sibling 3 page" } - }, - ]; - expect(result.siblingDirectories).toEqual(expect.arrayContaining(siblingDirectories)); - expect(result.siblingDirectories).toHaveLength(siblingDirectories.length); - }); - - it("returns sibling directories when dir is /", () => { - // Arrange - const pages: PageLinkData[] = [ - { - id: "sibling/level2.1", - data: { title: "level2.1" } - }, - { - id: "sibling/level2.2", - data: { title: "level2.2" } - }, - { - id: "sibling/level2/level3", - data: { title: "level3.1" } - }, - { - id: "sibling2/level2/level3", - data: { title: "level3.2" } - }, - { - id: "sibling3", - data: { title: "just a sibling 3 page" } - }, - { - id: "sibling3/level2/level3", - data: { title: "level3.3" } - }, - ]; - - // Act - const result = relativePagePaths(pages, "current"); - - // Assert - const siblingDirectories: PageLinkData[] = [ - { - id: "sibling", - data: { title: "sibling" } - }, - { - id: "sibling2", - data: { title: "sibling2" } - }, - { - id: "sibling3", - data: { title: "just a sibling 3 page" } - }, - ]; - expect(result.siblingDirectories).toEqual(expect.arrayContaining(siblingDirectories)); - expect(result.siblingDirectories).toHaveLength(siblingDirectories.length); - }); - - it("does not return siblingPages pages for directories on the same level", () => { - // Arrange - const pages: PageLinkData[] = [ - { - id: "sibling/level2.1", - data: { title: "level2.1" } - }, - { - id: "sibling/level2.2", - data: { title: "level2.2" } - }, - { - id: "sibling/level2/level3", - data: { title: "level3.1" } - }, - { - id: "sibling2/level2/level3", - data: { title: "level3.2" } - }, - { - id: "sibling3", - data: { title: "just a sibling 3 page" } - }, - { - id: "sibling3/level2/level3", - data: { title: "level3.3" } - }, - ]; - - // Act - const result = relativePagePaths(pages, "current"); - - // Assert - expect(result.siblingPages).toEqual([]); - }); - - it("does not return childPages pages for directories which are direct children", () => { - // Arrange - const pages: PageLinkData[] = [ - { - id: "thisdir/current/child/level2.1", - data: { title: "level2.1" } - }, - { - id: "thisdir/current/child/level2.2", - data: { title: "level2.2" } - }, - { - id: "thisdir/current/child/level2/level3", - data: { title: "level3.1" } - }, - { - id: "thisdir/current/child2/level2/level3", - data: { title: "level3.2" } - }, - { - id: "thisdir/current/child3", - data: { title: "just a child 3 page" } - }, - { - id: "thisdir/current/child3/level2/level3", - data: { title: "level3.3" } - }, - ]; - - // Act - const result = relativePagePaths(pages, "thisdir/current"); - - // Assert - expect(result.childPages).toEqual([]); - }); - - it("returns directories which are direct children but only have subdirectories", () => { - // Arrange - const pages: PageLinkData[] = [ - { - id: "current/child/subdirectory/second_subdirectory/page", - data: { title: "deeply nested page" } - }, - ]; - - // Act - const result = relativePagePaths(pages, "current"); - - // Assert - const childDirectories: PageLinkData[] = [ - { - id: "current/child", - data: { title: "child" } - }, - ]; - expect(result.childDirectories).toEqual(expect.arrayContaining(childDirectories)); - expect(result.childDirectories).toHaveLength(childDirectories.length); - }); - - it("returns directories which are siblings but only have subdirectories", () => { - // Arrange - const pages: PageLinkData[] = [ - { - id: "sibling/subdirectory/second_subdirectory/page", - data: { title: "deeply nested page" } - }, - ]; - - // Act - const result = relativePagePaths(pages, "current"); - - // Assert - const siblingDirectories: PageLinkData[] = [ - { - id: "sibling", - data: { title: "sibling" } - }, - ]; - expect(result.siblingDirectories).toEqual(expect.arrayContaining(siblingDirectories)); - expect(result.siblingDirectories).toHaveLength(siblingDirectories.length); - }); - - it("returns a generic parentDirectory if there is no page there", () => { - // Act - const result = relativePagePaths([], "some/dir/current"); - - // Assert - expect(result.parentDirectory).toEqual({ - id: "some/dir", - data: { title: "dir" } - }); - }); - - it("returns a specific parent directory if there is a page there", () => { - // Arrange - const parentDirectory: PageLinkData = { - id: "some/dir", - data: { title: "A Parent Directory Page" } - }; - - // Act - const result = relativePagePaths([parentDirectory], "some/dir/current"); - - // Assert - expect(result.parentDirectory).toEqual(parentDirectory); - }); - - it("returns parentDirectory null if we are at the top directory", () => { - // Act - const result = relativePagePaths([], "current"); - - // Assert - expect(result.parentDirectory).toEqual(null); - }); - - it("(.md extensions) returns the current page when it exists in the set", () => { - // Arrange - const currentPage: PageLinkData = { - id: "current.md", - data: { title: "Current Page" } - }; - - // Act - const result = relativePagePaths([currentPage], "current"); - - // Assert - expect(result.currentPage).toMatchObject(currentPage); - }); - - it("(.md extensions, .md currentPage) returns the current page when it exists in the set", () => { - // Arrange - const currentPage: PageLinkData = { - id: "current.md", - data: { title: "Current Page" } - }; - - // Act - const result = relativePagePaths([currentPage], "current.md"); - - // Assert - expect(result.currentPage).toMatchObject(currentPage); - }); - - it("(.md currentPage only) returns the current page when it exists in the set", () => { - // Arrange - const currentPage: PageLinkData = { - id: "current", - data: { title: "Current Page" } - }; - - // Act - const result = relativePagePaths([currentPage], "current.md"); - - // Assert - expect(result.currentPage).toMatchObject(currentPage); - }); - - it("(.md extensions) returns the current page when it exists in the set and there are other pages in the set", () => { - // Arrange - const currentPage: PageLinkData = { - id: "current.md", - data: { title: "Current Page" } - }; - const otherPage: PageLinkData = { - id: "notcurrent.md", - data: { title: "Should not be the current page" } - }; - - // Act - const result = relativePagePaths([ - otherPage, - currentPage, - otherPage, - otherPage - ], "current"); - - // Assert - expect(result.currentPage).toMatchObject(currentPage); - }); - - it("(.md extensions) returns the current page when it does not exist in the set but there are other pages in the set", () => { - // Arrange - const otherPage: PageLinkData = { - id: "notcurrent.md", - data: { title: "Should not be the current page" } - }; - - // Act - const result = relativePagePaths([ - otherPage, - otherPage, - otherPage - ], "current"); - - // Assert - const currentPage: PageLinkData = { - id: "current", - data: { title: "current" } - }; - expect(result.currentPage).toMatchObject(currentPage); - }); - - it("(.md extensions) returns pages in the same directory as siblingPages when the directory is /", () => { - // Arrange - const currentPage: PageLinkData = { - id: "current.md", - data: { title: "Current Page" } - }; - const otherPages: PageLinkData[] = [ - { - id: "notcurrent.md", - data: { title: "Should not be the current page" } - }, - { - id: "alsonotcurrent.md", - data: { title: "Should also not be the current page" } - }, - { - id: "notcurrent2.md", - data: { title: "Should still not be the current page" } - } - ]; - - // Act - const result = relativePagePaths([ - currentPage, - ...otherPages - ], "current"); - - // Assert - expect(result.siblingPages).toEqual(expect.arrayContaining(otherPages)); - expect(result.siblingPages).toHaveLength(otherPages.length); - }); - - it("(.md extensions) returns pages in the same directory as siblingPages when the directory is not /", () => { - // Arrange - const currentPage: PageLinkData = { - id: "thisdir/current.md", - data: { title: "Current Page" } - }; - const otherPages: PageLinkData[] = [ - { - id: "thisdir/notcurrent.md", - data: { title: "Should not be the current page" } - }, - { - id: "thisdir/alsonotcurrent.md", - data: { title: "Should also not be the current page" } - }, - { - id: "thisdir/notcurrent2.md", - data: { title: "Should still not be the current page" } - } - ]; - - // Act - const result = relativePagePaths([ - currentPage, - ...otherPages - ], "thisdir/current"); - - // Assert - expect(result.siblingPages).toEqual(expect.arrayContaining(otherPages)); - expect(result.siblingPages).toHaveLength(otherPages.length); - }); - - it("(.md extensions) does not return pages in different directories as siblingPages when the directory is /", () => { - // Arrange - const currentPage: PageLinkData = { - id: "current.md", - data: { title: "Current Page" } - }; - const otherPages: PageLinkData[] = [ - { - id: "otherdir/notcurrent.md", - data: { title: "Should not be the current page" } - }, - { - id: "current/child.md", - data: { title: "Not a sibling!" } - }, - { - id: "thisdir/lowerdown/notcurrent2.md", - data: { title: "Should still not be the current page" } - } - ]; - - // Act - const result = relativePagePaths([ - currentPage, - ...otherPages - ], "current"); - - // Assert - expect(result.siblingPages).toEqual([]); - }); - - it("(.md extensions) does not return pages in different directories as siblingPages when the directory is not /", () => { - // Arrange - const currentPage: PageLinkData = { - id: "thisdir/current.md", - data: { title: "Current Page" } - }; - const otherPages: PageLinkData[] = [ - { - id: "otherdir/notcurrent.md", - data: { title: "Should not be the current page" } - }, - { - id: "alsonotcurrent.md", - data: { title: "Should also not be the current page" } - }, - { - id: "thisdir/current/child.md", - data: { title: "Not a sibling!" } - }, - { - id: "thisdir/lowerdown/notcurrent2.md", - data: { title: "Should still not be the current page" } - } - ]; - - // Act - const result = relativePagePaths([ - currentPage, - ...otherPages - ], "thisdir/current"); - - // Assert - expect(result.siblingPages).toEqual([]); - }); - - it("(.md extensions) returns exclusively pages which are direct children when dir is /", () => { - // Arrange - const currentPage: PageLinkData = { - id: "current.md", - data: { title: "Current Page" } - }; - const otherPages: PageLinkData[] = [ - { - id: "otherdir/notcurrent.md", - data: { title: "Should not be the current page" } - }, - { - id: "alsonotcurrent.md", - data: { title: "Should also not be the current page" } - }, - { - id: "somedir/lowerdown/notcurrent2.md", - data: { title: "Should still not be the current page" } - }, - { - id: "current/child2/level2.md", - data: { title: "A 2nd-level child!" } - }, - ]; - const childPages: PageLinkData[] = [ - { - id: "current/child.md", - data: { title: "A child!" } - }, - ]; - - // Act - const result = relativePagePaths([ - currentPage, - ...otherPages, - ...childPages - ], "current"); - - // Assert - expect(result.childPages).toEqual(expect.arrayContaining(childPages)); - expect(result.childPages).toHaveLength(childPages.length); - }); - - it("(.md extensions) returns exclusively pages which are direct children when dir is not /", () => { - // Arrange - const currentPage: PageLinkData = { - id: "thisdir/current.md", - data: { title: "Current Page" } - }; - const otherPages: PageLinkData[] = [ - { - id: "otherdir/notcurrent.md", - data: { title: "Should not be the current page" } - }, - { - id: "alsonotcurrent.md", - data: { title: "Should also not be the current page" } - }, - { - id: "thisdir/lowerdown/notcurrent2.md", - data: { title: "Should still not be the current page" } - }, - { - id: "thisdir/current/child2/level2.md", - data: { title: "A 2nd-level child!" } - }, - ]; - const childPages: PageLinkData[] = [ - { - id: "thisdir/current/child.md", - data: { title: "A child!" } - }, - ]; - - // Act - const result = relativePagePaths([ - currentPage, - ...otherPages, - ...childPages - ], "thisdir/current"); - - // Assert - expect(result.childPages).toEqual(expect.arrayContaining(childPages)); - expect(result.childPages).toHaveLength(childPages.length); - }); - - it("(.md extensions) returns nonempty directories which are direct children when dir is not /", () => { - // Arrange - const pages: PageLinkData[] = [ - { - id: "thisdir/current/child/level2.1.md", - data: { title: "level2.1" } - }, - { - id: "thisdir/current/child/level2.2.md", - data: { title: "level2.2" } - }, - { - id: "thisdir/current/child/level2/level3.md", - data: { title: "level3.1" } - }, - { - id: "thisdir/current/child2/level2/level3.md", - data: { title: "level3.2" } - }, - { - id: "thisdir/current/child3.md", - data: { title: "just a child 3 page" } - }, - { - id: "thisdir/current/child3/level2/level3.md", - data: { title: "level3.3" } - }, - ]; - - // Act - const result = relativePagePaths(pages, "thisdir/current"); - - // Assert - const childDirectories: PageLinkData[] = [ - { - id: "thisdir/current/child", - data: { title: "child" } - }, - { - id: "thisdir/current/child2", - data: { title: "child2" } - }, - { - id: "thisdir/current/child3.md", - data: { title: "just a child 3 page" } - }, - ]; - expect(result.childDirectories).toEqual(expect.arrayContaining(childDirectories)); - expect(result.childDirectories).toHaveLength(childDirectories.length); - }); - - it("(.md extensions) returns nonempty directories which are direct children when dir is /", () => { - // Arrange - const pages: PageLinkData[] = [ - { - id: "current/child/level2.1.md", - data: { title: "level2.1" } - }, - { - id: "current/child/level2.2.md", - data: { title: "level2.2" } - }, - { - id: "current/child/level2/level3.md", - data: { title: "level3.1" } - }, - { - id: "current/child2/level2/level3.md", - data: { title: "level3.2" } - }, - { - id: "current/child3.md", - data: { title: "just a child 3 page" } - }, - { - id: "current/child3/level2/level3.md", - data: { title: "level3.3" } - }, - { - id: "sibling/dir.md", - data: { title: "siblingdirpage" } - }, - ]; - - // Act - const result = relativePagePaths(pages, "current"); - - // Assert - const childDirectories: PageLinkData[] = [ - { - id: "current/child", - data: { title: "child" } - }, - { - id: "current/child2", - data: { title: "child2" } - }, - { - id: "current/child3.md", - data: { title: "just a child 3 page" } - }, - ]; - expect(result.childDirectories).toEqual(expect.arrayContaining(childDirectories)); - expect(result.childDirectories).toHaveLength(childDirectories.length); - }); - - it("(.md extensions) returns sibling directories when dir is not /", () => { - // Arrange - const pages: PageLinkData[] = [ - { - id: "dir/sibling/level2.1.md", - data: { title: "level2.1" } - }, - { - id: "dir/sibling/level2.2.md", - data: { title: "level2.2" } - }, - { - id: "dir/sibling/level2/level3.md", - data: { title: "level3.1" } - }, - { - id: "dir/sibling2/level2/level3.md", - data: { title: "level3.2" } - }, - { - id: "dir/sibling3.md", - data: { title: "just a sibling 3 page" } - }, - { - id: "dir/sibling3/level2/level3.md", - data: { title: "level3.3" } - }, - ]; - - // Act - const result = relativePagePaths(pages, "dir/current"); - - // Assert - const siblingDirectories: PageLinkData[] = [ - { - id: "dir/sibling", - data: { title: "sibling" } - }, - { - id: "dir/sibling2", - data: { title: "sibling2" } - }, - { - id: "dir/sibling3.md", - data: { title: "just a sibling 3 page" } - }, - ]; - expect(result.siblingDirectories).toEqual(expect.arrayContaining(siblingDirectories)); - expect(result.siblingDirectories).toHaveLength(siblingDirectories.length); - }); - - it("(.md extensions) returns sibling directories when dir is /", () => { - // Arrange - const pages: PageLinkData[] = [ - { - id: "sibling/level2.1.md", - data: { title: "level2.1" } - }, - { - id: "sibling/level2.2.md", - data: { title: "level2.2" } - }, - { - id: "sibling/level2/level3.md", - data: { title: "level3.1" } - }, - { - id: "sibling2/level2/level3.md", - data: { title: "level3.2" } - }, - { - id: "sibling3.md", - data: { title: "just a sibling 3 page" } - }, - { - id: "sibling3/level2/level3.md", - data: { title: "level3.3" } - }, - ]; - - // Act - const result = relativePagePaths(pages, "current"); - - // Assert - const siblingDirectories: PageLinkData[] = [ - { - id: "sibling", - data: { title: "sibling" } - }, - { - id: "sibling2", - data: { title: "sibling2" } - }, - { - id: "sibling3.md", - data: { title: "just a sibling 3 page" } - }, - ]; - expect(result.siblingDirectories).toEqual(expect.arrayContaining(siblingDirectories)); - expect(result.siblingDirectories).toHaveLength(siblingDirectories.length); - }); - - it("(.md extensions) does not return siblingPages pages for directories on the same level", () => { - // Arrange - const pages: PageLinkData[] = [ - { - id: "sibling/level2.1.md", - data: { title: "level2.1" } - }, - { - id: "sibling/level2.2.md", - data: { title: "level2.2" } - }, - { - id: "sibling/level2/level3.md", - data: { title: "level3.1" } - }, - { - id: "sibling2/level2/level3.md", - data: { title: "level3.2" } - }, - { - id: "sibling3.md", - data: { title: "just a sibling 3 page" } - }, - { - id: "sibling3/level2/level3.md", - data: { title: "level3.3" } - }, - ]; - - // Act - const result = relativePagePaths(pages, "current"); - - // Assert - expect(result.siblingPages).toEqual([]); - }); - - it("(.md extensions) does not return childPages pages for directories which are direct children", () => { - // Arrange - const pages: PageLinkData[] = [ - { - id: "thisdir/current/child/level2.1.md", - data: { title: "level2.1" } - }, - { - id: "thisdir/current/child/level2.2.md", - data: { title: "level2.2" } - }, - { - id: "thisdir/current/child/level2/level3.md", - data: { title: "level3.1" } - }, - { - id: "thisdir/current/child2/level2/level3.md", - data: { title: "level3.2" } - }, - { - id: "thisdir/current/child3.md", - data: { title: "just a child 3 page" } - }, - { - id: "thisdir/current/child3/level2/level3.md", - data: { title: "level3.3" } - }, - ]; - - // Act - const result = relativePagePaths(pages, "thisdir/current"); - - // Assert - expect(result.childPages).toEqual([]); - }); - - it("(.md extensions) returns directories which are direct children but only have subdirectories", () => { - // Arrange - const pages: PageLinkData[] = [ - { - id: "current/child/subdirectory/second_subdirectory/page.md", - data: { title: "deeply nested page" } - }, - ]; - - // Act - const result = relativePagePaths(pages, "current"); - - // Assert - const childDirectories: PageLinkData[] = [ - { - id: "current/child", - data: { title: "child" } - }, - ]; - expect(result.childDirectories).toEqual(expect.arrayContaining(childDirectories)); - expect(result.childDirectories).toHaveLength(childDirectories.length); - }); - - it("(.md extensions) returns directories which are siblings but only have subdirectories", () => { - // Arrange - const pages: PageLinkData[] = [ - { - id: "sibling/subdirectory/second_subdirectory/page.md", - data: { title: "deeply nested page" } - }, - ]; - - // Act - const result = relativePagePaths(pages, "current"); - - // Assert - const siblingDirectories: PageLinkData[] = [ - { - id: "sibling", - data: { title: "sibling" } - }, - ]; - expect(result.siblingDirectories).toEqual(expect.arrayContaining(siblingDirectories)); - expect(result.siblingDirectories).toHaveLength(siblingDirectories.length); - }); - - it("(.md extensions) returns a generic parentDirectory if there is no page there", () => { - // Act - const result = relativePagePaths([], "some/dir/current.md"); - - // Assert - expect(result.parentDirectory).toEqual({ - id: "some/dir", - data: { title: "dir" } - }); - }); - - it("(.md extensions) returns a specific parent directory if there is a page there", () => { - // Arrange - const parentDirectory: PageLinkData = { - id: "some/dir", - data: { title: "A Parent Directory Page.md" } - }; - - // Act - const result = relativePagePaths([parentDirectory], "some/dir/current"); - - // Assert - expect(result.parentDirectory).toEqual(parentDirectory); - }); + // Assert + expect(result.parentDirectory).toEqual(parentDirectory); + }); }); describe("allPageAndDirectoryPaths", () => { - it("returns a page when it exists", () => { - // Arrange - const pageObject = { - ["current.md"]: { - id: "current.md" - } - }; - const nonDirectoryPages = Object.values(pageObject).filter(page => page != null); - const pages = Array.from(nonDirectoryPages) as unknown as CollectionEntry<"wiki">[]; + it("returns a page when it exists", () => { + // Arrange + const pageObject = { + ["current.md"]: { + id: "current.md", + }, + }; + const nonDirectoryPages = Object.values(pageObject).filter( + (page) => page != null, + ); + const pages = Array.from( + nonDirectoryPages, + ) as unknown as CollectionEntry<"wiki">[]; - // Act - const result = allPageAndDirectoryPaths(pages); + // Act + const result = allPageAndDirectoryPaths(pages); - // Assert - expect(Object.fromEntries(result)).toMatchObject(pageObject); - }); - it("returns parent directories when they exist", () => { - // Arrange - const pageObject = { - ["directory/current.md"]: { - id: "directory/current.md" - }, - ["directory"]: null, - }; - const nonDirectoryPages = Object.values(pageObject).filter(page => page != null); - const pages = Array.from(nonDirectoryPages) as unknown as CollectionEntry<"wiki">[]; + // Assert + expect(Object.fromEntries(result)).toMatchObject(pageObject); + }); + it("returns parent directories when they exist", () => { + // Arrange + const pageObject = { + ["directory/current.md"]: { + id: "directory/current.md", + }, + ["directory"]: null, + }; + const nonDirectoryPages = Object.values(pageObject).filter( + (page) => page != null, + ); + const pages = Array.from( + nonDirectoryPages, + ) as unknown as CollectionEntry<"wiki">[]; - // Act - const result = allPageAndDirectoryPaths(pages); + // Act + const result = allPageAndDirectoryPaths(pages); - // Assert - expect(Object.fromEntries(result)).toMatchObject(pageObject); - }); - it("returns only a single directory instance when there are multiple pages", () => { - // Arrange - const pageObject = { - ["directory/current.md"]: { - id: "directory/current.md" - }, - ["directory/current2.md"]: { - id: "directory/current2.md" - }, - ["directory"]: null, - }; - const nonDirectoryPages = Object.values(pageObject).filter(page => page != null); - const pages = Array.from(nonDirectoryPages) as unknown as CollectionEntry<"wiki">[]; + // Assert + expect(Object.fromEntries(result)).toMatchObject(pageObject); + }); + it("returns only a single directory instance when there are multiple pages", () => { + // Arrange + const pageObject = { + ["directory/current.md"]: { + id: "directory/current.md", + }, + ["directory/current2.md"]: { + id: "directory/current2.md", + }, + ["directory"]: null, + }; + const nonDirectoryPages = Object.values(pageObject).filter( + (page) => page != null, + ); + const pages = Array.from( + nonDirectoryPages, + ) as unknown as CollectionEntry<"wiki">[]; - // Act - const result = allPageAndDirectoryPaths(pages); + // Act + const result = allPageAndDirectoryPaths(pages); - // Assert - expect(Object.fromEntries(result)).toMatchObject(pageObject); - }); - it("returns nested subdirectories", () => { - // Arrange - const pageObject = { - ["directory/subdirectory/subsubdirectory/current.md"]: { - id: "directory/subdirectory/subsubdirectory/current.md" - }, - ["directory/current2.md"]: { - id: "directory/current2.md" - }, - ["directory"]: null, - ["directory/subdirectory"]: null, - ["directory/subdirectory/subsubdirectory"]: null, - }; - const nonDirectoryPages = Object.values(pageObject).filter(page => page != null); - const pages = Array.from(nonDirectoryPages) as unknown as CollectionEntry<"wiki">[]; + // Assert + expect(Object.fromEntries(result)).toMatchObject(pageObject); + }); + it("returns nested subdirectories", () => { + // Arrange + const pageObject = { + ["directory/subdirectory/subsubdirectory/current.md"]: { + id: "directory/subdirectory/subsubdirectory/current.md", + }, + ["directory/current2.md"]: { + id: "directory/current2.md", + }, + ["directory"]: null, + ["directory/subdirectory"]: null, + ["directory/subdirectory/subsubdirectory"]: null, + }; + const nonDirectoryPages = Object.values(pageObject).filter( + (page) => page != null, + ); + const pages = Array.from( + nonDirectoryPages, + ) as unknown as CollectionEntry<"wiki">[]; - // Act - const result = allPageAndDirectoryPaths(pages); + // Act + const result = allPageAndDirectoryPaths(pages); - // Assert - expect(Object.fromEntries(result)).toMatchObject(pageObject); - }); - -}); \ No newline at end of file + // Assert + expect(Object.fromEntries(result)).toMatchObject(pageObject); + }); +}); diff --git a/src/lib/pagePaths.ts b/src/lib/pagePaths.ts index 03c9622..404489b 100644 --- a/src/lib/pagePaths.ts +++ b/src/lib/pagePaths.ts @@ -2,162 +2,181 @@ import type { CollectionEntry } from "astro:content"; import { parse, join, sep } from "node:path"; export interface PageLinkData { - id: string; - data: { title: string; }; + id: string; + data: { title: string }; } type AllPathInformation = Map | null>; export interface Paths { - siblingPages: PageLinkData[]; - siblingDirectories: PageLinkData[]; - childPages: PageLinkData[]; - childDirectories: PageLinkData[]; + siblingPages: PageLinkData[]; + siblingDirectories: PageLinkData[]; + childPages: PageLinkData[]; + childDirectories: PageLinkData[]; - parentDirectory: PageLinkData | null; - currentPage: PageLinkData; -}; - -export function relativePagePaths(wikiEntries: PageLinkData[], currentPath: string): Paths { - let currentPage: PageLinkData | undefined; - let parentDirectory: PageLinkData | undefined | null; - const siblingPages: Map = new Map(); - const childPages: Map = new Map(); - - const currentPathParsed = parse(currentPath); - const currentPathExtensionless = join(currentPathParsed.dir, currentPathParsed.name); - - const childDirectoryPaths: Set = new Set(); - const siblingDirectoryPaths: Set = new Set(); - - for (const entry of wikiEntries) { - const pagePathParsed = parse(entry.id); - const pagePathExtensionless = join(pagePathParsed.dir, pagePathParsed.name); - - if (pagePathExtensionless === currentPathExtensionless) { - currentPage = entry - continue; - } - - const isInCurrentDirectory = pagePathParsed.dir === currentPathParsed.dir; - if (isInCurrentDirectory) { - siblingPages.set(pagePathExtensionless, entry); - continue; - } - - const isDirectChild = pagePathParsed.dir === currentPathExtensionless; - if (isDirectChild) { - childPages.set(pagePathExtensionless, entry); - continue; - } - - const isIndirectChild = pagePathParsed.dir.startsWith(currentPathExtensionless + sep); - if (isIndirectChild) { - const nextPathSeparator = pagePathParsed.dir.indexOf(sep, currentPathExtensionless.length + 1); - - if (nextPathSeparator === -1) { - childDirectoryPaths.add(pagePathParsed.dir); - continue; - } - - childDirectoryPaths.add(pagePathParsed.dir.slice(0, nextPathSeparator)); - continue; - } - - const isIndirectInCurrentDirectory = currentPathParsed.dir === "" || pagePathParsed.dir.startsWith(currentPathParsed.dir + sep); - if (isIndirectInCurrentDirectory) { - const nextPathSeparator = pagePathParsed.dir.indexOf(sep, currentPathParsed.dir.length + 1); - - if (nextPathSeparator === -1) { - siblingDirectoryPaths.add(pagePathParsed.dir); - continue; - } - - siblingDirectoryPaths.add(pagePathParsed.dir.slice(0, nextPathSeparator)); - continue; - } - - const isParentDirectory = pagePathExtensionless === currentPathParsed.dir; - if (isParentDirectory) { - parentDirectory = entry; - } - } - - const childDirectories: PageLinkData[] = []; - for (const childDirectoryPath of childDirectoryPaths.values()) { - const childDirectoryPage = childPages.get(childDirectoryPath); - if (childDirectoryPage) { - childDirectories.push(childDirectoryPage); - childPages.delete(childDirectoryPath); - continue; - } - - const childDirectoryPathParsed = parse(childDirectoryPath); - childDirectories.push({ - id: childDirectoryPath, - data: { title: childDirectoryPathParsed.name } - }); - } - - const siblingDirectories: PageLinkData[] = []; - for (const siblingDirectoryPath of siblingDirectoryPaths.values()) { - const siblingDirectoryPage = siblingPages.get(siblingDirectoryPath); - if (siblingDirectoryPage) { - siblingDirectories.push(siblingDirectoryPage); - siblingPages.delete(siblingDirectoryPath); - continue; - } - - const siblingDirectoryPathParsed = parse(siblingDirectoryPath); - siblingDirectories.push({ - id: siblingDirectoryPath, - data: { title: siblingDirectoryPathParsed.name } - }); - } - - if (currentPage === undefined) { - currentPage = { - id: currentPath, - data: { title: currentPathParsed.name } - }; - } - - if (parentDirectory === undefined) { - if (currentPathParsed.dir) { - const parentDirectoryPathParsed = parse(currentPathParsed.dir); - parentDirectory = { - id: currentPathParsed.dir, - data: { title: parentDirectoryPathParsed.name } - }; - } else { - parentDirectory = null; - } - } - - return { - siblingPages: Array.from(siblingPages.values()).sort(), - childPages: Array.from(childPages.values()).sort(), - - siblingDirectories: siblingDirectories.sort(), - childDirectories: childDirectories.sort(), - - currentPage, - parentDirectory, - } + parentDirectory: PageLinkData | null; + currentPage: PageLinkData; } -export function allPageAndDirectoryPaths(wikiEntries: CollectionEntry<"wiki">[]): AllPathInformation { - const pathInformation: Map | null> = new Map(); +export function relativePagePaths( + wikiEntries: PageLinkData[], + currentPath: string, +): Paths { + let currentPage: PageLinkData | undefined; + let parentDirectory: PageLinkData | undefined | null; + const siblingPages: Map = new Map(); + const childPages: Map = new Map(); - for (const entry of wikiEntries) { - pathInformation.set(entry.id, entry); + const currentPathParsed = parse(currentPath); + const currentPathExtensionless = join( + currentPathParsed.dir, + currentPathParsed.name, + ); - let parsedEntryPath = parse(entry.id); - while (parsedEntryPath.dir) { - pathInformation.set(parsedEntryPath.dir, null); - parsedEntryPath = parse(parsedEntryPath.dir); - } + const childDirectoryPaths: Set = new Set(); + const siblingDirectoryPaths: Set = new Set(); + + for (const entry of wikiEntries) { + const pagePathParsed = parse(entry.id); + const pagePathExtensionless = join(pagePathParsed.dir, pagePathParsed.name); + + if (pagePathExtensionless === currentPathExtensionless) { + currentPage = entry; + continue; } - return pathInformation; -} \ No newline at end of file + const isInCurrentDirectory = pagePathParsed.dir === currentPathParsed.dir; + if (isInCurrentDirectory) { + siblingPages.set(pagePathExtensionless, entry); + continue; + } + + const isDirectChild = pagePathParsed.dir === currentPathExtensionless; + if (isDirectChild) { + childPages.set(pagePathExtensionless, entry); + continue; + } + + const isIndirectChild = pagePathParsed.dir.startsWith( + currentPathExtensionless + sep, + ); + if (isIndirectChild) { + const nextPathSeparator = pagePathParsed.dir.indexOf( + sep, + currentPathExtensionless.length + 1, + ); + + if (nextPathSeparator === -1) { + childDirectoryPaths.add(pagePathParsed.dir); + continue; + } + + childDirectoryPaths.add(pagePathParsed.dir.slice(0, nextPathSeparator)); + continue; + } + + const isIndirectInCurrentDirectory = + currentPathParsed.dir === "" || + pagePathParsed.dir.startsWith(currentPathParsed.dir + sep); + if (isIndirectInCurrentDirectory) { + const nextPathSeparator = pagePathParsed.dir.indexOf( + sep, + currentPathParsed.dir.length + 1, + ); + + if (nextPathSeparator === -1) { + siblingDirectoryPaths.add(pagePathParsed.dir); + continue; + } + + siblingDirectoryPaths.add(pagePathParsed.dir.slice(0, nextPathSeparator)); + continue; + } + + const isParentDirectory = pagePathExtensionless === currentPathParsed.dir; + if (isParentDirectory) { + parentDirectory = entry; + } + } + + const childDirectories: PageLinkData[] = []; + for (const childDirectoryPath of childDirectoryPaths.values()) { + const childDirectoryPage = childPages.get(childDirectoryPath); + if (childDirectoryPage) { + childDirectories.push(childDirectoryPage); + childPages.delete(childDirectoryPath); + continue; + } + + const childDirectoryPathParsed = parse(childDirectoryPath); + childDirectories.push({ + id: childDirectoryPath, + data: { title: childDirectoryPathParsed.name }, + }); + } + + const siblingDirectories: PageLinkData[] = []; + for (const siblingDirectoryPath of siblingDirectoryPaths.values()) { + const siblingDirectoryPage = siblingPages.get(siblingDirectoryPath); + if (siblingDirectoryPage) { + siblingDirectories.push(siblingDirectoryPage); + siblingPages.delete(siblingDirectoryPath); + continue; + } + + const siblingDirectoryPathParsed = parse(siblingDirectoryPath); + siblingDirectories.push({ + id: siblingDirectoryPath, + data: { title: siblingDirectoryPathParsed.name }, + }); + } + + if (currentPage === undefined) { + currentPage = { + id: currentPath, + data: { title: currentPathParsed.name }, + }; + } + + if (parentDirectory === undefined) { + if (currentPathParsed.dir) { + const parentDirectoryPathParsed = parse(currentPathParsed.dir); + parentDirectory = { + id: currentPathParsed.dir, + data: { title: parentDirectoryPathParsed.name }, + }; + } else { + parentDirectory = null; + } + } + + return { + siblingPages: Array.from(siblingPages.values()).sort(), + childPages: Array.from(childPages.values()).sort(), + + siblingDirectories: siblingDirectories.sort(), + childDirectories: childDirectories.sort(), + + currentPage, + parentDirectory, + }; +} + +export function allPageAndDirectoryPaths( + wikiEntries: CollectionEntry<"wiki">[], +): AllPathInformation { + const pathInformation: Map | null> = + new Map(); + + for (const entry of wikiEntries) { + pathInformation.set(entry.id, entry); + + let parsedEntryPath = parse(entry.id); + while (parsedEntryPath.dir) { + pathInformation.set(parsedEntryPath.dir, null); + parsedEntryPath = parse(parsedEntryPath.dir); + } + } + + return pathInformation; +} diff --git a/src/reset.d.ts b/src/reset.d.ts index e186b1f..a3d4a03 100644 --- a/src/reset.d.ts +++ b/src/reset.d.ts @@ -1 +1 @@ -import "@total-typescript/ts-reset"; \ No newline at end of file +import "@total-typescript/ts-reset"; diff --git a/src/style/content.css b/src/style/content.css index 1df682b..e4b74a6 100644 --- a/src/style/content.css +++ b/src/style/content.css @@ -1,15 +1,15 @@ .contents table { - border: 1px solid black; - border-collapse: collapse; + border: 1px solid black; + border-collapse: collapse; } .contents td { - padding: 1em; - border: 1px solid black; + padding: 1em; + border: 1px solid black; } .contents { - overflow: scroll; - height: 100vh; - padding: 0em 2em; -} \ No newline at end of file + overflow: scroll; + height: 100vh; + padding: 0em 2em; +} diff --git a/src/style/globals.css b/src/style/globals.css index 1e13bfc..7d9e614 100644 --- a/src/style/globals.css +++ b/src/style/globals.css @@ -1,7 +1,7 @@ a:visited { - color: blue; + color: blue; } .contents { - width: 100%; + width: 100%; } diff --git a/tsconfig.json b/tsconfig.json index 3fd7ae6..fbc2f5f 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,3 +1,3 @@ { "extends": "astro/tsconfigs/strictest" -} \ No newline at end of file +}