@lonik/prestige 0.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.
Files changed (50) hide show
  1. package/README.md +29 -0
  2. package/dist/README.md +29 -0
  3. package/dist/client.d.ts +101 -0
  4. package/dist/content.types-BbDmygmP.d.ts +44 -0
  5. package/dist/index.d.ts +5 -0
  6. package/dist/index.js +6 -0
  7. package/dist/index.js.map +1 -0
  8. package/dist/ui.d.ts +124 -0
  9. package/dist/ui.js +675 -0
  10. package/dist/ui.js.map +1 -0
  11. package/dist/vite.d.ts +47 -0
  12. package/dist/vite.js +685 -0
  13. package/dist/vite.js.map +1 -0
  14. package/package.json +131 -0
  15. package/src/themes/core.css +54 -0
  16. package/src/themes/default-gray.css +44 -0
  17. package/src/themes/default-mauve.css +44 -0
  18. package/src/themes/default-mist.css +44 -0
  19. package/src/themes/default-neutral.css +44 -0
  20. package/src/themes/default-olive.css +44 -0
  21. package/src/themes/default-slate.css +44 -0
  22. package/src/themes/default-stone.css +44 -0
  23. package/src/themes/default-taupe.css +44 -0
  24. package/src/themes/default-zinc.css +44 -0
  25. package/src/themes/primary-amber.css +42 -0
  26. package/src/themes/primary-blue.css +42 -0
  27. package/src/themes/primary-cyan.css +42 -0
  28. package/src/themes/primary-emerald.css +42 -0
  29. package/src/themes/primary-fuchsia.css +42 -0
  30. package/src/themes/primary-gray.css +42 -0
  31. package/src/themes/primary-green.css +42 -0
  32. package/src/themes/primary-indigo.css +42 -0
  33. package/src/themes/primary-lime.css +42 -0
  34. package/src/themes/primary-mauve.css +42 -0
  35. package/src/themes/primary-mist.css +42 -0
  36. package/src/themes/primary-neutral.css +42 -0
  37. package/src/themes/primary-olive.css +42 -0
  38. package/src/themes/primary-orange.css +42 -0
  39. package/src/themes/primary-pink.css +42 -0
  40. package/src/themes/primary-purple.css +42 -0
  41. package/src/themes/primary-red.css +42 -0
  42. package/src/themes/primary-rose.css +42 -0
  43. package/src/themes/primary-sky.css +42 -0
  44. package/src/themes/primary-slate.css +42 -0
  45. package/src/themes/primary-stone.css +42 -0
  46. package/src/themes/primary-taupe.css +42 -0
  47. package/src/themes/primary-teal.css +42 -0
  48. package/src/themes/primary-violet.css +42 -0
  49. package/src/themes/primary-yellow.css +42 -0
  50. package/src/themes/primary-zinc.css +42 -0
package/dist/vite.js ADDED
@@ -0,0 +1,685 @@
1
+ import { join, parse, relative } from "pathe";
2
+ import picomatch from "picomatch";
3
+ import { z } from "zod";
4
+ import { mkdir, readFile, readdir, stat, unlink, writeFile } from "node:fs/promises";
5
+ import { genArrayFromRaw, genObjectFromValues } from "knitwork";
6
+ import { compile } from "@mdx-js/mdx";
7
+ import rehypeShiki from "@shikijs/rehype";
8
+ import rehypeSlug from "rehype-slug";
9
+ import remarkFlexibleToc from "remark-flexible-toc";
10
+ import remarkFrontmatter from "remark-frontmatter";
11
+ import remarkGfm from "remark-gfm";
12
+ import remarkDirective from "remark-directive";
13
+ import { matter } from "vfile-matter";
14
+ import { visit } from "unist-util-visit";
15
+ import { h } from "hastscript";
16
+ import { basename, join as join$1 } from "node:path";
17
+ import { createLogger } from "vite";
18
+ import { pathToFileURL } from "node:url";
19
+ import { glob } from "tinyglobby";
20
+ import { read } from "to-vfile";
21
+
22
+ //#region src/vite/utils/errors.ts
23
+ var PrestigeError = class extends Error {};
24
+ /**
25
+ * Parse data with zod schema and if fails throw PrestigeError that is friendly error
26
+ * for prestige ecosystem
27
+ */
28
+ function parseWithFriendlyErrors(s, input, message) {
29
+ try {
30
+ return s.parse(input);
31
+ } catch (e) {
32
+ if (e instanceof Error) throw new PrestigeError(`Prestige error cause: ${message}, with error: ${e.message} `);
33
+ else throw new PrestigeError(`Prestige error cause: ${message} `);
34
+ }
35
+ }
36
+
37
+ //#endregion
38
+ //#region src/vite/core/content/content.types.ts
39
+ const ContentFrontmatterSchema = z.object({
40
+ title: z.string().describe("The title of the article"),
41
+ description: z.string().optional().describe("The description of the article"),
42
+ label: z.string().optional().describe("The label of the content")
43
+ });
44
+ const ContentSchema = z.object({
45
+ matter: ContentFrontmatterSchema,
46
+ html: z.string().describe("The html of the content")
47
+ });
48
+ const InternalCollectionLinkSchema = z.union([z.object({
49
+ label: z.string(),
50
+ slug: z.string()
51
+ }), z.string()]);
52
+ const ExternalCollectionLinkSchema = z.object({
53
+ label: z.string(),
54
+ link: z.string()
55
+ });
56
+ const CollectionGroupSchema = z.object({
57
+ label: z.string(),
58
+ items: z.lazy(() => z.array(CollectionItemSchema)).optional(),
59
+ collapsible: z.boolean().optional(),
60
+ autogenerate: z.object({ directory: z.string() }).optional()
61
+ });
62
+ const CollectionItemSchema = z.union([
63
+ ExternalCollectionLinkSchema,
64
+ InternalCollectionLinkSchema,
65
+ z.lazy(() => CollectionGroupSchema)
66
+ ]);
67
+ const CollectionSchema = z.object({
68
+ id: z.string().min(1, { message: "Folder name cannot be empty" }).max(50, { message: "Folder name too long" }).regex(/^[a-zA-Z0-9-_]+$/, { message: "Only alphanumeric, hyphens, and underscores allowed" }).describe("The id of the collection, must match the folder name"),
69
+ items: z.array(CollectionItemSchema),
70
+ label: z.string().optional().describe("The label of the collection"),
71
+ defaultLink: z.string().optional().describe("The default link of the collection")
72
+ });
73
+ const CollectionsSchema = z.array(CollectionSchema);
74
+
75
+ //#endregion
76
+ //#region src/vite/config/config.types.ts
77
+ const PrestigeConfigSchema = z.object({
78
+ title: z.string().describe("Title of the website"),
79
+ github: z.string().optional().describe("Github repo"),
80
+ algolia: z.object({
81
+ appId: z.string().describe("Algolia app id"),
82
+ apiKey: z.string().describe("Algolia api key"),
83
+ indices: z.array(z.string()).describe("Algolia indices")
84
+ }).optional().describe("Algolia options"),
85
+ license: z.object({
86
+ label: z.string().describe("License label"),
87
+ url: z.string().describe("License url")
88
+ }).optional().describe("License options"),
89
+ collections: CollectionsSchema,
90
+ markdown: z.object({
91
+ shikiOptions: z.custom().optional().describe("Options for Shiki syntax highlighting"),
92
+ gfmOptions: z.custom().optional().describe("Options for remark-gfm"),
93
+ rehypePlugins: z.custom().optional().describe("Additional rehype plugins"),
94
+ remarkPlugins: z.custom().optional().describe("Additional remark plugins"),
95
+ remarkFlexibleToc: z.custom().optional().describe("Options for remark-flexible-toc"),
96
+ rehypeSlug: z.custom().optional().describe("Options for rehype-slug")
97
+ }).optional().describe("Markdown options, configure how markdown is parsed")
98
+ });
99
+
100
+ //#endregion
101
+ //#region src/vite/utils/file-utils.ts
102
+ async function pathExists(path) {
103
+ try {
104
+ await stat(path);
105
+ return true;
106
+ } catch {
107
+ return false;
108
+ }
109
+ }
110
+ function extractVirtualId(fullId, virtualPrefix) {
111
+ const startIndex = fullId.indexOf(virtualPrefix);
112
+ if (startIndex !== -1) return "\0" + fullId.slice(startIndex);
113
+ return null;
114
+ }
115
+
116
+ //#endregion
117
+ //#region src/vite/config/config.ts
118
+ function validateConfig(config) {
119
+ return parseWithFriendlyErrors(PrestigeConfigSchema, config, "Invalid schema");
120
+ }
121
+ async function resolvePrestigeConfig(configInput, root) {
122
+ if (!configInput) throw new PrestigeError("Prestige config is required");
123
+ const validatedConfig = validateConfig(configInput);
124
+ const docsDirPath = join(root, "src/content");
125
+ if (!await pathExists(docsDirPath)) throw new PrestigeError(`Docs! directory not found: ${docsDirPath}`);
126
+ return {
127
+ config: validatedConfig,
128
+ fullDocsDir: docsDirPath
129
+ };
130
+ }
131
+
132
+ //#endregion
133
+ //#region src/vite/content/content-compiler.ts
134
+ function remarkAdmonitions() {
135
+ return (tree) => {
136
+ visit(tree, (node) => {
137
+ if (node.type === "textDirective" || node.type === "leafDirective" || node.type === "containerDirective") {
138
+ if (node.type !== "containerDirective") {
139
+ const data$1 = node.data || (node.data = {});
140
+ const hast = h(node.type === "textDirective" ? "span" : "aside", {
141
+ className: ["admonition", `admonition-${node.name}`],
142
+ ...node.attributes
143
+ });
144
+ data$1.hName = hast.tagName;
145
+ data$1.hProperties = hast.properties;
146
+ return;
147
+ }
148
+ const type = [
149
+ "note",
150
+ "tip",
151
+ "caution",
152
+ "danger"
153
+ ].includes(node.name) ? node.name : "note";
154
+ const typeMap = {
155
+ note: "bg-blue-50/50 dark:bg-blue-900/20 border-blue-500 text-blue-900 dark:text-blue-200",
156
+ tip: "bg-purple-50/50 dark:bg-purple-900/20 border-purple-500 text-purple-900 dark:text-purple-200",
157
+ caution: "bg-yellow-50/50 dark:bg-yellow-900/20 border-yellow-500 text-yellow-900 dark:text-yellow-200",
158
+ danger: "bg-red-50/50 dark:bg-red-900/20 border-red-500 text-red-900 dark:text-red-200"
159
+ };
160
+ const data = node.data || (node.data = {});
161
+ data.hName = "aside";
162
+ data.hProperties = {
163
+ "aria-label": type.charAt(0).toUpperCase() + type.slice(1),
164
+ className: [
165
+ "relative",
166
+ "my-6",
167
+ "px-4",
168
+ "py-3",
169
+ "border-l-4",
170
+ "rounded-lg",
171
+ ...(typeMap[type] || typeMap["note"]).split(" ")
172
+ ],
173
+ ...node.attributes
174
+ };
175
+ let titleNodeIndex = node.children.findIndex((c) => c.data?.directiveLabel);
176
+ let titleChildren;
177
+ if (titleNodeIndex !== -1) {
178
+ titleChildren = node.children[titleNodeIndex].children;
179
+ node.children.splice(titleNodeIndex, 1);
180
+ } else titleChildren = [{
181
+ type: "text",
182
+ value: type.charAt(0).toUpperCase() + type.slice(1)
183
+ }];
184
+ const getIconHast = (t) => {
185
+ const props = {
186
+ xmlns: "http://www.w3.org/2000/svg",
187
+ width: "24",
188
+ height: "24",
189
+ viewBox: "0 0 24 24",
190
+ fill: "none",
191
+ stroke: "currentColor",
192
+ strokeWidth: "2",
193
+ strokeLinecap: "round",
194
+ strokeLinejoin: "round",
195
+ className: [
196
+ "w-5",
197
+ "h-5",
198
+ "flex-shrink-0"
199
+ ]
200
+ };
201
+ if (t === "note") return h("svg", props, [
202
+ h("circle", {
203
+ cx: "12",
204
+ cy: "12",
205
+ r: "10"
206
+ }),
207
+ h("path", { d: "M12 16v-4" }),
208
+ h("path", { d: "M12 8h.01" })
209
+ ]);
210
+ if (t === "tip") return h("svg", props, [
211
+ h("path", { d: "M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91-.09z" }),
212
+ h("path", { d: "m12 15-3-3a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22.35 22.35 0 0 1-4 2z" }),
213
+ h("path", { d: "M9 12H4s.55-3.03 2-4c1.62-1.08 5 0 5 0" }),
214
+ h("path", { d: "M12 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5" })
215
+ ]);
216
+ if (t === "caution") return h("svg", props, [
217
+ h("path", { d: "m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3Z" }),
218
+ h("path", { d: "M12 9v4" }),
219
+ h("path", { d: "M12 17h.01" })
220
+ ]);
221
+ if (t === "danger") return h("svg", props, [
222
+ h("polygon", { points: "7.86 2 16.14 2 22 7.86 22 16.14 16.14 22 7.86 22 2 16.14 2 7.86 7.86 2" }),
223
+ h("path", { d: "M12 8v4" }),
224
+ h("path", { d: "M12 16h.01" })
225
+ ]);
226
+ return null;
227
+ };
228
+ node.children = [{
229
+ type: "paragraph",
230
+ data: {
231
+ hName: "p",
232
+ hProperties: { className: [
233
+ "flex",
234
+ "items-center",
235
+ "gap-2",
236
+ "mb-2",
237
+ "mt-0",
238
+ "font-bold",
239
+ "text-lg"
240
+ ] }
241
+ },
242
+ children: [{
243
+ type: "text",
244
+ value: "",
245
+ data: {
246
+ hName: "span",
247
+ hChildren: [getIconHast(type)]
248
+ }
249
+ }, ...titleChildren]
250
+ }, {
251
+ type: "paragraph",
252
+ data: {
253
+ hName: "section",
254
+ hProperties: { className: [
255
+ "[&>p]:mt-0",
256
+ "[&>p]:mb-2",
257
+ "[&>p:last-child]:mb-0",
258
+ "text-sm"
259
+ ] }
260
+ },
261
+ children: node.children
262
+ }];
263
+ }
264
+ });
265
+ };
266
+ }
267
+ async function compileMarkdown(content, baseUrl, options) {
268
+ const toc = [];
269
+ const shikiOptions = {
270
+ themes: {
271
+ light: "github-light",
272
+ dark: "github-dark"
273
+ },
274
+ ...options?.shikiOptions
275
+ };
276
+ const code = await compile(content, {
277
+ outputFormat: "program",
278
+ rehypePlugins: [
279
+ ...options?.rehypePlugins ?? [],
280
+ [rehypeShiki, shikiOptions],
281
+ rehypeSlug
282
+ ],
283
+ remarkPlugins: [
284
+ ...options?.remarkPlugins ?? [],
285
+ remarkFrontmatter,
286
+ [remarkGfm, options?.gfmOptions || {}],
287
+ remarkDirective,
288
+ remarkAdmonitions,
289
+ [remarkFlexibleToc, { tocRef: toc }]
290
+ ],
291
+ baseUrl
292
+ });
293
+ return {
294
+ code: String(code),
295
+ toc
296
+ };
297
+ }
298
+ async function compileFrontmatter(vFile) {
299
+ matter(vFile, { strip: true });
300
+ return vFile.data["matter"] || {};
301
+ }
302
+ function warmupCompiler(options) {
303
+ compileMarkdown("```js\n```", "http://localhost", options).catch(() => {});
304
+ }
305
+
306
+ //#endregion
307
+ //#region src/vite/content/content-links.ts
308
+ function resolveContentInternalLinks(sidebars) {
309
+ const links = /* @__PURE__ */ new Map();
310
+ for (const [key, sidebar] of sidebars) {
311
+ const sidebarLinks = [];
312
+ for (const item of sidebar.items) processItem$1(item, sidebarLinks);
313
+ links.set(key, sidebarLinks);
314
+ }
315
+ return links;
316
+ }
317
+ function processItem$1(item, links = []) {
318
+ if ("slug" in item) links.push(item);
319
+ else if ("items" in item) for (const childItem of item.items) processItem$1(childItem, links);
320
+ return links;
321
+ }
322
+
323
+ //#endregion
324
+ //#region src/vite/utils/logger.ts
325
+ const logger = createLogger(void 0, { prefix: "[Prestige]" });
326
+ var logger_default = logger;
327
+
328
+ //#endregion
329
+ //#region src/vite/content/content.store.ts
330
+ const CONTENT_VIRTUAL_ID = "virtual:prestige/content/";
331
+ function resolveSiblings(base, slug, linksMap) {
332
+ const links = linksMap.get(base);
333
+ if (!links?.length) return {
334
+ prev: void 0,
335
+ next: void 0
336
+ };
337
+ const linkIndex = links.filter((l) => "slug" in l).findIndex((link) => link.slug === slug);
338
+ let prev;
339
+ let next;
340
+ if (linkIndex > 0) prev = links[linkIndex - 1];
341
+ if (linkIndex < links.length - 1) next = links[linkIndex + 1];
342
+ return {
343
+ prev,
344
+ next
345
+ };
346
+ }
347
+ async function resolveMarkdown(slug, contentDir) {
348
+ const filePath = await getPathBySlug(slug, contentDir);
349
+ const baseUrl = pathToFileURL(filePath).href;
350
+ const file = await read(filePath);
351
+ const frontmatter = await compileFrontmatter(file);
352
+ const { code, toc } = await compileMarkdown(file, baseUrl);
353
+ return {
354
+ code,
355
+ toc,
356
+ frontmatter
357
+ };
358
+ }
359
+ async function resolveContent(id, linksMap, contentDir) {
360
+ const slug = id.replace(CONTENT_VIRTUAL_ID, "").replace("\0", "");
361
+ const base = slug.split("/")[0];
362
+ const { prev, next } = resolveSiblings(base, slug, linksMap);
363
+ const { toc, code, frontmatter } = await resolveMarkdown(slug, contentDir);
364
+ let resolvedCode = code;
365
+ resolvedCode += `\n export const toc = ${JSON.stringify(toc)}\n`;
366
+ resolvedCode += `\n export const prev = ${JSON.stringify(prev)}\n`;
367
+ resolvedCode += `\n export const next = ${JSON.stringify(next)}\n`;
368
+ resolvedCode += `\n export const frontmatter = ${JSON.stringify(frontmatter)}\n`;
369
+ return resolvedCode;
370
+ }
371
+ async function getPathBySlug(slug, contentDir) {
372
+ const pathMatch = join$1(contentDir, slug);
373
+ const matches = await glob(`${pathMatch}.{md,mdx}`);
374
+ if (matches.length === 0) throw new PrestigeError(`[Prestige] Could not find markdown file for slug: "${slug}". Searched at: ${pathMatch}.{md,mdx}. If you want to link to a custom page, use 'link: "${slug}"' instead of 'slug: "${slug}"' in your collection config.`);
375
+ return matches[0];
376
+ }
377
+ async function getFileBySlug(slug, contentDir) {
378
+ return await read(await getPathBySlug(slug, contentDir));
379
+ }
380
+ function getSlugByPath(path, contentDir) {
381
+ const pathInfo = parse(relative(contentDir, path));
382
+ return join$1(pathInfo.dir, pathInfo.name);
383
+ }
384
+
385
+ //#endregion
386
+ //#region src/vite/content/content-sidebar.store.ts
387
+ const SIDEBAR_VIRTUAL_ID = "virtual:prestige/sidebar/";
388
+ function resolveDefaultLink(items, defaultLink) {
389
+ if (defaultLink) return defaultLink;
390
+ for (const item of items) if ("slug" in item) return item.slug;
391
+ else if ("link" in item) return item.link;
392
+ else if ("items" in item && item.items.length > 0) {
393
+ const link = resolveDefaultLink(item.items);
394
+ if (link) return link;
395
+ }
396
+ }
397
+ async function resolveSidebars(collections, contentDir) {
398
+ const store = /* @__PURE__ */ new Map();
399
+ for (const collection of collections) {
400
+ const sidebar = await processCollection(collection, contentDir);
401
+ store.set(collection.id, sidebar);
402
+ }
403
+ return store;
404
+ }
405
+ /** @visibleForTesting */
406
+ async function processCollection(collection, contentDir) {
407
+ const items = [];
408
+ for (const item of collection.items) items.push(await processItem(item, contentDir));
409
+ const defaultLink = resolveDefaultLink(items, collection.defaultLink);
410
+ if (!defaultLink) throw new PrestigeError(`No default link found in collection, it means there are no links in the collection. Please define one in ${collection.id}`);
411
+ return {
412
+ items,
413
+ defaultLink
414
+ };
415
+ }
416
+ /** @visibleForTesting */
417
+ async function processItem(item, contentDir) {
418
+ if (typeof item === "string" || "slug" in item) return resolveInternalSidebarLink(item, contentDir);
419
+ else if ("link" in item) return resolveSidebarLink(item, contentDir);
420
+ else return resolveSidebarGroup(item, contentDir);
421
+ }
422
+ /** @visibleForTesting */
423
+ async function resolveSidebarGroup(group, contentDir) {
424
+ const label = await resolveLabel(group, contentDir);
425
+ const items = [];
426
+ if (group.items?.length && group.autogenerate) logger_default.warn(`${group.label} has both items and autogenerate. Only items will be used.`);
427
+ if (group.items) for (const childItem of group.items) items.push(await processItem(childItem, contentDir));
428
+ else if (group.autogenerate?.directory) {
429
+ const generatedItems = await autogenerateSidebar(group.autogenerate.directory, contentDir);
430
+ items.push(...generatedItems);
431
+ }
432
+ return {
433
+ label,
434
+ collapsible: group.collapsible,
435
+ items
436
+ };
437
+ }
438
+ /** @visibleForTesting */
439
+ async function resolveInternalSidebarLink(item, contentDir) {
440
+ const label = await resolveLabel(item, contentDir);
441
+ const slug = resolveSlug(item);
442
+ if (slug.startsWith("/") || slug.endsWith("/")) throw new PrestigeError(`The slug ${slug} cannot start or end with a slash. Remove it and try again.`);
443
+ if (!slug) throw new PrestigeError(`The slug cannot be empty. Remove it and try again. link label is ${label}`);
444
+ return {
445
+ label,
446
+ slug
447
+ };
448
+ }
449
+ /** @visibleForTesting */
450
+ async function resolveSidebarLink(item, contentDir) {
451
+ const label = await resolveLabel(item, contentDir);
452
+ const link = resolveLink(item);
453
+ if (!link) throw new PrestigeError(`The link cannot be empty. Remove it and try again. link label is ${label}`);
454
+ return {
455
+ label,
456
+ link
457
+ };
458
+ }
459
+ /** @visibleForTesting */
460
+ async function autogenerateSidebar(directory, contentDir) {
461
+ const fileExtRegex = /\.mdx?$/i;
462
+ const items = [];
463
+ const dirPath = join(contentDir, directory);
464
+ if (!await pathExists(dirPath)) {
465
+ logger_default.warn(`Directory doesn't exist: ${directory}`);
466
+ return [];
467
+ }
468
+ const dirents = await readdir(dirPath, { withFileTypes: true });
469
+ dirents.sort((a, b) => a.name.localeCompare(b.name));
470
+ for (const dirent of dirents) if (dirent.isDirectory()) {
471
+ const subDir = join(directory, dirent.name);
472
+ const group = {
473
+ label: dirent.name,
474
+ autogenerate: { directory: subDir }
475
+ };
476
+ items.push(await resolveSidebarGroup(group, contentDir));
477
+ } else if (dirent.isFile() && fileExtRegex.test(dirent.name)) {
478
+ const slug = join(directory, dirent.name).replace(fileExtRegex, "");
479
+ items.push(await resolveInternalSidebarLink(slug, contentDir));
480
+ }
481
+ return items;
482
+ }
483
+ /** @visibleForTesting */
484
+ async function resolveLabel(item, contentDir) {
485
+ if (typeof item !== "string" && "label" in item && item.label) return item.label;
486
+ if (typeof item === "string" || "slug" in item) {
487
+ const slug = resolveSlug(item);
488
+ const file = await getFileBySlug(slug, contentDir);
489
+ if (!file) throw new PrestigeError(`markdown file not found with slug: ${slug} add one in content folder or update config`);
490
+ const data = await compileFrontmatter(file);
491
+ if (data?.label) return data?.label;
492
+ return basename(slug);
493
+ }
494
+ if (typeof item !== "string" && ("items" in item || "autogenerate" in item)) return item.label;
495
+ return "";
496
+ }
497
+ /** @visibleForTesting */
498
+ function resolveSlug(item) {
499
+ if (typeof item === "string") return item;
500
+ else {
501
+ if ("slug" in item) return item.slug;
502
+ return "";
503
+ }
504
+ }
505
+ /** @visibleForTesting */
506
+ function resolveLink(item) {
507
+ if (typeof item === "object" && "link" in item) return item.link;
508
+ return "";
509
+ }
510
+
511
+ //#endregion
512
+ //#region src/vite/content/router-compiler.ts
513
+ async function compileRoutes(linksMap, routesDir) {
514
+ const prestigeFullPath = join$1(routesDir, "(prestige)");
515
+ try {
516
+ await mkdir(prestigeFullPath, { recursive: true });
517
+ const generatedFiles = /* @__PURE__ */ new Map();
518
+ for (const [key, links] of linksMap) {
519
+ const onlyInternalLinks = links.filter((l) => "slug" in l);
520
+ const sidebarFile = key + ".lazy.tsx";
521
+ generatedFiles.set(sidebarFile, createLayoutRoute(key));
522
+ for (const l of onlyInternalLinks) {
523
+ const pathified = l.slug.replaceAll("/", ".") + ".lazy.tsx";
524
+ generatedFiles.set(pathified, createContentRoute(l.slug));
525
+ }
526
+ }
527
+ await Promise.all([...generatedFiles.entries()].map(async ([fileName, contents]) => {
528
+ const filePath = join$1(prestigeFullPath, fileName);
529
+ try {
530
+ if (await readFile(filePath, "utf-8") === contents) return;
531
+ } catch (e) {}
532
+ logger_default.info(`Writing route file: ${fileName}`, { timestamp: true });
533
+ return writeFile(filePath, contents);
534
+ }));
535
+ const staleFiles = (await readdir(prestigeFullPath)).filter((fileName) => fileName.endsWith(".lazy.tsx") && !generatedFiles.has(fileName));
536
+ await Promise.all(staleFiles.map((fileName) => {
537
+ logger_default.info(`Removing stale route file: ${fileName}`, { timestamp: true });
538
+ return unlink(join$1(prestigeFullPath, fileName));
539
+ }));
540
+ } catch (error) {
541
+ logger_default.error(`[Prestige Router Compiler] Failed to compile routes: ${error}`, { timestamp: true });
542
+ console.error("[Prestige Router Compiler] Failed to compile routes:", error);
543
+ }
544
+ }
545
+ function createLayoutRoute(id) {
546
+ return `
547
+ import { createLazyFileRoute } from '@tanstack/react-router';
548
+ import sidebar from "virtual:prestige/sidebar/${id}";
549
+ import { CollectionRoute } from "@lonik/prestige/ui";
550
+
551
+ export const Route = createLazyFileRoute('/(prestige)/${id}')(CollectionRoute(sidebar, "${id}"));
552
+ `.trim() + "\n";
553
+ }
554
+ function createContentRoute(slug) {
555
+ return `
556
+ import { createLazyFileRoute } from "@tanstack/react-router";
557
+ import * as contentData from "virtual:prestige/content/${slug}";
558
+ import { ContentRoute } from "@lonik/prestige/ui";
559
+
560
+ export const Route = createLazyFileRoute('/(prestige)/${slug}')(ContentRoute(contentData));
561
+ `.trim() + "\n";
562
+ }
563
+
564
+ //#endregion
565
+ //#region src/vite/utils/code-generation.ts
566
+ function genExportDefault(specifier) {
567
+ return `export default ${specifier};`;
568
+ }
569
+ /** exports default undefined */
570
+ function genExportUndefined() {
571
+ return genExportDefault("undefined");
572
+ }
573
+
574
+ //#endregion
575
+ //#region src/vite/core/content/content-collection.store.ts
576
+ const COLLECTION_VIRTUAL_ID = "virtual:prestige/collection-all";
577
+ function resolveCollectionNavigations(inlineCollections, linksMap) {
578
+ const collections = inlineCollections.map((c) => ({
579
+ id: c.id,
580
+ label: c.label ?? c.id,
581
+ defaultLink: c.defaultLink ?? ""
582
+ }));
583
+ if (collections.length === 0) throw new PrestigeError(`No collections found, add one in prestige plugin config`);
584
+ for (const coll of collections) {
585
+ const firstLink = linksMap.get(coll.id)?.[0];
586
+ if (coll.defaultLink || !firstLink) continue;
587
+ coll.defaultLink = firstLink.slug;
588
+ }
589
+ for (const coll of collections) if (!coll.defaultLink) console.warn(`No default link found for collection ${coll.id}, it won't be displayed in the header navigation`);
590
+ return genExportDefault(genArrayFromRaw(collections.filter((c) => c.defaultLink).map((c) => genObjectFromValues(c))));
591
+ }
592
+
593
+ //#endregion
594
+ //#region src/vite/plugin.ts
595
+ const CONFIG_VIRTUAL_ID = "virtual:prestige/config";
596
+ function prestige(inlineConfig) {
597
+ let config;
598
+ let contentDir;
599
+ let isDocsMatcher;
600
+ let collections = [];
601
+ let internalLinksMap;
602
+ let collectionNavigations;
603
+ let sidebarsMap;
604
+ return {
605
+ name: "vite-plugin-prestige",
606
+ enforce: "pre",
607
+ async configResolved(resolvedConfig) {
608
+ logger_default.info("Resolving Prestige configuration...", { timestamp: true });
609
+ const { config: loadedConfig } = await resolvePrestigeConfig(inlineConfig, resolvedConfig.root);
610
+ config = loadedConfig;
611
+ contentDir = join(resolvedConfig.root, "src/content");
612
+ isDocsMatcher = picomatch(join(contentDir, "**/*.{md,mdx}"));
613
+ collections = config.collections ?? [];
614
+ logger_default.info("Resolving sidebars...", { timestamp: true });
615
+ sidebarsMap = await resolveSidebars(collections, contentDir);
616
+ logger_default.info("Resolving content links...", { timestamp: true });
617
+ internalLinksMap = resolveContentInternalLinks(sidebarsMap);
618
+ logger_default.info("Resolving collection navigations...", { timestamp: true });
619
+ collectionNavigations = resolveCollectionNavigations(collections, internalLinksMap);
620
+ const routesDir = join(resolvedConfig.root, "src", "routes");
621
+ logger_default.info("Compiling routes...", { timestamp: true });
622
+ await compileRoutes(internalLinksMap, routesDir);
623
+ logger_default.info("Warming up compiler...", { timestamp: true });
624
+ warmupCompiler(config.markdown);
625
+ },
626
+ resolveId(id) {
627
+ if (id.includes(CONFIG_VIRTUAL_ID)) {
628
+ logger_default.info(`Resolving config virtual ID: ${id}`, { timestamp: true });
629
+ return extractVirtualId(id, CONFIG_VIRTUAL_ID);
630
+ }
631
+ if (id.includes(CONTENT_VIRTUAL_ID)) {
632
+ logger_default.info(`Resolving content virtual ID: ${id}`, { timestamp: true });
633
+ return extractVirtualId(id, CONTENT_VIRTUAL_ID);
634
+ }
635
+ if (id.includes(COLLECTION_VIRTUAL_ID)) {
636
+ logger_default.info(`Resolving collection virtual ID: ${id}`, { timestamp: true });
637
+ return extractVirtualId(id, COLLECTION_VIRTUAL_ID);
638
+ }
639
+ if (id.includes(SIDEBAR_VIRTUAL_ID)) {
640
+ logger_default.info(`Resolving sidebar virtual ID: ${id}`, { timestamp: true });
641
+ return extractVirtualId(id, SIDEBAR_VIRTUAL_ID);
642
+ }
643
+ return null;
644
+ },
645
+ async load(id) {
646
+ if (id === `\0${CONFIG_VIRTUAL_ID}`) {
647
+ logger_default.info(`Loading config virtual module: ${id}`, { timestamp: true });
648
+ return genExportDefault(JSON.stringify(config));
649
+ }
650
+ if (id.includes(CONTENT_VIRTUAL_ID)) {
651
+ logger_default.info(`Loading content virtual module: ${id}`, { timestamp: true });
652
+ return await resolveContent(id, internalLinksMap, contentDir);
653
+ }
654
+ if (id.includes(COLLECTION_VIRTUAL_ID)) {
655
+ logger_default.info(`Loading collection virtual module: ${id}`, { timestamp: true });
656
+ return collectionNavigations;
657
+ }
658
+ if (id.includes(SIDEBAR_VIRTUAL_ID)) {
659
+ logger_default.info(`Loading sidebar virtual module: ${id}`, { timestamp: true });
660
+ const sidebarId = id.replace(SIDEBAR_VIRTUAL_ID, "").replace("\0", "");
661
+ const sidebar = sidebarsMap.get(sidebarId);
662
+ if (!sidebar) return genExportUndefined();
663
+ return genExportDefault(genObjectFromValues(sidebar));
664
+ }
665
+ return null;
666
+ },
667
+ async hotUpdate({ file, timestamp }) {
668
+ if (isDocsMatcher(file)) {
669
+ logger_default.info(`Invalidating module ${file}...`, { timestamp: true });
670
+ const invalidatedModules = /* @__PURE__ */ new Set();
671
+ const virtualModuleId = `\0${CONTENT_VIRTUAL_ID}${getSlugByPath(file, contentDir)}`;
672
+ const module = this.environment.moduleGraph.getModuleById(virtualModuleId);
673
+ if (module) {
674
+ this.environment.moduleGraph.invalidateModule(module, invalidatedModules, timestamp, true);
675
+ logger_default.info(`Reloading application...`, { timestamp: true });
676
+ this.environment.hot.send({ type: "full-reload" });
677
+ }
678
+ }
679
+ }
680
+ };
681
+ }
682
+
683
+ //#endregion
684
+ export { prestige };
685
+ //# sourceMappingURL=vite.js.map