polen 0.8.0-next.4 → 0.8.0-next.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/build/api/vite/plugins/core.d.ts.map +1 -1
  2. package/build/api/vite/plugins/core.js +83 -52
  3. package/build/api/vite/plugins/core.js.map +1 -1
  4. package/build/lib/file-router/linter.d.ts.map +1 -1
  5. package/build/lib/file-router/linter.js +3 -3
  6. package/build/lib/file-router/linter.js.map +1 -1
  7. package/build/lib/file-router/route.d.ts +48 -10
  8. package/build/lib/file-router/route.d.ts.map +1 -1
  9. package/build/lib/file-router/route.js +68 -3
  10. package/build/lib/file-router/route.js.map +1 -1
  11. package/build/lib/file-router/scan.d.ts +2 -2
  12. package/build/lib/file-router/scan.d.ts.map +1 -1
  13. package/build/lib/file-router/scan.js +8 -8
  14. package/build/lib/file-router/scan.js.map +1 -1
  15. package/build/lib/kit-temp.d.ts +2 -0
  16. package/build/lib/kit-temp.d.ts.map +1 -0
  17. package/build/lib/kit-temp.js +23 -0
  18. package/build/lib/kit-temp.js.map +1 -0
  19. package/build/project-data.d.ts +10 -1
  20. package/build/project-data.d.ts.map +1 -1
  21. package/build/template/components/Sidebar.d.ts +11 -0
  22. package/build/template/components/Sidebar.d.ts.map +1 -0
  23. package/build/template/components/Sidebar.jsx +47 -0
  24. package/build/template/components/Sidebar.jsx.map +1 -0
  25. package/build/template/routes/root.d.ts.map +1 -1
  26. package/build/template/routes/root.jsx +28 -5
  27. package/build/template/routes/root.jsx.map +1 -1
  28. package/package.json +1 -1
  29. package/src/api/vite/plugins/core.ts +97 -54
  30. package/src/lib/file-router/index.test.ts +5 -5
  31. package/src/lib/file-router/linter.ts +3 -3
  32. package/src/lib/file-router/route.ts +147 -11
  33. package/src/lib/file-router/scan.ts +9 -9
  34. package/src/lib/kit-temp.ts +21 -0
  35. package/src/project-data.ts +12 -1
  36. package/src/template/components/Sidebar.tsx +92 -0
  37. package/src/template/routes/root.tsx +35 -5
@@ -1 +1 @@
1
- {"version":3,"file":"root.d.ts","sourceRoot":"","sources":["../../../src/template/routes/root.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAA;AAyB7D,eAAO,MAAM,SAAS,mCA6BrB,CAAA;AAmHD,eAAO,MAAM,IAAI;;;;CAIf,CAAA"}
1
+ {"version":3,"file":"root.d.ts","sourceRoot":"","sources":["../../../src/template/routes/root.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAA;AA0B7D,eAAO,MAAM,SAAS,mCA6BrB,CAAA;AAgJD,eAAO,MAAM,IAAI;;;;CAIf,CAAA"}
@@ -4,10 +4,11 @@ import { Box, Button, Heading, Text } from '@radix-ui/themes';
4
4
  import { Flex, Theme } from '@radix-ui/themes';
5
5
  import radixStylesUrl from '@radix-ui/themes/styles.css?url';
6
6
  import { Link as LinkReactRouter } from 'react-router';
7
- import { Outlet, ScrollRestoration } from 'react-router';
7
+ import { Outlet, ScrollRestoration, useLocation } from 'react-router';
8
8
  import { PROJECT_DATA } from 'virtual:polen/project/data';
9
9
  import { templateVariables } from 'virtual:polen/template/variables';
10
10
  import { Link } from '../components/Link.jsx';
11
+ import { Sidebar } from '../components/Sidebar.jsx';
11
12
  import entryClientUrl from '../entry.client.jsx?url';
12
13
  import { changelog } from './changelog.jsx';
13
14
  import { index } from './index.jsx';
@@ -40,6 +41,20 @@ export const Component = () => {
40
41
  </html>);
41
42
  };
42
43
  const Layout = () => {
44
+ const location = useLocation();
45
+ // Determine if we should show sidebar based on current path
46
+ const getCurrentNavPathExp = () => {
47
+ // todo: general path manipulation lib because we are duplicating logic here found in FileRouter
48
+ // todo: kit: try a Str.split that returns [] | string[] so that our predicates can refine on it?
49
+ const segments = location.pathname.split(`/`).filter(Boolean);
50
+ if (Arr.isntEmpty(segments)) {
51
+ return `/${segments[0]}`;
52
+ }
53
+ return null;
54
+ };
55
+ const currentNavPathExp = getCurrentNavPathExp();
56
+ const sidebarItems = currentNavPathExp && PROJECT_DATA.sidebar[currentNavPathExp];
57
+ const showSidebar = sidebarItems && sidebarItems.length > 0;
43
58
  return (<Theme asChild>
44
59
  <Box m='8'>
45
60
  <Flex align='center' gap='8' pb='4' mb='8' style={{
@@ -54,14 +69,21 @@ const Layout = () => {
54
69
  </Flex>
55
70
  </LinkReactRouter>
56
71
  <Flex direction='row' gap='4'>
57
- {PROJECT_DATA.siteNavigationItems.map((item, key) => (<Link key={key} color='gray' to={item.path}>
72
+ {PROJECT_DATA.siteNavigationItems.map((item, key) => (<Link key={key} color='gray' to={item.pathExp}>
58
73
  {item.title}
59
74
  </Link>))}
60
75
  </Flex>
61
76
  </Flex>
62
- <Box>
63
- <Outlet />
64
- </Box>
77
+ {showSidebar
78
+ ? (<Flex gap='8'>
79
+ <Sidebar items={sidebarItems}/>
80
+ <Box style={{ flex: 1 }}>
81
+ <Outlet />
82
+ </Box>
83
+ </Flex>)
84
+ : (<Box>
85
+ <Outlet />
86
+ </Box>)}
65
87
  </Box>
66
88
  </Theme>);
67
89
  };
@@ -127,6 +149,7 @@ children.push(notFoundRoute);
127
149
  // ━━━━━━━━━━━━━━ • Root Route
128
150
  //
129
151
  //
152
+ import { Arr } from '@wollybeard/kit';
130
153
  import { pages } from 'virtual:polen/project/pages.jsx';
131
154
  export const root = createRoute({
132
155
  path: `/`,
@@ -1 +1 @@
1
- {"version":3,"file":"root.jsx","sourceRoot":"","sources":["../../../src/template/routes/root.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"root.jsx","sourceRoot":"","sources":["../../../src/template/routes/root.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,2CAA2C,CAAA;AACvE,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AACtD,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAA;AAC7D,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,cAAc,MAAM,iCAAiC,CAAA;AAC5D,OAAO,EAAE,IAAI,IAAI,eAAe,EAAE,MAAM,cAAc,CAAA;AACtD,OAAO,EAAE,MAAM,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAA;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAA;AACpE,OAAO,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAA;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAA;AACnD,OAAO,cAAc,MAAM,yBAAyB,CAAA;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AACnC,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAE3C,yEAAyE;AACzE,MAAM,oBAAoB,GAAG;;;;;;CAM5B,CAAA;AAED,MAAM,CAAC,MAAM,SAAS,GAAG,GAAG,EAAE;IAC5B,OAAO,CACL,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CACb;MAAA,CAAC,IAAI,CACH;QAAA,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,oBAAoB,CAAC,EAAE,MAAM,CAAC,CAC7E;QAAA,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC,CAC3E;QAAA,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EACrB;QAAA,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,qCAAqC,EACnE;QAAA,CAAC,KAAK,CAAC,CAAC,iBAAiB,CAAC,KAAK,CAAC,EAAE,KAAK,CACvC;QAAA,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,cAAc,CAAC,EAAG,CACvE;QAAA,CAAC,IAAI,CACH,GAAG,CAAC,MAAM,CACV,IAAI,CAAC,CAAC,YAAY,CAAC,WAAW,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC,CAChE,KAAK,CAAC,WAAW,EAEnB;QAAA,CAAC,IAAI,CACH,GAAG,CAAC,MAAM,CACV,IAAI,CAAC,CAAC,YAAY,CAAC,WAAW,GAAG,MAAM,CAAC,CACxC,KAAK,CAAC,KAAK,CACX,IAAI,CAAC,eAAe,EAExB;MAAA,EAAE,IAAI,CACN;MAAA,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CACzB;QAAA,CAAC,MAAM,CAAC,AAAD,EACP;QAAA,CAAC,iBAAiB,CAAC,AAAD,EAClB;QAAA,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,cAAc,CAAC,CAAC,EAAE,MAAM,CAAC,CAC9E;MAAA,EAAE,IAAI,CACR;IAAA,EAAE,IAAI,CAAC,CACR,CAAA;AACH,CAAC,CAAA;AAED,MAAM,MAAM,GAAG,GAAG,EAAE;IAClB,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAA;IAE9B,4DAA4D;IAC5D,MAAM,oBAAoB,GAAG,GAAkB,EAAE;QAC/C,gGAAgG;QAChG,iGAAiG;QACjG,MAAM,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;QAC7D,IAAI,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC5B,OAAO,IAAI,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAA;QAC1B,CAAC;QACD,OAAO,IAAI,CAAA;IACb,CAAC,CAAA;IAED,MAAM,iBAAiB,GAAG,oBAAoB,EAAE,CAAA;IAChD,MAAM,YAAY,GAAG,iBAAiB,IAAI,YAAY,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAA;IACjF,MAAM,WAAW,GAAG,YAAY,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,CAAA;IAE3D,OAAO,CACL,CAAC,KAAK,CAAC,OAAO,CACZ;MAAA,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CACR;QAAA,CAAC,IAAI,CACH,KAAK,CAAC,QAAQ,CACd,GAAG,CAAC,GAAG,CACP,EAAE,CAAC,GAAG,CACN,EAAE,CAAC,GAAG,CACN,KAAK,CAAC,CAAC;YACL,YAAY,EAAE,yBAAyB;SACxC,CAAC,CAEF;UAAA,CAAC,eAAe,CACd,EAAE,CAAC,GAAG,CACN,KAAK,CAAC,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,EAAE,CAAC,CAEpD;YAAA,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAC1B;cAAA,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,EACjD;cAAA,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAC5B;gBAAA,CAAC,iBAAiB,CAAC,KAAK,CAC1B;cAAA,EAAE,IAAI,CACR;YAAA,EAAE,IAAI,CACR;UAAA,EAAE,eAAe,CACjB;UAAA,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAC3B;YAAA,CAAC,YAAY,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC,CACnD,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAC5C;gBAAA,CAAC,IAAI,CAAC,KAAK,CACb;cAAA,EAAE,IAAI,CAAC,CACR,CAAC,CACJ;UAAA,EAAE,IAAI,CACR;QAAA,EAAE,IAAI,CACN;QAAA,CAAC,WAAW;YACV,CAAC,CAAC,CACA,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CACX;cAAA,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,EAC7B;cAAA,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CACtB;gBAAA,CAAC,MAAM,CAAC,AAAD,EACT;cAAA,EAAE,GAAG,CACP;YAAA,EAAE,IAAI,CAAC,CACR;YACD,CAAC,CAAC,CACA,CAAC,GAAG,CACF;cAAA,CAAC,MAAM,CAAC,AAAD,EACT;YAAA,EAAE,GAAG,CAAC,CACP,CACL;MAAA,EAAE,GAAG,CACP;IAAA,EAAE,KAAK,CAAC,CACT,CAAA;AACH,CAAC,CAAA;AAED,MAAM,QAAQ,GAA8B;IAC1C,KAAK;IACL,GAAG,KAAK;CACT,CAAA;AAED,EAAE;AACF,EAAE;AACF,EAAE;AACF,EAAE;AACF,8DAA8D;AAC9D,EAAE;AACF,EAAE;AACF,EAAE;AAEF,IAAI,YAAY,CAAC,MAAM,EAAE,CAAC;IACxB,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;IACxB,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;AAC1B,CAAC;AAED,EAAE;AACF,EAAE;AACF,EAAE;AACF,EAAE;AACF,mCAAmC;AACnC,EAAE;AACF,EAAE;AACF,EAAE;AAEF,MAAM,iBAAiB,GAAG,GAAG,EAAE;IAC7B,OAAO,CACL,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC,CACjG;MAAA,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC,CAAC,GAAG,EAAE,OAAO,CAClE;MAAA,CAAC,GAAG,CACF;QAAA,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,cAAc,EAAE,OAAO,CAChD;QAAA,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CACzB;;QACF,EAAE,IAAI,CACR;MAAA,EAAE,GAAG,CACL;MAAA,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CACX;QAAA,CAAC,eAAe,CAAC,EAAE,CAAC,GAAG,CACrB;UAAA,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAC7B;;UACF,EAAE,MAAM,CACV;QAAA,EAAE,eAAe,CACjB;QAAA,CAAC,eAAe,CAAC,EAAE,CAAC,YAAY,CAC9B;UAAA,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAChC;;UACF,EAAE,MAAM,CACV;QAAA,EAAE,eAAe,CACnB;MAAA,EAAE,IAAI,CACR;IAAA,EAAE,IAAI,CAAC,CACR,CAAA;AACH,CAAC,CAAA;AAED,MAAM,aAAa,GAAG,WAAW,CAAC;IAChC,EAAE,EAAE,aAAa;IACjB,IAAI,EAAE,GAAG;IACT,SAAS,EAAE,iBAAiB;IAC5B,MAAM,EAAE;QACN,UAAU,EAAE,GAAG;KAChB;CACF,CAAC,CAAA;AACF,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC,CAAA;AAE5B,EAAE;AACF,EAAE;AACF,EAAE;AACF,8BAA8B;AAC9B,EAAE;AACF,EAAE;AAEF,OAAO,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAA;AACrC,OAAO,EAAE,KAAK,EAAE,MAAM,iCAAiC,CAAA;AAEvD,MAAM,CAAC,MAAM,IAAI,GAAG,WAAW,CAAC;IAC9B,IAAI,EAAE,GAAG;IACT,SAAS;IACT,QAAQ;CACT,CAAC,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "polen",
3
- "version": "0.8.0-next.4",
3
+ "version": "0.8.0-next.5",
4
4
  "type": "module",
5
5
  "description": "A framework for delightful GraphQL developer portals",
6
6
  "author": {
@@ -1,13 +1,12 @@
1
- import { Markdown } from '#api/singletons/markdown/index.js'
2
1
  import type { ReactRouter } from '#dep/react-router/index.js'
3
2
  import type { Vite } from '#dep/vite/index.js'
4
3
  import { FileRouter } from '#lib/file-router/index.js'
5
4
  import { ViteVirtual } from '#lib/vite-virtual/index.js'
6
5
  import mdx from '@mdx-js/rollup'
7
- import { Cache, Fs, Json, Path, Str } from '@wollybeard/kit'
6
+ import { Cache, Json, Path, Str } from '@wollybeard/kit'
8
7
  import jsesc from 'jsesc'
9
8
  import remarkGfm from 'remark-gfm'
10
- import type { ProjectData, SiteNavigationItem } from '../../../project-data.js'
9
+ import type { ProjectData, Sidebar, SidebarItem, SiteNavigationItem } from '../../../project-data.js'
11
10
  import { superjson } from '../../../singletons/superjson.js'
12
11
  import type { Configurator } from '../../configurator/index.js'
13
12
  import { SchemaAugmentation } from '../../schema-augmentation/index.js'
@@ -53,27 +52,31 @@ export const Core = (config: Configurator.Config): Vite.PluginOption[] => {
53
52
  ],
54
53
  }),
55
54
  },
56
- {
57
- name: `polen:markdown`,
58
- enforce: `pre`,
59
- resolveId(id) {
60
- if (id.endsWith(`.md`)) {
61
- return id
62
- }
63
- return null
64
- },
65
- async load(id) {
66
- if (id.endsWith(`.md`)) {
67
- const markdownString = await Fs.read(id)
68
- if (!markdownString) return null
69
- const htmlString = await Markdown.parse(markdownString)
70
-
71
- const code = `export default ${JSON.stringify(htmlString)}`
72
- return code
73
- }
74
- return null
75
- },
76
- },
55
+ // TODO: We can remove, mdx subsumes this
56
+ // TODO: First we need to investigate how e can make our api singleton Markdown used by MDX.
57
+ // If we cannot, then we might want to ditch MDX instead and use our lower level solution here.
58
+ // It depends in part on how complex our Markdown singleton gets.
59
+ // {
60
+ // name: `polen:markdown`,
61
+ // enforce: `pre`,
62
+ // resolveId(id) {
63
+ // if (id.endsWith(`.md`)) {
64
+ // return id
65
+ // }
66
+ // return null
67
+ // },
68
+ // async load(id) {
69
+ // if (id.endsWith(`.md`)) {
70
+ // const markdownString = await Fs.read(id)
71
+ // if (!markdownString) return null
72
+ // const htmlString = await Markdown.parse(markdownString)
73
+
74
+ // const code = `export default ${JSON.stringify(htmlString)}`
75
+ // return code
76
+ // }
77
+ // return null
78
+ // },
79
+ // },
77
80
  {
78
81
  name: `polen:core:alias`,
79
82
  resolveId(id, importer) {
@@ -136,35 +139,84 @@ export const Core = (config: Configurator.Config): Vite.PluginOption[] => {
136
139
  async loader() {
137
140
  // todo: parallel
138
141
  const schema = await readSchema()
139
- console.log({ schema })
140
142
  const pagesScanResult = await scanPageRoutes()
141
143
 
142
144
  const siteNavigationItems: SiteNavigationItem[] = []
143
145
 
144
- const siteNavigationItemsFromTopLevelPages = pagesScanResult.routes
145
- // We exclude home page
146
- .filter(route => route.path.segments.length === 1)
147
- .map(route => {
148
- const path = FileRouter.routeToString(route)
149
- const title = Str.titlizeSlug(path)
150
- return {
151
- path,
152
- title,
153
- }
154
- })
146
+ //
147
+ // ━━ Build Navbar
148
+ //
155
149
 
156
- siteNavigationItems.push(...siteNavigationItemsFromTopLevelPages)
150
+ // ━ Top pages become navigation items
151
+ const topPages = pagesScanResult.routes.filter(FileRouter.routeIsTopLevel)
152
+
153
+ for (const page of topPages) {
154
+ const path = FileRouter.routeToPathExpression(page)
155
+ const title = Str.titlizeSlug(path)
156
+ siteNavigationItems.push({ pathExp: path, title })
157
+ }
157
158
 
159
+ // ━ Top directories become navigation items
160
+ const topDirsPaths = pagesScanResult.routes
161
+ .filter(FileRouter.routeIsSubLevel)
162
+ // todo: kit, slice that understands non-empty
163
+ // Arr.slice(route.path.segments, 1)
164
+ .map(route => [route.logical.path[0]])
165
+
166
+ for (const dir of topDirsPaths) {
167
+ const pathExp = FileRouter.pathToExpression(dir)
168
+ const title = Str.titlizeSlug(pathExp)
169
+ // todo: this should never happen, if it does, swarn user
170
+ // Only add if not already added as a top page
171
+ if (!siteNavigationItems.some(item => item.pathExp === pathExp)) {
172
+ siteNavigationItems.push({ pathExp: pathExp, title })
173
+ }
174
+ }
175
+
176
+ // ━ Schema presence causes adding some navbar items
158
177
  if (schema) {
159
- siteNavigationItems.push({ path: `/reference`, title: `Reference` })
178
+ siteNavigationItems.push({ pathExp: `/reference`, title: `Reference` })
160
179
  if (schema.versions.length > 1) {
161
- siteNavigationItems.push({ path: `/changelog`, title: `Changelog` })
180
+ siteNavigationItems.push({ pathExp: `/changelog`, title: `Changelog` })
162
181
  }
163
182
  }
164
183
 
184
+ //
185
+ // ━━ Build Sidebar
186
+ //
187
+
188
+ const sidebar: Sidebar = {}
189
+
190
+ for (const dirPath of topDirsPaths) {
191
+ const childPages = pagesScanResult.routes.filter(page => FileRouter.routeIsSubOf(page, dirPath))
192
+
193
+ const sidebarItems: SidebarItem[] = []
194
+
195
+ // ━ Pages in this dir become sidebar items
196
+ for (const childPage of childPages) {
197
+ const childPageRelative = FileRouter.makeRelativeUnsafe(childPage, dirPath)
198
+
199
+ if (FileRouter.routeIsRootLevel(childPageRelative)) {
200
+ // We elide root from items. Root represents this whole group of items.
201
+ continue
202
+ }
203
+
204
+ if (FileRouter.routeIsTopLevel(childPageRelative)) {
205
+ const pathExp = FileRouter.routeToPathExpression(childPage)
206
+ const relativePathExp = FileRouter.routeToPathExpression(childPageRelative)
207
+ const title = Str.titlizeSlug(relativePathExp)
208
+ sidebarItems.push({ pathExp, title })
209
+ }
210
+ // TODO: Handle nested directories in phase 3
211
+ }
212
+
213
+ sidebar[FileRouter.pathToExpression(dirPath)] = sidebarItems
214
+ }
215
+
165
216
  const projectData: ProjectData = {
166
217
  schema,
167
218
  siteNavigationItems,
219
+ sidebar,
168
220
  faviconPath: `/logo.svg`,
169
221
  pagesScanResult: pagesScanResult,
170
222
  paths: config.paths.project,
@@ -204,25 +256,16 @@ export const Core = (config: Configurator.Config): Vite.PluginOption[] => {
204
256
 
205
257
  // todo: kit fs should accept parsed file paths
206
258
  for (const route of pagesScanResult.routes) {
207
- const filePath = Path.format(route.file.path.absolute)
208
- const path = FileRouter.routeToString(route)
209
- const ident = Str.Case.camel(`page ` + Str.titlizeSlug(path))
259
+ const filePathExp = Path.format(route.file.path.absolute)
260
+ const pathExp = FileRouter.routeToPathExpression(route)
261
+ const ident = Str.Case.camel(`page ` + Str.titlizeSlug(pathExp))
210
262
 
211
263
  s`
212
- import ${ident} from '${filePath}'
264
+ import ${ident} from '${filePathExp}'
213
265
 
214
266
  ${$.pages}.push({
215
- path: '${path}',
216
- Component: () => {
217
- if (typeof ${ident} === 'function') {
218
- // ━ MDX
219
- const Component = ${ident}
220
- return <Component />
221
- } else {
222
- // ━ MD
223
- return <div dangerouslySetInnerHTML={{ __html: ${ident} }} />
224
- }
225
- }
267
+ path: '${pathExp}',
268
+ Component: ${ident}
226
269
  })
227
270
  `
228
271
  }
@@ -21,7 +21,7 @@ describe('.scan', () => {
21
21
  const routes = await scan(project.dir)
22
22
  expect(routes).toMatchObject($({
23
23
  routes: [{
24
- path: { segments: ['a'] },
24
+ logical: { path: ['a'] },
25
25
  file: { path: { relative: { dir: '', base: 'a.md' } } },
26
26
  }],
27
27
  }))
@@ -31,7 +31,7 @@ describe('.scan', () => {
31
31
  const routes = await scan(project.dir)
32
32
  expect(routes).toMatchObject($({
33
33
  routes: [{
34
- path: { segments: ['a', 'b'] },
34
+ logical: { path: ['a', 'b'] },
35
35
  file: { path: { relative: { dir: 'a', base: 'b.md' } } },
36
36
  }],
37
37
  }))
@@ -43,7 +43,7 @@ describe('.scan', () => {
43
43
  const routes = await scan(project.dir)
44
44
  expect(routes).toMatchObject($({
45
45
  routes: [{
46
- path: { segments: [] },
46
+ logical: { path: [] },
47
47
  file: { path: { relative: { dir: '', base: 'index.md' } } },
48
48
  }],
49
49
  }))
@@ -53,7 +53,7 @@ describe('.scan', () => {
53
53
  const routes = await scan(project.dir)
54
54
  expect(routes).toMatchObject($({
55
55
  routes: [{
56
- path: { segments: ['a'] },
56
+ logical: { path: ['a'] },
57
57
  file: { path: { relative: { dir: 'a', base: 'index.md' } } },
58
58
  }],
59
59
  }))
@@ -66,7 +66,7 @@ describe('.scan', () => {
66
66
  expect(routes).toMatchObject($({
67
67
  diagnostics: [{}],
68
68
  routes: [{
69
- path: { segments: ['a'] },
69
+ logical: { path: ['a'] },
70
70
  file: { path: { relative: { dir: '', base: 'a.md' } } },
71
71
  }],
72
72
  }))
@@ -1,5 +1,5 @@
1
1
  import { Idx, Path } from '@wollybeard/kit'
2
- import { type Route, type RouteFile, routeIsIndex, routeToString } from './route.js'
2
+ import { type Route, type RouteFile, routeIsFromIndexFile, routeToPathExpression } from './route.js'
3
3
 
4
4
  export type Diagnostic = DiagnosticIndexConflict
5
5
 
@@ -21,7 +21,7 @@ export interface LintResult {
21
21
  export const lint = (routes: Route[]): LintResult => {
22
22
  const diagnostics: Diagnostic[] = []
23
23
 
24
- const seen = Idx.create({ toKey: routeToString })
24
+ const seen = Idx.create({ toKey: routeToPathExpression })
25
25
 
26
26
  // ━ Check for conflict between index and literal.
27
27
  // Note: There is no other way for paths to conflict so we safely assuming the cause is index+literal.
@@ -31,7 +31,7 @@ export const lint = (routes: Route[]): LintResult => {
31
31
 
32
32
  if (seenRoute) {
33
33
  // Fix - ignore the index
34
- const [index, literal] = routeIsIndex(route) ? [route, seenRoute] : [seenRoute, route]
34
+ const [index, literal] = routeIsFromIndexFile(route) ? [route, seenRoute] : [seenRoute, route]
35
35
  if (seenRoute === index) {
36
36
  seen.set(route)
37
37
  }
@@ -1,9 +1,45 @@
1
- import type { Path } from '@wollybeard/kit'
1
+ import { arrayEquals } from '#lib/kit-temp.js'
2
+ import { type Path } from '@wollybeard/kit'
2
3
 
3
- export type RoutePathSegment = string
4
+ //
5
+ //
6
+ //
7
+ //
8
+ // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ • Path
9
+ //
10
+ //
4
11
 
5
- export interface RoutePath {
6
- segments: RoutePathSegment[]
12
+ export type Path = PathSegment[]
13
+
14
+ export type PathRoot = []
15
+
16
+ export type PathTop = [PathSegment]
17
+
18
+ export type PathSub = [PathSegment, PathSegment, ...PathSegment[]]
19
+
20
+ export type PathSegment = string
21
+
22
+ export const sep = `/`
23
+
24
+ export const pathToExpression = (path: Path) => {
25
+ return sep + path.join(sep)
26
+ }
27
+
28
+ //
29
+ //
30
+ //
31
+ //
32
+ // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ • Route (Generic)
33
+ //
34
+ //
35
+
36
+ export interface Route {
37
+ logical: RouteLogical
38
+ file: RouteFile
39
+ }
40
+
41
+ export interface RouteLogical {
42
+ path: Path
7
43
  }
8
44
 
9
45
  export interface RouteFile {
@@ -13,21 +49,121 @@ export interface RouteFile {
13
49
  }
14
50
  }
15
51
 
16
- export interface Route {
17
- path: RoutePath
18
- file: RouteFile
52
+ //
53
+ //
54
+ //
55
+ //
56
+ // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ • Top Level Route
57
+ //
58
+ //
59
+
60
+ export interface TopLevelRoute extends Route {
61
+ logical: TopLevelRouteLogical
19
62
  }
20
63
 
21
- export const sep = `/`
64
+ export interface TopLevelRouteLogical {
65
+ path: PathTop
66
+ }
22
67
 
23
- export const routeToString = (route: Route) => {
24
- return sep + route.path.segments.join(sep)
68
+ /**
69
+ * Route is top level meaning exists directly under the root.
70
+ *
71
+ * It excludes the root level route.
72
+ */
73
+ export const routeIsTopLevel = (route: Route): route is TopLevelRoute => {
74
+ return route.logical.path.length === 1
25
75
  }
26
76
 
27
- export const routeIsIndex = (route: Route) => {
77
+ //
78
+ // ━━ Sub Level
79
+ //
80
+
81
+ //
82
+ //
83
+ //
84
+ //
85
+ // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ • Sub Level Route
86
+ //
87
+ //
88
+
89
+ export interface RouteSubLevel extends Route {
90
+ logical: RoutePathSubLevel
91
+ }
92
+
93
+ export interface RoutePathSubLevel {
94
+ path: PathSub
95
+ }
96
+
97
+ /**
98
+ * Route is not top or root level
99
+ */
100
+ export const routeIsSubLevel = (route: Route): route is RouteSubLevel => {
101
+ return route.logical.path.length > 1
102
+ }
103
+
104
+ //
105
+ // ━━ Root Level
106
+ //
107
+
108
+ //
109
+ //
110
+ //
111
+ //
112
+ // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ • Root Level Route
113
+ //
114
+ //
115
+
116
+ /**
117
+ * Route is the singular root route.
118
+
119
+ * This is the case of index under root.
120
+ */
121
+ export const routeIsRootLevel = (route: Route): route is TopLevelRoute => {
122
+ // No need to check for name "index"
123
+ // Segments is uniquely empty for <root>/index
124
+ return route.logical.path.length === 0
125
+ }
126
+
127
+ //
128
+ //
129
+ //
130
+ // ━━━━━━━━━━━━━━ • Route Functions
131
+ //
132
+ //
133
+
134
+ export const routeIsFromIndexFile = (route: Route): boolean => {
28
135
  return route.file.path.relative.name === conventions.index.name
29
136
  }
30
137
 
138
+ export const routeIsSubOf = (route: Route, potentialAncestorPath: PathSegment[]): boolean => {
139
+ if (route.logical.path.length <= potentialAncestorPath.length) {
140
+ return false
141
+ }
142
+ return arrayEquals(
143
+ route.logical.path.slice(0, potentialAncestorPath.length),
144
+ potentialAncestorPath,
145
+ )
146
+ }
147
+
148
+ /**
149
+ * You are responsible for ensuring given ancestor path is really an ancestor of given route's path.
150
+ */
151
+ export const makeRelativeUnsafe = (route: Route, assumedAncestorPath: PathSegment[]): Route => {
152
+ // We assume that we're working with paths where index is elided per our FileRouter system.
153
+ const newPath = route.logical.path.slice(assumedAncestorPath.length)
154
+ return {
155
+ ...route,
156
+ logical: {
157
+ ...route.logical,
158
+ path: newPath,
159
+ },
160
+ }
161
+ }
162
+
163
+ export const routeToPathExpression = (route: Route) => {
164
+ return pathToExpression(route.logical.path)
165
+ }
166
+
31
167
  const conventions = {
32
168
  index: {
33
169
  name: `index`,
@@ -1,7 +1,7 @@
1
1
  import { TinyGlobby } from '#dep/tiny-globby/index.js'
2
2
  import { Path, Str } from '@wollybeard/kit'
3
3
  import { type Diagnostic, lint } from './linter.js'
4
- import type { Route, RouteFile, RoutePath } from './route.js'
4
+ import type { Route, RouteFile, RouteLogical } from './route.js'
5
5
 
6
6
  //
7
7
  //
@@ -64,26 +64,26 @@ export const filePathToRoute = (filePathExpression: string, rootDir: string): Ro
64
64
  relative: Path.parse(Path.relative(rootDir, filePathExpression)),
65
65
  },
66
66
  }
67
- const path = filePathToRoutePath(file.path.relative)
67
+ const logical = filePathToRouteLogical(file.path.relative)
68
68
 
69
69
  return {
70
- path,
70
+ logical,
71
71
  file,
72
72
  }
73
73
  }
74
74
 
75
- export const filePathToRoutePath = (filePath: Path.Parsed): RoutePath => {
76
- const dirSegments = Str.split(Str.removeSurrounding(filePath.dir, Path.sep), Path.sep)
75
+ export const filePathToRouteLogical = (filePath: Path.Parsed): RouteLogical => {
76
+ const dirPath = Str.split(Str.removeSurrounding(filePath.dir, Path.sep), Path.sep)
77
77
 
78
78
  if (Str.isMatch(filePath.name, conventions.index.name)) {
79
- const segments = dirSegments
79
+ const path = dirPath
80
80
  return {
81
- segments,
81
+ path,
82
82
  }
83
83
  }
84
84
 
85
- const segments = dirSegments.concat(filePath.name)
85
+ const path = dirPath.concat(filePath.name)
86
86
  return {
87
- segments,
87
+ path,
88
88
  }
89
89
  }
@@ -0,0 +1,21 @@
1
+ //
2
+ //
3
+ //
4
+ //
5
+ //
6
+ // Holding Module for Missing @wollybeard/kit Functionality
7
+ //
8
+ // ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
9
+ //
10
+ // Code here is meant to be migrated eventually to @wollybeard/kit.
11
+ //
12
+ //
13
+ //
14
+
15
+ export const arrayEquals = (a: any[], b: any[]) => {
16
+ if (a.length !== b.length) return false
17
+ for (let i = 0; i < a.length; i++) {
18
+ if (a[i] !== b[i]) return false
19
+ }
20
+ return true
21
+ }
@@ -5,6 +5,7 @@ import type { Schema } from './api/schema/index.js'
5
5
  export interface ProjectData {
6
6
  schema: null | Schema.Schema
7
7
  siteNavigationItems: SiteNavigationItem[]
8
+ sidebar: Sidebar
8
9
  faviconPath: string
9
10
  paths: Configurator.Config[`paths`][`project`]
10
11
  pagesScanResult: FileRouter.ScanResult
@@ -18,5 +19,15 @@ export interface ProjectData {
18
19
 
19
20
  export interface SiteNavigationItem {
20
21
  title: string
21
- path: string
22
+ pathExp: string
23
+ }
24
+
25
+ export interface Sidebar {
26
+ [navPath: string]: SidebarItem[]
27
+ }
28
+
29
+ export interface SidebarItem {
30
+ title: string
31
+ pathExp: string
32
+ children?: SidebarItem[]
22
33
  }