fumadocs-core 9.1.0 → 10.0.0

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.
@@ -1,6 +1,23 @@
1
1
  import { ReactElement } from 'react';
2
2
  import { R as Root } from '../page-tree-mLHMYx2B.js';
3
3
 
4
+ interface FileInfo {
5
+ locale?: string;
6
+ /**
7
+ * Original path of file
8
+ */
9
+ path: string;
10
+ /**
11
+ * File path without extension
12
+ */
13
+ flattenedPath: string;
14
+ /**
15
+ * File name without locale and extension
16
+ */
17
+ name: string;
18
+ dirname: string;
19
+ }
20
+
4
21
  interface LoadOptions {
5
22
  files: VirtualFile[];
6
23
  transformers?: Transformer[];
@@ -15,10 +32,12 @@ interface VirtualFile {
15
32
  }
16
33
  interface LoadResult {
17
34
  storage: Storage;
35
+ }
36
+ type Transformer = (context: {
37
+ storage: Storage;
18
38
  getSlugs: (info: FileInfo) => string[];
19
39
  getUrl: (slugs: string[], locale?: string) => string;
20
- data: Record<string, unknown>;
21
- }
40
+ }) => void;
22
41
  declare function load(options: LoadOptions): LoadResult;
23
42
 
24
43
  interface LoaderConfig {
@@ -54,7 +73,7 @@ interface Source<Config extends SourceConfig> {
54
73
  }
55
74
  interface LoaderOutput<Config extends LoaderConfig> {
56
75
  pageTree: Config['i18n'] extends true ? Record<string, Root> : Root;
57
- files: Node<Config['source']['metaData'], Config['source']['pageData']>[];
76
+ files: (Meta<Config['source']['metaData']> | Page<Config['source']['pageData']>)[];
58
77
  /**
59
78
  * Get list of pages from language, empty if language hasn't specified
60
79
  *
@@ -72,22 +91,6 @@ declare function loader<Options extends LoaderOptions>(options: Options): Loader
72
91
  i18n: Options['languages'] extends string[] ? true : false;
73
92
  }>;
74
93
 
75
- interface FileInfo {
76
- locale?: string;
77
- /**
78
- * Original path of file
79
- */
80
- path: string;
81
- /**
82
- * File path without extension
83
- */
84
- flattenedPath: string;
85
- /**
86
- * File name without locale and extension
87
- */
88
- name: string;
89
- dirname: string;
90
- }
91
94
  interface MetaData {
92
95
  icon?: string;
93
96
  title?: string;
@@ -101,7 +104,6 @@ interface PageData {
101
104
  }
102
105
  type InferPageType<Utils extends LoaderOutput<any>> = Utils extends LoaderOutput<infer Config> ? Page<Config['source']['pageData']> : never;
103
106
  type InferMetaType<Utils extends LoaderOutput<any>> = Utils extends LoaderOutput<infer Config> ? Meta<Config['source']['metaData']> : never;
104
- type Transformer = (context: LoadResult) => void;
105
107
 
106
108
  interface Meta<Data extends MetaData = MetaData> {
107
109
  type: 'meta';
@@ -118,9 +120,8 @@ interface Page<Data extends PageData = PageData> {
118
120
  interface Folder<MD extends MetaData = MetaData, PD extends PageData = PageData> {
119
121
  type: 'folder';
120
122
  file: FileInfo;
121
- children: Node<MD, PD>[];
123
+ children: (Meta<MD> | Page<PD> | Folder<MD, PD>)[];
122
124
  }
123
- type Node<MD extends MetaData = MetaData, PD extends PageData = PageData> = Meta<MD> | Page<PD> | Folder<MD, PD>;
124
125
  /**
125
126
  * A virtual file system that solves inconsistent behaviours
126
127
  *
@@ -152,12 +153,11 @@ declare class Storage {
152
153
 
153
154
  type fileSystem_Folder<MD extends MetaData = MetaData, PD extends PageData = PageData> = Folder<MD, PD>;
154
155
  type fileSystem_Meta<Data extends MetaData = MetaData> = Meta<Data>;
155
- type fileSystem_Node<MD extends MetaData = MetaData, PD extends PageData = PageData> = Node<MD, PD>;
156
156
  type fileSystem_Page<Data extends PageData = PageData> = Page<Data>;
157
157
  type fileSystem_Storage = Storage;
158
158
  declare const fileSystem_Storage: typeof Storage;
159
159
  declare namespace fileSystem {
160
- export { type fileSystem_Folder as Folder, type fileSystem_Meta as Meta, type fileSystem_Node as Node, type fileSystem_Page as Page, fileSystem_Storage as Storage };
160
+ export { type fileSystem_Folder as Folder, type fileSystem_Meta as Meta, type fileSystem_Page as Page, fileSystem_Storage as Storage };
161
161
  }
162
162
 
163
163
  interface BuildPageTreeOptionsWithI18n {
@@ -176,4 +176,4 @@ interface CreatePageTreeBuilderOptions {
176
176
  }
177
177
  declare function createPageTreeBuilder({ storage, resolveIcon, }: CreatePageTreeBuilderOptions): PageTreeBuilder;
178
178
 
179
- export { type BuildPageTreeOptionsWithI18n, type CreatePageTreeBuilderOptions, type FileInfo, fileSystem as FileSystem, type InferMetaType, type InferPageType, type LoadOptions, type LoadResult, type LoaderOptions, type LoaderOutput, type MetaData, type PageData, type PageTreeBuilder, type Source, type Transformer, type VirtualFile, createPageTreeBuilder, load, loader };
179
+ export { type BuildPageTreeOptionsWithI18n, type CreatePageTreeBuilderOptions, fileSystem as FileSystem, type InferMetaType, type InferPageType, type LoadOptions, type LoadResult, type LoaderOptions, type LoaderOutput, type MetaData, type PageData, type PageTreeBuilder, type Source, type Transformer, type VirtualFile, createPageTreeBuilder, load, loader };
@@ -49,6 +49,7 @@ function joinPaths(paths, slashMode = "none") {
49
49
  }
50
50
 
51
51
  // src/source/page-tree-builder.ts
52
+ var external = new RegExp("\\[(?<text>.+)\\]\\((?<url>.+)\\)");
52
53
  var separator = new RegExp("---(?<name>.*?)---");
53
54
  var rest = "...";
54
55
  var extractor = new RegExp("\\.\\.\\.(?<name>.+)");
@@ -95,6 +96,17 @@ function resolveFolderItem(folder, item, ctx, addedNodePaths) {
95
96
  }
96
97
  ];
97
98
  }
99
+ const externalResult = external.exec(item);
100
+ if (externalResult == null ? void 0 : externalResult.groups) {
101
+ return [
102
+ {
103
+ type: "page",
104
+ name: externalResult.groups.text,
105
+ url: externalResult.groups.url,
106
+ external: true
107
+ }
108
+ ];
109
+ }
98
110
  const extractResult = extractor.exec(item);
99
111
  const path2 = joinPaths([
100
112
  folder.file.path,
@@ -106,7 +118,7 @@ function resolveFolderItem(folder, item, ctx, addedNodePaths) {
106
118
  addedNodePaths.add(itemNode.file.path);
107
119
  if (itemNode.type === "folder") {
108
120
  const node = buildFolderNode(itemNode, false, ctx);
109
- return (extractResult == null ? void 0 : extractResult.groups) ? node.children : [node];
121
+ return extractResult ? node.children : [node];
110
122
  }
111
123
  return [buildFileNode(itemNode, ctx)];
112
124
  }
@@ -289,16 +301,14 @@ var Storage = class {
289
301
  function load(options) {
290
302
  const { transformers = [] } = options;
291
303
  const storage = buildStorage(options);
292
- const ctx = {
293
- getSlugs: options.getSlugs,
294
- getUrl: options.getUrl,
295
- storage,
296
- data: {}
297
- };
298
304
  for (const transformer of transformers) {
299
- transformer(ctx);
305
+ transformer({
306
+ storage,
307
+ getUrl: options.getUrl,
308
+ getSlugs: options.getSlugs
309
+ });
300
310
  }
301
- return ctx;
311
+ return { storage };
302
312
  }
303
313
  function buildStorage(options) {
304
314
  const storage = new Storage();
@@ -307,8 +317,7 @@ function buildStorage(options) {
307
317
  path.relative(options.rootDir, path.join("./", path.dirname(file.path))),
308
318
  path.basename(file.path)
309
319
  );
310
- const isRelative = !relativePath.startsWith("..") && !path.isAbsolute(relativePath);
311
- if (!isRelative)
320
+ if (relativePath.startsWith("..") || path.isAbsolute(relativePath))
312
321
  continue;
313
322
  if (file.type === "page") {
314
323
  const parsedPath = parseFilePath(relativePath);
@@ -330,26 +339,20 @@ function buildStorage(options) {
330
339
  return storage;
331
340
  }
332
341
 
333
- // src/source/create.ts
334
- function groupByLanguages(nodes, languages) {
342
+ // src/source/loader.ts
343
+ function groupByLanguages(storage, languages) {
335
344
  var _a, _b, _c;
336
- const pageMap = /* @__PURE__ */ new Map();
337
- for (const node of nodes) {
338
- if (node.type === "page")
339
- pageMap.set(node.file.flattenedPath, node);
340
- }
341
345
  const langMap = /* @__PURE__ */ new Map();
342
346
  langMap.set("", []);
343
- for (const lang of languages) {
344
- langMap.set(lang, []);
345
- }
346
- for (const [key, node] of pageMap) {
347
- if (node.file.locale)
347
+ for (const node of storage.list()) {
348
+ if (node.type !== "page" || node.file.locale)
348
349
  continue;
349
350
  (_a = langMap.get("")) == null ? void 0 : _a.push(node);
350
351
  for (const lang of languages) {
351
- const v = (_b = pageMap.get(`${key}.${lang}`)) != null ? _b : node;
352
- (_c = langMap.get(lang)) == null ? void 0 : _c.push(v);
352
+ const list = (_b = langMap.get(lang)) != null ? _b : [];
353
+ const page = (_c = storage.readPage(`${node.file.flattenedPath}.${lang}`)) != null ? _c : node;
354
+ list.push(page);
355
+ langMap.set(lang, list);
353
356
  }
354
357
  }
355
358
  return langMap;
@@ -386,7 +389,7 @@ function createOutput({
386
389
  getSlugs: slugs,
387
390
  getUrl: url
388
391
  });
389
- const i18nMap = groupByLanguages(result.storage.list(), languages != null ? languages : []);
392
+ const i18nMap = groupByLanguages(result.storage, languages != null ? languages : []);
390
393
  const builder = createPageTreeBuilder({
391
394
  storage: result.storage,
392
395
  resolveIcon: icon
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fumadocs-core",
3
- "version": "9.1.0",
3
+ "version": "10.0.0",
4
4
  "description": "The library for building a documentation website in Next.js",
5
5
  "keywords": [
6
6
  "NextJs",
@@ -44,10 +44,6 @@
44
44
  "import": "./dist/link.js",
45
45
  "types": "./dist/link.d.ts"
46
46
  },
47
- "./typescript": {
48
- "import": "./dist/typescript.js",
49
- "types": "./dist/typescript.d.ts"
50
- },
51
47
  "./middleware": {
52
48
  "import": "./dist/middleware.js",
53
49
  "types": "./dist/middleware.d.ts"
@@ -76,9 +72,6 @@
76
72
  "toc": [
77
73
  "./dist/toc.d.ts"
78
74
  ],
79
- "typescript": [
80
- "./dist/typescript.d.ts"
81
- ],
82
75
  "search/client": [
83
76
  "./dist/search/client.d.ts"
84
77
  ],
@@ -142,7 +135,7 @@
142
135
  "@types/react": "18.2.0",
143
136
  "@types/react-dom": "18.2.1",
144
137
  "algoliasearch": "^4.20.0",
145
- "next": "14.1.0",
138
+ "next": "14.1.1",
146
139
  "unified": "^11.0.4",
147
140
  "eslint-config-custom": "0.0.0",
148
141
  "tsconfig": "0.0.0"
@@ -1,37 +0,0 @@
1
- import * as ts from 'typescript';
2
-
3
- interface DocEntry {
4
- name: string;
5
- description: string;
6
- type: string;
7
- default?: string;
8
- }
9
- interface Context {
10
- program: ts.Program;
11
- checker: ts.TypeChecker;
12
- options: Options;
13
- }
14
- interface EntryContext extends Context {
15
- type: ts.Type;
16
- symbol: ts.Symbol;
17
- }
18
- interface Options {
19
- file: string;
20
- name: string;
21
- /**
22
- * Modify output property entry
23
- */
24
- transform?: (this: EntryContext, entry: DocEntry, propertyType: ts.Type, propertySymbol: ts.Symbol) => void;
25
- options?: Partial<{
26
- files: string[];
27
- tsconfigPath: string;
28
- /** A root directory to resolve relative path entries in the config file to. e.g. outDir */
29
- basePath: string;
30
- }>;
31
- }
32
- /**
33
- * Generate documentation for properties in an exported type/interface
34
- */
35
- declare function generateDocumentation(options: Options): DocEntry[];
36
-
37
- export { type DocEntry, type Options, generateDocumentation };
@@ -1,90 +0,0 @@
1
- import {
2
- __spreadProps,
3
- __spreadValues
4
- } from "./chunk-WEAGW6MQ.js";
5
-
6
- // src/typescript.ts
7
- import * as ts from "typescript";
8
- var cache = /* @__PURE__ */ new Map();
9
- function getProgram(options = {}) {
10
- var _a, _b, _c;
11
- const key = JSON.stringify(options);
12
- const cached = cache.get(key);
13
- if (cached)
14
- return cached;
15
- const configFile = ts.readJsonConfigFile(
16
- (_a = options.tsconfigPath) != null ? _a : "./tsconfig.json",
17
- (path) => ts.sys.readFile(path)
18
- );
19
- const parsed = ts.parseJsonSourceFileConfigFileContent(
20
- configFile,
21
- ts.sys,
22
- (_b = options.basePath) != null ? _b : "./"
23
- );
24
- const program = ts.createProgram({
25
- rootNames: (_c = options.files) != null ? _c : parsed.fileNames,
26
- options: __spreadProps(__spreadValues({}, parsed.options), {
27
- incremental: false
28
- })
29
- });
30
- cache.set(key, program);
31
- return program;
32
- }
33
- function getExportedSymbol({
34
- options: { file, name },
35
- checker,
36
- program
37
- }) {
38
- const sourceFile = program.getSourceFile(file);
39
- if (!sourceFile)
40
- return;
41
- const fileSymbol = checker.getSymbolAtLocation(sourceFile);
42
- if (!fileSymbol)
43
- return;
44
- const exports = checker.getExportsOfModule(fileSymbol);
45
- return exports.find((e) => e.getEscapedName().toString() === name);
46
- }
47
- function generateDocumentation(options) {
48
- const program = getProgram(options.options);
49
- const checker = program.getTypeChecker();
50
- const ctx = {
51
- checker,
52
- program,
53
- options
54
- };
55
- const symbol = getExportedSymbol(ctx);
56
- if (!symbol)
57
- return [];
58
- const type = checker.getDeclaredTypeOfSymbol(symbol);
59
- const entryContext = __spreadProps(__spreadValues({}, ctx), {
60
- type,
61
- symbol
62
- });
63
- return type.getProperties().map(getDocEntry.bind(entryContext));
64
- }
65
- function getDocEntry(prop) {
66
- var _a;
67
- const subType = this.checker.getTypeOfSymbol(prop);
68
- const defaultJsDocTag = prop.getJsDocTags().find((info) => ["default", "defaultValue"].includes(info.name));
69
- let typeName = this.checker.typeToString(
70
- subType.getNonNullableType(),
71
- void 0,
72
- ts.TypeFormatFlags.UseAliasDefinedOutsideCurrentScope
73
- );
74
- if (subType.aliasSymbol && !subType.aliasTypeArguments) {
75
- typeName = subType.aliasSymbol.escapedName.toString();
76
- }
77
- const entry = {
78
- name: prop.getName(),
79
- description: ts.displayPartsToString(
80
- prop.getDocumentationComment(this.checker)
81
- ),
82
- default: (defaultJsDocTag == null ? void 0 : defaultJsDocTag.text) ? ts.displayPartsToString(defaultJsDocTag.text) : void 0,
83
- type: typeName
84
- };
85
- (_a = this.options.transform) == null ? void 0 : _a.call(this, entry, subType, prop);
86
- return entry;
87
- }
88
- export {
89
- generateDocumentation
90
- };