@xyd-js/content 0.1.0-xyd.4 → 0.1.0-xyd.55

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 (98) hide show
  1. package/CHANGELOG.md +628 -0
  2. package/ISSUES.md +1 -0
  3. package/LICENSE +21 -0
  4. package/TODO.md +2 -0
  5. package/dist/index.d.ts +27 -1733
  6. package/dist/index.js +1602 -179
  7. package/dist/index.js.map +1 -0
  8. package/dist/md.d.ts +69 -0
  9. package/dist/md.js +23396 -0
  10. package/dist/md.js.map +1 -0
  11. package/dist/mdToc-NBBxMJ4l.d.ts +12 -0
  12. package/dist/vite.d.ts +1066 -0
  13. package/dist/vite.js +20046 -0
  14. package/dist/vite.js.map +1 -0
  15. package/package.json +27 -7
  16. package/packages/md/index.ts +22 -0
  17. package/packages/md/plugins/component-directives/index.ts +3 -0
  18. package/packages/md/plugins/component-directives/mdComponentDirective.ts +524 -0
  19. package/packages/md/plugins/component-directives/types.ts +1 -0
  20. package/packages/md/plugins/component-directives/utils.ts +27 -0
  21. package/packages/md/plugins/composer/__fixtures__/1.single-example/input.md +7 -0
  22. package/packages/md/plugins/composer/__fixtures__/1.single-example/output.json +63 -0
  23. package/packages/md/plugins/composer/__fixtures__/2.single-example-with-name/input.md +7 -0
  24. package/packages/md/plugins/composer/__fixtures__/2.single-example-with-name/output.json +63 -0
  25. package/packages/md/plugins/composer/__fixtures__/3.multiple-examples/input.md +15 -0
  26. package/packages/md/plugins/composer/__fixtures__/3.multiple-examples/output.json +122 -0
  27. package/packages/md/plugins/composer/__fixtures__/4.example-groups/input.md +23 -0
  28. package/packages/md/plugins/composer/__fixtures__/4.example-groups/output.json +184 -0
  29. package/packages/md/plugins/composer/__tests__/mdComposer.test.ts +41 -0
  30. package/packages/md/plugins/composer/__tests__/testHelpers.ts +48 -0
  31. package/packages/md/plugins/composer/index.ts +1 -0
  32. package/packages/md/plugins/composer/mdComposer.ts +146 -0
  33. package/packages/md/plugins/developer-writing/index.ts +3 -0
  34. package/packages/md/plugins/developer-writing/mdCodeRehype.ts +78 -0
  35. package/packages/md/plugins/functions/__fixtures__/external.ts +4 -0
  36. package/packages/md/plugins/functions/__fixtures__/test.js +11 -0
  37. package/packages/md/plugins/functions/__fixtures__/test.py +9 -0
  38. package/packages/md/plugins/functions/__fixtures__/test.ts +18 -0
  39. package/packages/md/plugins/functions/__tests__/mdFunctionImportCode.test.ts +295 -0
  40. package/packages/md/plugins/functions/__tests__/parseFunctionCall.test.ts +47 -0
  41. package/packages/md/plugins/functions/__tests__/testHelpers.ts +71 -0
  42. package/packages/md/plugins/functions/index.ts +11 -0
  43. package/packages/md/plugins/functions/mdFunctionChangelog.ts +124 -0
  44. package/packages/md/plugins/functions/mdFunctionImportCode.ts +83 -0
  45. package/packages/md/plugins/functions/mdFunctionUniform.ts +79 -0
  46. package/packages/md/plugins/functions/types.ts +6 -0
  47. package/packages/md/plugins/functions/uniformProcessor.ts +349 -0
  48. package/packages/md/plugins/functions/utils.ts +423 -0
  49. package/packages/md/plugins/index.ts +71 -0
  50. package/packages/md/plugins/mdCode.ts +67 -0
  51. package/packages/md/plugins/mdHeadingId.ts +47 -0
  52. package/packages/md/plugins/mdPage.ts +35 -0
  53. package/{src/mdx/themeSettings.ts → packages/md/plugins/mdThemeSettings.ts} +8 -0
  54. package/packages/md/plugins/mdToc.ts +224 -0
  55. package/packages/md/plugins/meta/index.ts +1 -0
  56. package/packages/md/plugins/meta/mdMeta.ts +189 -0
  57. package/packages/md/plugins/output-variables/__fixtures__/1.simple/input.md +22 -0
  58. package/packages/md/plugins/output-variables/__fixtures__/1.simple/output.json +191 -0
  59. package/packages/md/plugins/output-variables/__fixtures__/2.multiple-vars/input.md +21 -0
  60. package/packages/md/plugins/output-variables/__fixtures__/2.multiple-vars/output.json +127 -0
  61. package/packages/md/plugins/output-variables/__tests__/index.test.ts +28 -0
  62. package/packages/md/plugins/output-variables/__tests__/testHelpers.ts +36 -0
  63. package/packages/md/plugins/output-variables/index.ts +1 -0
  64. package/packages/md/plugins/output-variables/lib/const.ts +4 -0
  65. package/packages/md/plugins/output-variables/lib/factoryAttributes.ts +350 -0
  66. package/packages/md/plugins/output-variables/lib/factoryLabel.ts +135 -0
  67. package/packages/md/plugins/output-variables/lib/factoryName.ts +59 -0
  68. package/packages/md/plugins/output-variables/lib/index.ts +21 -0
  69. package/packages/md/plugins/output-variables/lib/outputVarsContainer.ts +328 -0
  70. package/packages/md/plugins/output-variables/lib/util.ts +494 -0
  71. package/packages/md/plugins/output-variables/remarkOutputVars.ts +22 -0
  72. package/packages/md/plugins/rehypeHeading.ts +50 -0
  73. package/packages/md/plugins/types.ts +15 -0
  74. package/packages/md/plugins/utils/componentLike.ts +72 -0
  75. package/packages/md/plugins/utils/index.ts +2 -0
  76. package/packages/md/plugins/utils/mdParameters.test.ts +114 -0
  77. package/packages/md/plugins/utils/mdParameters.ts +249 -0
  78. package/packages/md/plugins/utils/mdastTypes.ts +42 -0
  79. package/packages/md/search/index.ts +251 -0
  80. package/packages/md/search/types.ts +36 -0
  81. package/{src/vite-plugins → packages/vite}/index.ts +8 -3
  82. package/src/fs.ts +58 -0
  83. package/src/index.ts +8 -0
  84. package/src/{navigation/index.ts → navigation.ts} +54 -58
  85. package/src/types.ts +8 -0
  86. package/tsconfig.json +31 -8
  87. package/tsup.config.ts +8 -6
  88. package/vitest.config.ts +17 -0
  89. package/dist/navigation.d.ts +0 -6
  90. package/dist/navigation.js +0 -2345
  91. package/index.ts +0 -10
  92. package/navigation.ts +0 -4
  93. package/src/mdx/code.ts +0 -15
  94. package/src/mdx/options.ts +0 -23
  95. package/src/mdx/page.ts +0 -22
  96. package/src/mdx/toc.ts +0 -132
  97. package/src/utils/index.ts +0 -43
  98. package/vite.config.js +0 -53
@@ -1,15 +1,20 @@
1
1
  import type {Plugin} from 'rollup';
2
2
  import mdx from '@mdx-js/rollup';
3
3
 
4
- import {RemarkMdxTocOptions} from "@/mdx/toc";
5
- import {mdxOptions} from "@/mdx/options";
4
+ import {Settings} from "@xyd-js/core";
5
+
6
+ import {RemarkMdxTocOptions, markdownPlugins} from "../md";
6
7
 
7
8
  export interface VitePluginInterface {
8
9
  toc: RemarkMdxTocOptions
10
+ settings: Settings
9
11
  }
10
12
 
11
13
  export function vitePlugins(options: VitePluginInterface): Plugin[] {
12
14
  return [
13
- mdx(mdxOptions(options.toc)),
15
+ mdx(markdownPlugins(
16
+ options.toc,
17
+ options.settings
18
+ )),
14
19
  ];
15
20
  }
package/src/fs.ts ADDED
@@ -0,0 +1,58 @@
1
+ import fs from "fs/promises"
2
+
3
+ import { VFile } from "vfile"
4
+ import { PluggableList } from "unified";
5
+ import { compile as mdxCompile } from "@mdx-js/mdx";
6
+
7
+ import { Settings } from "@xyd-js/core"
8
+
9
+ export {
10
+ pageFrontMatters,
11
+ filterNavigationByLevels
12
+ } from "./navigation"
13
+
14
+ export type { VarCode } from "./types"
15
+
16
+ export class ContentFS {
17
+ constructor(
18
+ private readonly settings: Settings,
19
+ private readonly remarkPlugins: PluggableList,
20
+ private readonly rehypePlugins: PluggableList,
21
+ ) { }
22
+
23
+ public async compile(filePath: string): Promise<string> {
24
+ await fs.access(filePath)
25
+
26
+ const content = await fs.readFile(filePath, "utf-8");
27
+
28
+ return await this.compileContent(content, filePath)
29
+ }
30
+
31
+
32
+ public async compileContent(content: string, filePath?: string): Promise<string> {
33
+ const vfile = new VFile({
34
+ path: filePath,
35
+ value: content,
36
+ contents: content
37
+ });
38
+
39
+ const compiled = await mdxCompile(vfile, {
40
+ remarkPlugins: this.remarkPlugins,
41
+ rehypePlugins: this.rehypePlugins,
42
+ recmaPlugins: [],
43
+ outputFormat: 'function-body',
44
+ development: false,
45
+ jsx: false
46
+ });
47
+
48
+ return String(compiled)
49
+ }
50
+
51
+ public async readRaw(filePath: string) {
52
+ await fs.access(filePath)
53
+
54
+ const content = await fs.readFile(filePath, "utf-8");
55
+
56
+ return content
57
+ }
58
+ }
package/src/index.ts ADDED
@@ -0,0 +1,8 @@
1
+ export { ContentFS } from "./fs"
2
+
3
+ export {
4
+ pageFrontMatters,
5
+ filterNavigationByLevels
6
+ } from "./navigation"
7
+
8
+ export type { VarCode } from "./types"
@@ -1,31 +1,33 @@
1
- import {promises as fs} from 'fs';
2
- import fs2, {open} from 'fs';
1
+ import { promises as fs } from 'fs';
3
2
  import path from 'path';
4
3
 
5
4
  import React from "react";
6
5
  import remarkFrontmatter from "remark-frontmatter";
7
6
  import remarkMdxFrontmatter from "remark-mdx-frontmatter";
8
- import matter from 'gray-matter';
9
- import {VFile} from "vfile";
10
- import {compile as mdxCompile} from "@mdx-js/mdx";
7
+ import { VFile } from "vfile";
8
+ import { compile as mdxCompile } from "@mdx-js/mdx";
11
9
 
12
- import {FrontMatter, Sidebar, PageFrontMatter, Header} from "@xyd-js/core";
10
+ import { Metadata, Sidebar, MetadataMap, Header, PageURL, VirtualPage } from "@xyd-js/core";
13
11
 
14
12
  // TODO: better algorithm + data structures - since it's on build time it's not a big deal nevertheless it should be changed in the future
15
13
 
16
14
  // pageFrontMatters gets frontmatters for given navigation
17
- export async function pageFrontMatters(navigation: Sidebar[]): Promise<PageFrontMatter> {
18
- const frontmatters: PageFrontMatter = {}
15
+ export async function pageFrontMatters(navigation: Sidebar[], pagePathMapping: { [key: string]: string }): Promise<MetadataMap> {
16
+ const frontmatters: MetadataMap = {}
19
17
 
20
18
  const promises: Promise<any>[] = []
21
19
 
22
- function mapPages(page: string | Sidebar) {
20
+ function mapPages(page: PageURL) {
23
21
  if (typeof page !== "string") {
24
- page.pages?.forEach(mapPages)
22
+ if ("virtual" in page) {
23
+ promises.push(job(page, frontmatters, pagePathMapping))
24
+ } else if ("pages" in page) {
25
+ page.pages?.forEach(mapPages)
26
+ }
25
27
  return
26
28
  }
27
29
 
28
- promises.push(job(page, frontmatters))
30
+ promises.push(job(page, frontmatters, pagePathMapping))
29
31
  }
30
32
 
31
33
  navigation.map(async (nav: Sidebar) => {
@@ -43,7 +45,7 @@ export function filterNavigationByLevels(
43
45
  slug: string
44
46
  ) {
45
47
  const topLevelTabMatcher = headers?.reduce((acc: any, header) => {
46
- const tabLevel = header?.url?.split("/")?.length
48
+ const tabLevel = header?.page?.split("/")?.length
47
49
 
48
50
  if (!tabLevel) {
49
51
  return {
@@ -54,13 +56,13 @@ export function filterNavigationByLevels(
54
56
  if (!acc[tabLevel]) {
55
57
  return {
56
58
  ...acc,
57
- [tabLevel]: new Set().add(header?.url)
59
+ [tabLevel]: new Set().add(header?.page)
58
60
  }
59
61
  }
60
62
 
61
63
  return {
62
64
  ...acc,
63
- [tabLevel]: acc[tabLevel].add(header?.url)
65
+ [tabLevel]: acc[tabLevel].add(header?.page)
64
66
  }
65
67
  }, {}) as { [level: number]: Set<string> }
66
68
 
@@ -74,11 +76,20 @@ export function filterNavigationByLevels(
74
76
  const level = parseInt(levelStr)
75
77
  const findThisSlug = slug.split("/").filter(s => !!s).slice(0, level).join("/")
76
78
 
77
- function findMatchedPage(page: string | Sidebar) {
79
+ function findMatchedPage(page: PageURL) {
78
80
  if (typeof page !== "string") {
79
- page.pages?.forEach(findMatchedPage)
81
+ if ("virtual" in page && page.virtual) {
82
+ return matchPage(page.virtual)
83
+ } else if ("pages" in page) {
84
+ page.pages?.forEach(findMatchedPage)
85
+ }
80
86
  return
81
87
  }
88
+
89
+ return matchPage(page)
90
+ }
91
+
92
+ function matchPage(page: string) {
82
93
  const findThisPage = page.split("/").filter(p => !!p).slice(0, level).join("/")
83
94
 
84
95
  const set = topLevelTabMatcher[level]
@@ -96,27 +107,6 @@ export function filterNavigationByLevels(
96
107
  }
97
108
  }
98
109
 
99
- async function getFrontmatter(filePath: string, chunkSize = 1024 * 5) { // 5 KB chunk
100
- return new Promise((resolve, reject) => {
101
- open(filePath, 'r', (err, fd) => {
102
- if (err) return reject(err);
103
-
104
- const buffer = Buffer.alloc(chunkSize);
105
- fs2.read(fd, buffer, 0, chunkSize, 0, (err, bytesRead) => {
106
- if (err) return reject(err);
107
-
108
- const uint8Array = new Uint8Array(buffer.buffer, buffer.byteOffset, bytesRead);
109
- const content = new TextDecoder('utf-8').decode(uint8Array);
110
- const {data: frontmatter} = matter(content); // extract frontmatter
111
- resolve(frontmatter);
112
-
113
- fs2.close(fd, () => {
114
- });
115
- });
116
- });
117
- });
118
- }
119
-
120
110
  function mdxExport(code: string) {
121
111
  const scope = {
122
112
  Fragment: React.Fragment,
@@ -128,7 +118,7 @@ function mdxExport(code: string) {
128
118
  return fn(scope)
129
119
  }
130
120
 
131
- async function getFrontmatterV2(filePath: string): Promise<FrontMatter> {
121
+ async function getFrontmatter(filePath: string): Promise<Metadata> {
132
122
  const body = await fs.readFile(filePath, "utf-8");
133
123
 
134
124
  const vfile = new VFile({
@@ -155,34 +145,40 @@ async function getFrontmatterV2(filePath: string): Promise<FrontMatter> {
155
145
  frontmatter
156
146
  } = mdxExport(code)
157
147
 
158
- const matter: FrontMatter = frontmatter
148
+ const matter: Metadata = frontmatter
149
+
150
+ if (!matter) {
151
+ throw new Error(`Frontmatter not found in ${filePath}`)
152
+ }
159
153
 
154
+ let title = ""
155
+ if (typeof matter.title === "string") {
156
+ title = matter.title
157
+ }
160
158
  if (reactFrontmatter) {
161
- if (typeof reactFrontmatter?.title === "function") {
162
- matter.title = {
163
- code: reactFrontmatter.title.toString()
164
- }
165
- }
159
+ console.error("currently react frontmatter is not supported")
166
160
  }
167
161
 
168
162
  return matter
169
163
  }
170
164
 
171
- async function job(page: string, frontmatters: PageFrontMatter) {
172
- // TODO: it can be cwd because on build time it has entire path?
173
- let filePath = path.join(process.cwd(), `${page}.mdx`) // TODO: support md toos
174
- try {
175
- await fs.access(filePath)
176
- } catch (e) {
177
- try {
178
- const mdPath = filePath.replace(".mdx", ".md")
179
- await fs.access(mdPath)
180
- filePath = mdPath
181
- } catch (e) {
182
- }
165
+ // TODO: indices map to not do like this - search for mdx if not then md
166
+ async function job(page: string | VirtualPage, frontmatters: MetadataMap, pagePathMapping: { [key: string]: string }) {
167
+ let pageName = ""
168
+ if (typeof page === "string") {
169
+ pageName = page
170
+ } else if (page.page) {
171
+ pageName = page.page
172
+ }
173
+
174
+ if (!pageName || !pagePathMapping[pageName]) {
175
+ console.log(`⚠️ "${pageName}" is defined in the docs.json navigation but the file does not exist.`)
176
+ return
183
177
  }
184
178
 
185
- const matter = await getFrontmatterV2(filePath)
179
+ const filePath = path.join(process.cwd(), pagePathMapping[pageName])
180
+
181
+ const matter = await getFrontmatter(filePath)
186
182
 
187
- frontmatters[page] = matter
183
+ frontmatters[pageName] = matter
188
184
  }
package/src/types.ts ADDED
@@ -0,0 +1,8 @@
1
+ import { HighlightedCode } from "codehike/code"
2
+
3
+ export type VarCode = [
4
+ [
5
+ string,
6
+ ...(HighlightedCode)[]
7
+ ] | HighlightedCode
8
+ ]
package/tsconfig.json CHANGED
@@ -2,10 +2,24 @@
2
2
  "compilerOptions": {
3
3
  "baseUrl": ".",
4
4
  "paths": {
5
- "@/mdx/*": ["src/mdx/*"],
6
- "@/navigation/*": ["src/navigation/*"],
7
- "@/utils/*": ["src/utils/*"],
8
- "@/vite-plugins/*": ["src/vite-plugins/*"]
5
+ "@/mdx/*": [
6
+ "src/mdx/*"
7
+ ],
8
+ "@/navigation/*": [
9
+ "src/navigation/*"
10
+ ],
11
+ "@/utils/*": [
12
+ "src/utils/*"
13
+ ],
14
+ "@/vite-plugins/*": [
15
+ "src/vite-plugins/*"
16
+ ],
17
+ "@xyd-js/core": [
18
+ "../xyd-core"
19
+ ],
20
+ "@xyd-js/context": [
21
+ "../xyd-context/src/index.ts"
22
+ ]
9
23
  },
10
24
  "target": "ES2020",
11
25
  "module": "ESNext",
@@ -15,12 +29,21 @@
15
29
  "skipLibCheck": true,
16
30
  "forceConsistentCasingInFileNames": true,
17
31
  "outDir": "./dist",
18
- "types": ["node", "estree", "vite"],
32
+ "types": [
33
+ "node",
34
+ "estree",
35
+ "vite"
36
+ ],
19
37
  "declaration": true,
20
38
  "declarationMap": true,
21
39
  "incremental": true,
22
- "tsBuildInfoFile": "./dist/tsconfig.tsbuildinfo"
40
+ "tsBuildInfoFile": "./dist/tsconfig.tsbuildinfo",
23
41
  },
24
- "include": ["src/**/*.ts"],
25
- "exclude": ["node_modules", "dist"]
42
+ "include": [
43
+ "src/**/*.ts"
44
+ ],
45
+ "exclude": [
46
+ "node_modules",
47
+ "dist"
48
+ ]
26
49
  }
package/tsup.config.ts CHANGED
@@ -1,21 +1,23 @@
1
- import { defineConfig, Options } from 'tsup';
1
+ import {defineConfig, Options} from 'tsup';
2
2
 
3
3
  const config: Options = {
4
4
  entry: {
5
- index: 'index.ts',
6
- navigation: 'navigation.ts',
5
+ index: 'src/index.ts',
6
+ vite: 'packages/vite/index.ts',
7
+ md: 'packages/md/index.ts',
7
8
  },
8
9
  dts: {
9
10
  entry: {
10
- index: 'index.ts',
11
- navigation: 'navigation.ts',
11
+ index: 'src/index.ts',
12
+ vite: 'packages/vite/index.ts',
13
+ md: 'packages/md/index.ts'
12
14
  },
13
15
  resolve: true, // Resolve external types
14
16
  },
15
17
  format: ['esm'], // Output both ESM and CJS formats
16
18
  target: 'node16', // Ensure compatibility with Node.js 16
17
19
  splitting: false, // Disable code splitting
18
- sourcemap: false, // Generate source maps
20
+ sourcemap: true, // Generate source maps
19
21
  clean: true, // Clean the output directory before each build
20
22
  // esbuildOptions: (options) => {
21
23
  // options.platform = 'node'; // Ensure the platform is set to Node.js
@@ -0,0 +1,17 @@
1
+ import {defineConfig} from 'vitest/config'
2
+
3
+ export default defineConfig({
4
+ test: {
5
+ globals: true,
6
+ environment: 'node',
7
+ include: [
8
+ 'src/**/*.test.ts',
9
+ 'packages/**/*.test.ts',
10
+ '**/__tests__/**/*.test.ts'
11
+ ],
12
+ coverage: {
13
+ provider: 'v8',
14
+ reporter: ['text', 'json', 'html'],
15
+ },
16
+ },
17
+ })
@@ -1,6 +0,0 @@
1
- import { Sidebar, PageFrontMatter, Header } from '@xyd-js/core';
2
-
3
- declare function pageFrontMatters(navigation: Sidebar[]): Promise<PageFrontMatter>;
4
- declare function filterNavigationByLevels(headers: Header[], slug: string): (nav: Sidebar) => boolean;
5
-
6
- export { filterNavigationByLevels, pageFrontMatters };