fumadocs-core 15.6.12 → 15.7.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.
- 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 +5 -14
- 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 +80 -27
- package/dist/source/index.js +271 -185
- 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 = true) {
|
|
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,38 @@ function createPageTreeBuilder(getUrl) {
|
|
|
186
275
|
};
|
|
187
276
|
}
|
|
188
277
|
return {
|
|
189
|
-
build(options) {
|
|
190
|
-
const resolve = createFlattenPathResolver(
|
|
191
|
-
return build({
|
|
278
|
+
build({ storage, id, generateFallback, ...options }) {
|
|
279
|
+
const resolve = createFlattenPathResolver(storage);
|
|
280
|
+
return build(id ?? "root", {
|
|
281
|
+
transformers: getTransformers(options, generateFallback),
|
|
192
282
|
options,
|
|
193
283
|
builder: this,
|
|
194
|
-
storage
|
|
284
|
+
storage,
|
|
195
285
|
getUrl,
|
|
196
286
|
resolveName(name, format) {
|
|
197
287
|
return resolve(name, format) ?? name;
|
|
198
288
|
}
|
|
199
289
|
});
|
|
200
290
|
},
|
|
201
|
-
buildI18n({
|
|
202
|
-
const
|
|
203
|
-
const
|
|
204
|
-
const
|
|
205
|
-
const
|
|
291
|
+
buildI18n({ id, storages, ...options }) {
|
|
292
|
+
const transformers = getTransformers(options);
|
|
293
|
+
const out = {};
|
|
294
|
+
for (const [locale, storage] of Object.entries(storages)) {
|
|
295
|
+
const resolve = createFlattenPathResolver(storage);
|
|
296
|
+
out[locale] = build(id ?? (locale.length === 0 ? "root" : locale), {
|
|
297
|
+
transformers,
|
|
298
|
+
builder: this,
|
|
206
299
|
options,
|
|
207
300
|
getUrl,
|
|
208
|
-
|
|
209
|
-
locale: lang,
|
|
301
|
+
locale,
|
|
210
302
|
storage,
|
|
211
|
-
|
|
303
|
+
storages,
|
|
212
304
|
resolveName(name, format) {
|
|
213
305
|
return resolve(name, format) ?? name;
|
|
214
306
|
}
|
|
215
307
|
});
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
return Object.fromEntries(entries);
|
|
308
|
+
}
|
|
309
|
+
return out;
|
|
219
310
|
}
|
|
220
311
|
};
|
|
221
312
|
}
|
|
@@ -231,10 +322,19 @@ function pathToName(name) {
|
|
|
231
322
|
|
|
232
323
|
// src/source/file-system.ts
|
|
233
324
|
var FileSystem = class {
|
|
234
|
-
constructor() {
|
|
325
|
+
constructor(inherit) {
|
|
235
326
|
this.files = /* @__PURE__ */ new Map();
|
|
236
327
|
this.folders = /* @__PURE__ */ new Map();
|
|
237
|
-
|
|
328
|
+
if (inherit) {
|
|
329
|
+
for (const [k, v] of inherit.folders) {
|
|
330
|
+
this.folders.set(k, v);
|
|
331
|
+
}
|
|
332
|
+
for (const [k, v] of inherit.files) {
|
|
333
|
+
this.files.set(k, v);
|
|
334
|
+
}
|
|
335
|
+
} else {
|
|
336
|
+
this.folders.set("", []);
|
|
337
|
+
}
|
|
238
338
|
}
|
|
239
339
|
read(path) {
|
|
240
340
|
return this.files.get(path);
|
|
@@ -246,11 +346,21 @@ var FileSystem = class {
|
|
|
246
346
|
return this.folders.get(path);
|
|
247
347
|
}
|
|
248
348
|
write(path, file) {
|
|
349
|
+
if (this.files.has(path)) {
|
|
350
|
+
this.files.set(path, file);
|
|
351
|
+
return;
|
|
352
|
+
}
|
|
249
353
|
const dir = dirname(path);
|
|
250
354
|
this.makeDir(dir);
|
|
251
355
|
this.readDir(dir)?.push(path);
|
|
252
356
|
this.files.set(path, file);
|
|
253
357
|
}
|
|
358
|
+
delete(path) {
|
|
359
|
+
return this.files.delete(path);
|
|
360
|
+
}
|
|
361
|
+
deleteDir(path) {
|
|
362
|
+
return this.folders.delete(path);
|
|
363
|
+
}
|
|
254
364
|
getFiles() {
|
|
255
365
|
return Array.from(this.files.keys());
|
|
256
366
|
}
|
|
@@ -266,62 +376,59 @@ var FileSystem = class {
|
|
|
266
376
|
};
|
|
267
377
|
|
|
268
378
|
// 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;
|
|
379
|
+
function isLocaleValid(locale) {
|
|
380
|
+
return locale.length > 0 && !/\d+/.test(locale);
|
|
286
381
|
}
|
|
287
|
-
|
|
288
|
-
|
|
382
|
+
var parsers = {
|
|
383
|
+
dir(path) {
|
|
384
|
+
const [locale, ...segs] = path.split("/");
|
|
385
|
+
if (locale && segs.length > 0 && isLocaleValid(locale))
|
|
386
|
+
return [segs.join("/"), locale];
|
|
387
|
+
return [path];
|
|
388
|
+
},
|
|
389
|
+
dot(path) {
|
|
390
|
+
const dir = dirname(path);
|
|
391
|
+
const base = basename(path);
|
|
392
|
+
const parts = base.split(".");
|
|
393
|
+
if (parts.length < 3) return [path];
|
|
394
|
+
const [locale] = parts.splice(parts.length - 2, 1);
|
|
395
|
+
if (!isLocaleValid(locale)) return [path];
|
|
396
|
+
return [joinPath(dir, parts.join(".")), locale];
|
|
397
|
+
},
|
|
398
|
+
none(path) {
|
|
399
|
+
return [path];
|
|
400
|
+
}
|
|
401
|
+
};
|
|
402
|
+
function loadFiles(files, options, i18n) {
|
|
403
|
+
const { buildFile, transformers = [] } = options;
|
|
404
|
+
const parser = parsers[i18n.parser];
|
|
289
405
|
const storages = {};
|
|
406
|
+
const normalized = files.map(
|
|
407
|
+
(file) => buildFile({
|
|
408
|
+
...file,
|
|
409
|
+
path: normalizePath(file.path)
|
|
410
|
+
})
|
|
411
|
+
);
|
|
412
|
+
function scan(lang, fallback) {
|
|
413
|
+
const storage = new FileSystem(fallback);
|
|
414
|
+
for (const item of normalized) {
|
|
415
|
+
const [path, locale = i18n.defaultLanguage] = parser(item.path);
|
|
416
|
+
if (locale === lang) storage.write(path, item);
|
|
417
|
+
}
|
|
418
|
+
for (const transformer of transformers) {
|
|
419
|
+
transformer({
|
|
420
|
+
storage,
|
|
421
|
+
options
|
|
422
|
+
});
|
|
423
|
+
}
|
|
424
|
+
return storage;
|
|
425
|
+
}
|
|
426
|
+
storages[i18n.defaultLanguage] = scan(i18n.defaultLanguage);
|
|
290
427
|
for (const lang of i18n.languages) {
|
|
291
|
-
storages[lang]
|
|
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
|
-
);
|
|
428
|
+
storages[lang] ??= scan(lang, storages[i18n.defaultLanguage]);
|
|
304
429
|
}
|
|
305
430
|
return storages;
|
|
306
431
|
}
|
|
307
|
-
function dirParser(path) {
|
|
308
|
-
const parsed = path.split("/");
|
|
309
|
-
if (parsed.length >= 2) return [parsed.slice(1).join("/"), parsed[0]];
|
|
310
|
-
return [path];
|
|
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(".");
|
|
320
|
-
return [segs.join("/"), locale];
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
return [path];
|
|
324
|
-
}
|
|
325
432
|
function normalizePath(path) {
|
|
326
433
|
const segments = splitPath(slash(path));
|
|
327
434
|
if (segments[0] === "." || segments[0] === "..")
|
|
@@ -330,7 +437,7 @@ function normalizePath(path) {
|
|
|
330
437
|
}
|
|
331
438
|
|
|
332
439
|
// src/source/loader.ts
|
|
333
|
-
function indexPages(storages, getUrl
|
|
440
|
+
function indexPages(storages, getUrl) {
|
|
334
441
|
const result = {
|
|
335
442
|
// (locale.slugs -> page)
|
|
336
443
|
pages: /* @__PURE__ */ new Map(),
|
|
@@ -339,36 +446,17 @@ function indexPages(storages, getUrl, i18n) {
|
|
|
339
446
|
// (locale.path -> meta)
|
|
340
447
|
pathToPage: /* @__PURE__ */ new Map()
|
|
341
448
|
};
|
|
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
|
-
);
|
|
449
|
+
for (const [lang, storage] of Object.entries(storages)) {
|
|
450
|
+
for (const filePath of storage.getFiles()) {
|
|
451
|
+
const item = storage.read(filePath);
|
|
452
|
+
const path = `${lang}.${filePath}`;
|
|
453
|
+
if (item.format === "meta") {
|
|
454
|
+
result.pathToMeta.set(path, fileToMeta(item));
|
|
455
|
+
continue;
|
|
371
456
|
}
|
|
457
|
+
const page = fileToPage(item, getUrl, lang);
|
|
458
|
+
result.pathToPage.set(path, page);
|
|
459
|
+
result.pages.set(`${lang}.${page.slugs.join("/")}`, page);
|
|
372
460
|
}
|
|
373
461
|
}
|
|
374
462
|
return result;
|
|
@@ -401,86 +489,84 @@ function createOutput(options) {
|
|
|
401
489
|
i18n,
|
|
402
490
|
slugs: slugsFn,
|
|
403
491
|
url: getUrl = createGetUrl(baseUrl ?? "/", i18n),
|
|
404
|
-
transformers
|
|
492
|
+
transformers = []
|
|
405
493
|
} = options;
|
|
406
494
|
const defaultLanguage = i18n?.defaultLanguage ?? "";
|
|
407
495
|
const files = typeof source.files === "function" ? source.files() : source.files;
|
|
408
|
-
|
|
409
|
-
const indexFiles =
|
|
496
|
+
const transformerSlugs = ({ storage }) => {
|
|
497
|
+
const indexFiles = /* @__PURE__ */ new Set();
|
|
410
498
|
const taken = /* @__PURE__ */ new Set();
|
|
411
|
-
for (const
|
|
412
|
-
|
|
413
|
-
if (
|
|
414
|
-
|
|
499
|
+
for (const path of storage.getFiles()) {
|
|
500
|
+
const file = storage.read(path);
|
|
501
|
+
if (!file || file.format !== "page" || file.slugs) continue;
|
|
502
|
+
if (isIndex(path) && !slugsFn) {
|
|
503
|
+
indexFiles.add(path);
|
|
415
504
|
continue;
|
|
416
505
|
}
|
|
417
|
-
file.slugs = slugsFn ? slugsFn(parseFilePath(
|
|
506
|
+
file.slugs = slugsFn ? slugsFn(parseFilePath(path)) : getSlugs(path);
|
|
418
507
|
const key = file.slugs.join("/");
|
|
419
508
|
if (taken.has(key)) throw new Error("Duplicated slugs");
|
|
420
509
|
taken.add(key);
|
|
421
510
|
}
|
|
422
|
-
for (const
|
|
423
|
-
file
|
|
511
|
+
for (const path of indexFiles) {
|
|
512
|
+
const file = storage.read(path);
|
|
513
|
+
if (file?.format !== "page") continue;
|
|
514
|
+
file.slugs = getSlugs(path);
|
|
424
515
|
if (taken.has(file.slugs.join("/"))) file.slugs.push("index");
|
|
425
516
|
}
|
|
426
|
-
|
|
427
|
-
|
|
517
|
+
};
|
|
518
|
+
const storages = loadFiles(
|
|
519
|
+
files,
|
|
520
|
+
{
|
|
521
|
+
buildFile(file) {
|
|
522
|
+
if (file.type === "page") {
|
|
523
|
+
return {
|
|
524
|
+
format: "page",
|
|
525
|
+
path: file.path,
|
|
526
|
+
slugs: file.slugs,
|
|
527
|
+
data: file.data,
|
|
528
|
+
absolutePath: file.absolutePath ?? ""
|
|
529
|
+
};
|
|
530
|
+
}
|
|
428
531
|
return {
|
|
429
|
-
format: "
|
|
532
|
+
format: "meta",
|
|
430
533
|
path: file.path,
|
|
431
|
-
|
|
432
|
-
data: file.data
|
|
433
|
-
absolutePath: file.absolutePath ?? ""
|
|
534
|
+
absolutePath: file.absolutePath ?? "",
|
|
535
|
+
data: file.data
|
|
434
536
|
};
|
|
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
|
|
537
|
+
},
|
|
538
|
+
transformers: [transformerSlugs, ...transformers]
|
|
449
539
|
},
|
|
450
|
-
{
|
|
540
|
+
i18n ? {
|
|
451
541
|
...i18n,
|
|
452
542
|
parser: i18n.parser ?? "dot"
|
|
543
|
+
} : {
|
|
544
|
+
defaultLanguage,
|
|
545
|
+
parser: "none",
|
|
546
|
+
languages: [defaultLanguage]
|
|
453
547
|
}
|
|
454
|
-
)
|
|
455
|
-
|
|
456
|
-
transformers,
|
|
457
|
-
buildFiles
|
|
458
|
-
})
|
|
459
|
-
};
|
|
460
|
-
const walker = indexPages(storages, getUrl, i18n);
|
|
548
|
+
);
|
|
549
|
+
const walker = indexPages(storages, getUrl);
|
|
461
550
|
const builder = createPageTreeBuilder(getUrl);
|
|
462
551
|
let pageTree;
|
|
463
552
|
return {
|
|
464
553
|
_i18n: i18n,
|
|
465
554
|
get pageTree() {
|
|
555
|
+
pageTree ??= builder.buildI18n({
|
|
556
|
+
storages,
|
|
557
|
+
resolveIcon: options.icon,
|
|
558
|
+
...options.pageTree
|
|
559
|
+
});
|
|
560
|
+
return i18n ? pageTree : pageTree[defaultLanguage];
|
|
561
|
+
},
|
|
562
|
+
set pageTree(v) {
|
|
466
563
|
if (i18n) {
|
|
467
|
-
pageTree
|
|
468
|
-
storages,
|
|
469
|
-
resolveIcon: options.icon,
|
|
470
|
-
i18n,
|
|
471
|
-
...options.pageTree
|
|
472
|
-
});
|
|
564
|
+
pageTree = v;
|
|
473
565
|
} else {
|
|
474
|
-
pageTree
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
...options.pageTree
|
|
478
|
-
});
|
|
566
|
+
pageTree = {
|
|
567
|
+
defaultLanguage: v
|
|
568
|
+
};
|
|
479
569
|
}
|
|
480
|
-
return pageTree;
|
|
481
|
-
},
|
|
482
|
-
set pageTree(v) {
|
|
483
|
-
pageTree = v;
|
|
484
570
|
},
|
|
485
571
|
getPageByHref(href, { dir = "", language } = {}) {
|
|
486
572
|
const [value, hash] = href.split("#", 2);
|