fumadocs-core 15.6.12 → 15.7.1
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.
- package/dist/breadcrumb.d.ts +1 -1
- package/dist/chunk-HUTQC33E.js +8 -0
- package/dist/chunk-KLUGJRZC.js +72 -0
- package/dist/{chunk-3NX26V7I.js → chunk-NJLFLPV4.js} +0 -2
- package/dist/{page-tree-bSt6K__E.d.ts → definitions-Q95-psoo.d.ts} +16 -12
- package/dist/highlight/client.d.ts +6 -1
- package/dist/highlight/client.js +14 -74
- package/dist/highlight/index.js +1 -1
- package/dist/i18n/index.d.ts +12 -15
- package/dist/i18n/index.js +4 -70
- package/dist/i18n/index.server.d.ts +3 -0
- package/dist/i18n/index.server.js +11 -0
- package/dist/i18n/middleware.d.ts +12 -0
- package/dist/i18n/middleware.js +7 -0
- package/dist/mdx-plugins/index.js +1 -1
- package/dist/search/server.d.ts +15 -14
- package/dist/search/server.js +47 -22
- package/dist/server/index.d.ts +5 -4
- package/dist/server/index.js +23 -22
- package/dist/source/index.d.ts +72 -28
- package/dist/source/index.js +292 -196
- package/package.json +14 -9
package/dist/source/index.js
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
import {
|
|
2
|
+
joinPath,
|
|
3
|
+
slash,
|
|
4
|
+
splitPath
|
|
5
|
+
} from "../chunk-3JSIVMCJ.js";
|
|
1
6
|
import {
|
|
2
7
|
basename,
|
|
3
8
|
dirname,
|
|
@@ -5,14 +10,72 @@ import {
|
|
|
5
10
|
parseFilePath,
|
|
6
11
|
parseFolderPath
|
|
7
12
|
} from "../chunk-7GNSIKII.js";
|
|
8
|
-
import {
|
|
9
|
-
joinPath,
|
|
10
|
-
slash,
|
|
11
|
-
splitPath
|
|
12
|
-
} from "../chunk-3JSIVMCJ.js";
|
|
13
13
|
import "../chunk-JSBRDJBE.js";
|
|
14
14
|
|
|
15
|
-
// src/source/page-tree
|
|
15
|
+
// src/source/page-tree/legacy.ts
|
|
16
|
+
function legacyTransformer(transformer) {
|
|
17
|
+
return {
|
|
18
|
+
file(node, file) {
|
|
19
|
+
if (!transformer.attachFile) return node;
|
|
20
|
+
const content = file ? this.storage.read(file) : void 0;
|
|
21
|
+
return transformer.attachFile(
|
|
22
|
+
node,
|
|
23
|
+
content?.format === "page" ? content : void 0
|
|
24
|
+
);
|
|
25
|
+
},
|
|
26
|
+
folder(node, folderPath, metaPath) {
|
|
27
|
+
if (!transformer.attachFolder) return node;
|
|
28
|
+
const files = this.storage.readDir(folderPath) ?? [];
|
|
29
|
+
const meta = metaPath ? this.storage.read(metaPath) : void 0;
|
|
30
|
+
return transformer.attachFolder(
|
|
31
|
+
node,
|
|
32
|
+
{
|
|
33
|
+
children: files.flatMap((file) => this.storage.read(file) ?? [])
|
|
34
|
+
},
|
|
35
|
+
meta?.format === "meta" ? meta : void 0
|
|
36
|
+
);
|
|
37
|
+
},
|
|
38
|
+
separator(node) {
|
|
39
|
+
if (!transformer.attachSeparator) return node;
|
|
40
|
+
return transformer.attachSeparator(node);
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// src/source/page-tree/transformer-fallback.ts
|
|
46
|
+
function transformerFallback() {
|
|
47
|
+
const addedFiles = /* @__PURE__ */ new Set();
|
|
48
|
+
return {
|
|
49
|
+
name: "fumadocs:fallback",
|
|
50
|
+
root(root) {
|
|
51
|
+
const isolatedStorage = new FileSystem();
|
|
52
|
+
for (const file of this.storage.getFiles()) {
|
|
53
|
+
if (addedFiles.has(file)) continue;
|
|
54
|
+
const content = this.storage.read(file);
|
|
55
|
+
if (content) isolatedStorage.write(file, content);
|
|
56
|
+
}
|
|
57
|
+
if (isolatedStorage.getFiles().length === 0) return root;
|
|
58
|
+
root.fallback = this.builder.build({
|
|
59
|
+
...this.options,
|
|
60
|
+
id: `fallback-${root.$id ?? ""}`,
|
|
61
|
+
storage: isolatedStorage,
|
|
62
|
+
generateFallback: false
|
|
63
|
+
});
|
|
64
|
+
addedFiles.clear();
|
|
65
|
+
return root;
|
|
66
|
+
},
|
|
67
|
+
file(node, file) {
|
|
68
|
+
if (file) addedFiles.add(file);
|
|
69
|
+
return node;
|
|
70
|
+
},
|
|
71
|
+
folder(node, _dir, metaPath) {
|
|
72
|
+
if (metaPath) addedFiles.add(metaPath);
|
|
73
|
+
return node;
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// src/source/page-tree/builder.ts
|
|
16
79
|
var group = /^\((?<name>.+)\)$/;
|
|
17
80
|
var link = /^(?:\[(?<icon>[^\]]+)])?\[(?<name>[^\]]+)]\((?<url>[^)]+)\)$/;
|
|
18
81
|
var separator = /^---(?:\[(?<icon>[^\]]+)])?(?<name>.+)---|^---$/;
|
|
@@ -42,26 +105,34 @@ function resolveFolderItem(folderPath, item, ctx, idx, restNodePaths) {
|
|
|
42
105
|
const { options, resolveName } = ctx;
|
|
43
106
|
let match = separator.exec(item);
|
|
44
107
|
if (match?.groups) {
|
|
45
|
-
|
|
108
|
+
let node = {
|
|
46
109
|
$id: `${folderPath}#${idx}`,
|
|
47
110
|
type: "separator",
|
|
48
111
|
icon: options.resolveIcon?.(match.groups.icon),
|
|
49
112
|
name: match.groups.name
|
|
50
113
|
};
|
|
51
|
-
|
|
114
|
+
for (const transformer of ctx.transformers) {
|
|
115
|
+
if (!transformer.separator) continue;
|
|
116
|
+
node = transformer.separator.call(ctx, node);
|
|
117
|
+
}
|
|
118
|
+
return [node];
|
|
52
119
|
}
|
|
53
120
|
match = link.exec(item);
|
|
54
121
|
if (match?.groups) {
|
|
55
122
|
const { icon, url, name } = match.groups;
|
|
56
123
|
const isRelative = url.startsWith("/") || url.startsWith("#") || url.startsWith(".");
|
|
57
|
-
|
|
124
|
+
let node = {
|
|
58
125
|
type: "page",
|
|
59
126
|
icon: options.resolveIcon?.(icon),
|
|
60
127
|
name,
|
|
61
128
|
url,
|
|
62
129
|
external: !isRelative
|
|
63
130
|
};
|
|
64
|
-
|
|
131
|
+
for (const transformer of ctx.transformers) {
|
|
132
|
+
if (!transformer.file) continue;
|
|
133
|
+
node = transformer.file.call(ctx, node);
|
|
134
|
+
}
|
|
135
|
+
return [node];
|
|
65
136
|
}
|
|
66
137
|
const isExcept = item.startsWith(excludePrefix);
|
|
67
138
|
const isExtract = !isExcept && item.startsWith(extractPrefix);
|
|
@@ -82,24 +153,27 @@ function resolveFolderItem(folderPath, item, ctx, idx, restNodePaths) {
|
|
|
82
153
|
return fileNode ? [fileNode] : [];
|
|
83
154
|
}
|
|
84
155
|
function buildFolderNode(folderPath, isGlobalRoot, ctx) {
|
|
85
|
-
const { storage,
|
|
156
|
+
const { storage, options, resolveName, transformers } = ctx;
|
|
86
157
|
const files = storage.readDir(folderPath);
|
|
87
158
|
if (!files) return;
|
|
88
159
|
const metaPath = resolveName(joinPath(folderPath, "meta"), "meta");
|
|
89
160
|
const indexPath = resolveName(joinPath(folderPath, "index"), "page");
|
|
90
|
-
let meta =
|
|
161
|
+
let meta = storage.read(metaPath);
|
|
91
162
|
if (meta?.format !== "meta") {
|
|
92
163
|
meta = void 0;
|
|
93
164
|
}
|
|
94
|
-
|
|
95
|
-
let indexDisabled = false;
|
|
165
|
+
let indexDisabled = meta?.data.root ?? isGlobalRoot;
|
|
96
166
|
let children;
|
|
97
167
|
if (!meta?.data.pages) {
|
|
98
|
-
children = buildAll(
|
|
168
|
+
children = buildAll(
|
|
169
|
+
files,
|
|
170
|
+
ctx,
|
|
171
|
+
(file) => indexDisabled || file !== indexPath
|
|
172
|
+
);
|
|
99
173
|
} else {
|
|
100
174
|
const restItems = new Set(files);
|
|
101
175
|
const resolved = meta.data.pages.flatMap((item, i) => resolveFolderItem(folderPath, item, ctx, i, restItems));
|
|
102
|
-
if (!
|
|
176
|
+
if (!indexDisabled && !restItems.has(indexPath)) {
|
|
103
177
|
indexDisabled = true;
|
|
104
178
|
}
|
|
105
179
|
for (let i = 0; i < resolved.length; i++) {
|
|
@@ -108,8 +182,7 @@ function buildFolderNode(folderPath, isGlobalRoot, ctx) {
|
|
|
108
182
|
const items = buildAll(
|
|
109
183
|
files,
|
|
110
184
|
ctx,
|
|
111
|
-
|
|
112
|
-
(file) => (file !== indexPath || isRoot) && restItems.has(file),
|
|
185
|
+
(file) => (indexDisabled || file !== indexPath) && restItems.has(file),
|
|
113
186
|
item === restReversed
|
|
114
187
|
);
|
|
115
188
|
resolved.splice(i, 1, ...items);
|
|
@@ -123,7 +196,7 @@ function buildFolderNode(folderPath, isGlobalRoot, ctx) {
|
|
|
123
196
|
const folderName = basename(folderPath);
|
|
124
197
|
name = pathToName(group.exec(folderName)?.[1] ?? folderName);
|
|
125
198
|
}
|
|
126
|
-
|
|
199
|
+
let node = {
|
|
127
200
|
type: "folder",
|
|
128
201
|
name,
|
|
129
202
|
icon: options.resolveIcon?.(meta?.data.icon) ?? index?.icon,
|
|
@@ -137,21 +210,18 @@ function buildFolderNode(folderPath, isGlobalRoot, ctx) {
|
|
|
137
210
|
metaFile: metaPath
|
|
138
211
|
} : void 0
|
|
139
212
|
};
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
}
|
|
146
|
-
},
|
|
147
|
-
meta
|
|
148
|
-
) ?? node;
|
|
213
|
+
for (const transformer of transformers) {
|
|
214
|
+
if (!transformer.folder) continue;
|
|
215
|
+
node = transformer.folder.call(ctx, node, folderPath, metaPath);
|
|
216
|
+
}
|
|
217
|
+
return node;
|
|
149
218
|
}
|
|
150
|
-
function buildFileNode(path,
|
|
151
|
-
const
|
|
219
|
+
function buildFileNode(path, ctx) {
|
|
220
|
+
const { options, getUrl, storage, locale, transformers } = ctx;
|
|
221
|
+
const page = storage.read(path);
|
|
152
222
|
if (page?.format !== "page") return;
|
|
153
223
|
const { title, description, icon } = page.data;
|
|
154
|
-
|
|
224
|
+
let item = {
|
|
155
225
|
$id: path,
|
|
156
226
|
type: "page",
|
|
157
227
|
name: title ?? pathToName(basename(path, extname(path))),
|
|
@@ -162,17 +232,36 @@ function buildFileNode(path, { options, getUrl, storage, localeStorage, locale }
|
|
|
162
232
|
file: path
|
|
163
233
|
} : void 0
|
|
164
234
|
};
|
|
165
|
-
|
|
235
|
+
for (const transformer of transformers) {
|
|
236
|
+
if (!transformer.file) continue;
|
|
237
|
+
item = transformer.file.call(ctx, item, path);
|
|
238
|
+
}
|
|
239
|
+
return item;
|
|
166
240
|
}
|
|
167
|
-
function build(ctx) {
|
|
241
|
+
function build(id, ctx) {
|
|
168
242
|
const folder = buildFolderNode("", true, ctx);
|
|
169
|
-
|
|
170
|
-
$id:
|
|
243
|
+
let root = {
|
|
244
|
+
$id: id,
|
|
171
245
|
name: folder.name,
|
|
172
246
|
children: folder.children
|
|
173
247
|
};
|
|
248
|
+
for (const transformer of ctx.transformers) {
|
|
249
|
+
if (!transformer.root) continue;
|
|
250
|
+
root = transformer.root.call(ctx, root);
|
|
251
|
+
}
|
|
252
|
+
return root;
|
|
174
253
|
}
|
|
175
254
|
function createPageTreeBuilder(getUrl) {
|
|
255
|
+
function getTransformers(options, generateFallback) {
|
|
256
|
+
const transformers = [legacyTransformer(options)];
|
|
257
|
+
if (options.transformers) {
|
|
258
|
+
transformers.push(...options.transformers);
|
|
259
|
+
}
|
|
260
|
+
if (generateFallback) {
|
|
261
|
+
transformers.push(transformerFallback());
|
|
262
|
+
}
|
|
263
|
+
return transformers;
|
|
264
|
+
}
|
|
176
265
|
function createFlattenPathResolver(storage) {
|
|
177
266
|
const map = /* @__PURE__ */ new Map();
|
|
178
267
|
const files = storage.getFiles();
|
|
@@ -186,36 +275,34 @@ function createPageTreeBuilder(getUrl) {
|
|
|
186
275
|
};
|
|
187
276
|
}
|
|
188
277
|
return {
|
|
189
|
-
build(options) {
|
|
190
|
-
const
|
|
191
|
-
return
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
resolveName(name, format) {
|
|
197
|
-
return resolve(name, format) ?? name;
|
|
198
|
-
}
|
|
199
|
-
});
|
|
278
|
+
build({ storage, id, ...options }) {
|
|
279
|
+
const key = "";
|
|
280
|
+
return this.buildI18n({
|
|
281
|
+
id,
|
|
282
|
+
storages: { [key]: storage },
|
|
283
|
+
...options
|
|
284
|
+
})[key];
|
|
200
285
|
},
|
|
201
|
-
buildI18n({
|
|
202
|
-
const
|
|
203
|
-
const
|
|
204
|
-
const
|
|
205
|
-
const
|
|
286
|
+
buildI18n({ id, storages, generateFallback = true, ...options }) {
|
|
287
|
+
const transformers = getTransformers(options, generateFallback);
|
|
288
|
+
const out = {};
|
|
289
|
+
for (const [locale, storage] of Object.entries(storages)) {
|
|
290
|
+
const resolve = createFlattenPathResolver(storage);
|
|
291
|
+
const branch = locale.length === 0 ? "root" : locale;
|
|
292
|
+
out[locale] = build(id ? `${id}-${branch}` : branch, {
|
|
293
|
+
transformers,
|
|
294
|
+
builder: this,
|
|
206
295
|
options,
|
|
207
296
|
getUrl,
|
|
208
|
-
|
|
209
|
-
locale: lang,
|
|
297
|
+
locale,
|
|
210
298
|
storage,
|
|
211
|
-
|
|
299
|
+
storages,
|
|
212
300
|
resolveName(name, format) {
|
|
213
301
|
return resolve(name, format) ?? name;
|
|
214
302
|
}
|
|
215
303
|
});
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
return Object.fromEntries(entries);
|
|
304
|
+
}
|
|
305
|
+
return out;
|
|
219
306
|
}
|
|
220
307
|
};
|
|
221
308
|
}
|
|
@@ -231,10 +318,19 @@ function pathToName(name) {
|
|
|
231
318
|
|
|
232
319
|
// src/source/file-system.ts
|
|
233
320
|
var FileSystem = class {
|
|
234
|
-
constructor() {
|
|
321
|
+
constructor(inherit) {
|
|
235
322
|
this.files = /* @__PURE__ */ new Map();
|
|
236
323
|
this.folders = /* @__PURE__ */ new Map();
|
|
237
|
-
|
|
324
|
+
if (inherit) {
|
|
325
|
+
for (const [k, v] of inherit.folders) {
|
|
326
|
+
this.folders.set(k, v);
|
|
327
|
+
}
|
|
328
|
+
for (const [k, v] of inherit.files) {
|
|
329
|
+
this.files.set(k, v);
|
|
330
|
+
}
|
|
331
|
+
} else {
|
|
332
|
+
this.folders.set("", []);
|
|
333
|
+
}
|
|
238
334
|
}
|
|
239
335
|
read(path) {
|
|
240
336
|
return this.files.get(path);
|
|
@@ -246,11 +342,21 @@ var FileSystem = class {
|
|
|
246
342
|
return this.folders.get(path);
|
|
247
343
|
}
|
|
248
344
|
write(path, file) {
|
|
345
|
+
if (this.files.has(path)) {
|
|
346
|
+
this.files.set(path, file);
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
249
349
|
const dir = dirname(path);
|
|
250
350
|
this.makeDir(dir);
|
|
251
351
|
this.readDir(dir)?.push(path);
|
|
252
352
|
this.files.set(path, file);
|
|
253
353
|
}
|
|
354
|
+
delete(path) {
|
|
355
|
+
return this.files.delete(path);
|
|
356
|
+
}
|
|
357
|
+
deleteDir(path) {
|
|
358
|
+
return this.folders.delete(path);
|
|
359
|
+
}
|
|
254
360
|
getFiles() {
|
|
255
361
|
return Array.from(this.files.keys());
|
|
256
362
|
}
|
|
@@ -266,61 +372,63 @@ var FileSystem = class {
|
|
|
266
372
|
};
|
|
267
373
|
|
|
268
374
|
// src/source/load-files.ts
|
|
269
|
-
function
|
|
270
|
-
|
|
271
|
-
const storage = new FileSystem();
|
|
272
|
-
const normalized = files.map((file) => ({
|
|
273
|
-
...file,
|
|
274
|
-
path: normalizePath(file.path)
|
|
275
|
-
}));
|
|
276
|
-
for (const item of options.buildFiles(normalized)) {
|
|
277
|
-
storage.write(item.path, item);
|
|
278
|
-
}
|
|
279
|
-
for (const transformer of transformers) {
|
|
280
|
-
transformer({
|
|
281
|
-
storage,
|
|
282
|
-
options
|
|
283
|
-
});
|
|
284
|
-
}
|
|
285
|
-
return storage;
|
|
286
|
-
}
|
|
287
|
-
function loadFilesI18n(files, options, i18n) {
|
|
288
|
-
const parser = i18n.parser === "dir" ? dirParser : dotParser;
|
|
289
|
-
const storages = {};
|
|
290
|
-
for (const lang of i18n.languages) {
|
|
291
|
-
storages[lang] = loadFiles(
|
|
292
|
-
files.flatMap((file) => {
|
|
293
|
-
const [path, locale] = parser(normalizePath(file.path));
|
|
294
|
-
if ((locale ?? i18n.defaultLanguage) === lang) {
|
|
295
|
-
return {
|
|
296
|
-
...file,
|
|
297
|
-
path
|
|
298
|
-
};
|
|
299
|
-
}
|
|
300
|
-
return [];
|
|
301
|
-
}),
|
|
302
|
-
options
|
|
303
|
-
);
|
|
304
|
-
}
|
|
305
|
-
return storages;
|
|
375
|
+
function isLocaleValid(locale) {
|
|
376
|
+
return locale.length > 0 && !/\d+/.test(locale);
|
|
306
377
|
}
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
}
|
|
312
|
-
function dotParser(path) {
|
|
313
|
-
const segs = path.split("/");
|
|
314
|
-
if (segs.length === 0) return [path];
|
|
315
|
-
const name = segs[segs.length - 1].split(".");
|
|
316
|
-
if (name.length >= 3) {
|
|
317
|
-
const locale = name.splice(name.length - 2, 1)[0];
|
|
318
|
-
if (locale.length > 0 && !/\d+/.test(locale)) {
|
|
319
|
-
segs[segs.length - 1] = name.join(".");
|
|
378
|
+
var parsers = {
|
|
379
|
+
dir(path) {
|
|
380
|
+
const [locale, ...segs] = path.split("/");
|
|
381
|
+
if (locale && segs.length > 0 && isLocaleValid(locale))
|
|
320
382
|
return [segs.join("/"), locale];
|
|
383
|
+
return [path];
|
|
384
|
+
},
|
|
385
|
+
dot(path) {
|
|
386
|
+
const dir = dirname(path);
|
|
387
|
+
const base = basename(path);
|
|
388
|
+
const parts = base.split(".");
|
|
389
|
+
if (parts.length < 3) return [path];
|
|
390
|
+
const [locale] = parts.splice(parts.length - 2, 1);
|
|
391
|
+
if (!isLocaleValid(locale)) return [path];
|
|
392
|
+
return [joinPath(dir, parts.join(".")), locale];
|
|
393
|
+
},
|
|
394
|
+
none(path) {
|
|
395
|
+
return [path];
|
|
396
|
+
}
|
|
397
|
+
};
|
|
398
|
+
function loadFiles(files, options, i18n) {
|
|
399
|
+
const { buildFile, transformers = [] } = options;
|
|
400
|
+
const parser = parsers[i18n.parser ?? "dot"];
|
|
401
|
+
const storages = {};
|
|
402
|
+
const normalized = files.map(
|
|
403
|
+
(file) => buildFile({
|
|
404
|
+
...file,
|
|
405
|
+
path: normalizePath(file.path)
|
|
406
|
+
})
|
|
407
|
+
);
|
|
408
|
+
const fallbackLang = i18n.fallbackLanguage !== null ? i18n.fallbackLanguage ?? i18n.defaultLanguage : null;
|
|
409
|
+
function scan(lang) {
|
|
410
|
+
if (storages[lang]) return;
|
|
411
|
+
let storage;
|
|
412
|
+
if (fallbackLang && fallbackLang !== lang) {
|
|
413
|
+
scan(fallbackLang);
|
|
414
|
+
storage = new FileSystem(storages[fallbackLang]);
|
|
415
|
+
} else {
|
|
416
|
+
storage = new FileSystem();
|
|
417
|
+
}
|
|
418
|
+
for (const item of normalized) {
|
|
419
|
+
const [path, locale = i18n.defaultLanguage] = parser(item.path);
|
|
420
|
+
if (locale === lang) storage.write(path, item);
|
|
421
|
+
}
|
|
422
|
+
for (const transformer of transformers) {
|
|
423
|
+
transformer({
|
|
424
|
+
storage,
|
|
425
|
+
options
|
|
426
|
+
});
|
|
321
427
|
}
|
|
428
|
+
storages[lang] = storage;
|
|
322
429
|
}
|
|
323
|
-
|
|
430
|
+
for (const lang of i18n.languages) scan(lang);
|
|
431
|
+
return storages;
|
|
324
432
|
}
|
|
325
433
|
function normalizePath(path) {
|
|
326
434
|
const segments = splitPath(slash(path));
|
|
@@ -330,7 +438,7 @@ function normalizePath(path) {
|
|
|
330
438
|
}
|
|
331
439
|
|
|
332
440
|
// src/source/loader.ts
|
|
333
|
-
function indexPages(storages, getUrl
|
|
441
|
+
function indexPages(storages, getUrl) {
|
|
334
442
|
const result = {
|
|
335
443
|
// (locale.slugs -> page)
|
|
336
444
|
pages: /* @__PURE__ */ new Map(),
|
|
@@ -339,36 +447,17 @@ function indexPages(storages, getUrl, i18n) {
|
|
|
339
447
|
// (locale.path -> meta)
|
|
340
448
|
pathToPage: /* @__PURE__ */ new Map()
|
|
341
449
|
};
|
|
342
|
-
const
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
);
|
|
350
|
-
}
|
|
351
|
-
if (item.format === "page") {
|
|
352
|
-
const page = fileToPage(item, getUrl, defaultLanguage);
|
|
353
|
-
result.pathToPage.set(`${defaultLanguage}.${item.path}`, page);
|
|
354
|
-
result.pages.set(`${defaultLanguage}.${page.slugs.join("/")}`, page);
|
|
355
|
-
if (!i18n) continue;
|
|
356
|
-
for (const lang of i18n.languages) {
|
|
357
|
-
if (lang === defaultLanguage) continue;
|
|
358
|
-
const localizedItem = storages[lang].read(filePath);
|
|
359
|
-
const localizedPage = fileToPage(
|
|
360
|
-
localizedItem?.format === "page" ? localizedItem : item,
|
|
361
|
-
getUrl,
|
|
362
|
-
lang
|
|
363
|
-
);
|
|
364
|
-
if (localizedItem) {
|
|
365
|
-
result.pathToPage.set(`${lang}.${item.path}`, localizedPage);
|
|
366
|
-
}
|
|
367
|
-
result.pages.set(
|
|
368
|
-
`${lang}.${localizedPage.slugs.join("/")}`,
|
|
369
|
-
localizedPage
|
|
370
|
-
);
|
|
450
|
+
for (const [lang, storage] of Object.entries(storages)) {
|
|
451
|
+
for (const filePath of storage.getFiles()) {
|
|
452
|
+
const item = storage.read(filePath);
|
|
453
|
+
const path = `${lang}.${filePath}`;
|
|
454
|
+
if (item.format === "meta") {
|
|
455
|
+
result.pathToMeta.set(path, fileToMeta(item));
|
|
456
|
+
continue;
|
|
371
457
|
}
|
|
458
|
+
const page = fileToPage(item, getUrl, lang);
|
|
459
|
+
result.pathToPage.set(path, page);
|
|
460
|
+
result.pages.set(`${lang}.${page.slugs.join("/")}`, page);
|
|
372
461
|
}
|
|
373
462
|
}
|
|
374
463
|
return result;
|
|
@@ -391,6 +480,17 @@ function createGetUrl(baseUrl, i18n) {
|
|
|
391
480
|
function loader(options) {
|
|
392
481
|
return createOutput(options);
|
|
393
482
|
}
|
|
483
|
+
function loadSource(source) {
|
|
484
|
+
const out = [];
|
|
485
|
+
for (const item of Array.isArray(source) ? source : [source]) {
|
|
486
|
+
if (typeof item.files === "function") {
|
|
487
|
+
out.push(...item.files());
|
|
488
|
+
} else {
|
|
489
|
+
out.push(...item.files);
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
return out;
|
|
493
|
+
}
|
|
394
494
|
function createOutput(options) {
|
|
395
495
|
if (!options.url && !options.baseUrl) {
|
|
396
496
|
console.warn("`loader()` now requires a `baseUrl` option to be defined.");
|
|
@@ -401,86 +501,82 @@ function createOutput(options) {
|
|
|
401
501
|
i18n,
|
|
402
502
|
slugs: slugsFn,
|
|
403
503
|
url: getUrl = createGetUrl(baseUrl ?? "/", i18n),
|
|
404
|
-
transformers
|
|
504
|
+
transformers = []
|
|
405
505
|
} = options;
|
|
406
506
|
const defaultLanguage = i18n?.defaultLanguage ?? "";
|
|
407
|
-
const files =
|
|
408
|
-
|
|
409
|
-
const indexFiles =
|
|
507
|
+
const files = loadSource(source);
|
|
508
|
+
const transformerSlugs = ({ storage }) => {
|
|
509
|
+
const indexFiles = /* @__PURE__ */ new Set();
|
|
410
510
|
const taken = /* @__PURE__ */ new Set();
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
511
|
+
const autoIndex = slugsFn === void 0;
|
|
512
|
+
for (const path of storage.getFiles()) {
|
|
513
|
+
const file = storage.read(path);
|
|
514
|
+
if (!file || file.format !== "page" || file.slugs) continue;
|
|
515
|
+
if (isIndex(path) && autoIndex) {
|
|
516
|
+
indexFiles.add(path);
|
|
415
517
|
continue;
|
|
416
518
|
}
|
|
417
|
-
file.slugs = slugsFn ? slugsFn(parseFilePath(
|
|
519
|
+
file.slugs = slugsFn ? slugsFn(parseFilePath(path)) : getSlugs(path);
|
|
418
520
|
const key = file.slugs.join("/");
|
|
419
521
|
if (taken.has(key)) throw new Error("Duplicated slugs");
|
|
420
522
|
taken.add(key);
|
|
421
523
|
}
|
|
422
|
-
for (const
|
|
423
|
-
file
|
|
524
|
+
for (const path of indexFiles) {
|
|
525
|
+
const file = storage.read(path);
|
|
526
|
+
if (file?.format !== "page") continue;
|
|
527
|
+
file.slugs = getSlugs(path);
|
|
424
528
|
if (taken.has(file.slugs.join("/"))) file.slugs.push("index");
|
|
425
529
|
}
|
|
426
|
-
|
|
427
|
-
|
|
530
|
+
};
|
|
531
|
+
const storages = loadFiles(
|
|
532
|
+
files,
|
|
533
|
+
{
|
|
534
|
+
buildFile(file) {
|
|
535
|
+
if (file.type === "page") {
|
|
536
|
+
return {
|
|
537
|
+
format: "page",
|
|
538
|
+
path: file.path,
|
|
539
|
+
slugs: file.slugs,
|
|
540
|
+
data: file.data,
|
|
541
|
+
absolutePath: file.absolutePath ?? ""
|
|
542
|
+
};
|
|
543
|
+
}
|
|
428
544
|
return {
|
|
429
|
-
format: "
|
|
545
|
+
format: "meta",
|
|
430
546
|
path: file.path,
|
|
431
|
-
|
|
432
|
-
data: file.data
|
|
433
|
-
absolutePath: file.absolutePath ?? ""
|
|
547
|
+
absolutePath: file.absolutePath ?? "",
|
|
548
|
+
data: file.data
|
|
434
549
|
};
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
format: "meta",
|
|
438
|
-
path: file.path,
|
|
439
|
-
absolutePath: file.absolutePath ?? "",
|
|
440
|
-
data: file.data
|
|
441
|
-
};
|
|
442
|
-
});
|
|
443
|
-
}
|
|
444
|
-
const storages = i18n ? loadFilesI18n(
|
|
445
|
-
files,
|
|
446
|
-
{
|
|
447
|
-
buildFiles,
|
|
448
|
-
transformers
|
|
550
|
+
},
|
|
551
|
+
transformers: [transformerSlugs, ...transformers]
|
|
449
552
|
},
|
|
450
|
-
{
|
|
451
|
-
|
|
452
|
-
parser:
|
|
553
|
+
i18n ?? {
|
|
554
|
+
defaultLanguage,
|
|
555
|
+
parser: "none",
|
|
556
|
+
languages: [defaultLanguage]
|
|
453
557
|
}
|
|
454
|
-
)
|
|
455
|
-
|
|
456
|
-
transformers,
|
|
457
|
-
buildFiles
|
|
458
|
-
})
|
|
459
|
-
};
|
|
460
|
-
const walker = indexPages(storages, getUrl, i18n);
|
|
558
|
+
);
|
|
559
|
+
const walker = indexPages(storages, getUrl);
|
|
461
560
|
const builder = createPageTreeBuilder(getUrl);
|
|
462
561
|
let pageTree;
|
|
463
562
|
return {
|
|
464
563
|
_i18n: i18n,
|
|
465
564
|
get pageTree() {
|
|
565
|
+
pageTree ??= builder.buildI18n({
|
|
566
|
+
storages,
|
|
567
|
+
resolveIcon: options.icon,
|
|
568
|
+
...options.pageTree
|
|
569
|
+
});
|
|
570
|
+
return i18n ? pageTree : pageTree[defaultLanguage];
|
|
571
|
+
},
|
|
572
|
+
set pageTree(v) {
|
|
466
573
|
if (i18n) {
|
|
467
|
-
pageTree
|
|
468
|
-
storages,
|
|
469
|
-
resolveIcon: options.icon,
|
|
470
|
-
i18n,
|
|
471
|
-
...options.pageTree
|
|
472
|
-
});
|
|
574
|
+
pageTree = v;
|
|
473
575
|
} else {
|
|
474
|
-
pageTree
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
...options.pageTree
|
|
478
|
-
});
|
|
576
|
+
pageTree = {
|
|
577
|
+
defaultLanguage: v
|
|
578
|
+
};
|
|
479
579
|
}
|
|
480
|
-
return pageTree;
|
|
481
|
-
},
|
|
482
|
-
set pageTree(v) {
|
|
483
|
-
pageTree = v;
|
|
484
580
|
},
|
|
485
581
|
getPageByHref(href, { dir = "", language } = {}) {
|
|
486
582
|
const [value, hash] = href.split("#", 2);
|