@unterberg/nivel 0.0.2 → 0.0.3

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/README.md CHANGED
@@ -84,7 +84,8 @@ Then the consumer wires:
84
84
  - `@unterberg/nivel/vike` into Vike config
85
85
  - `MetaHead` in global `+Head`
86
86
  - `AppLayout` in global `+Layout`
87
- - `syncGeneratedDocsPages()` before dev/build/typecheck
87
+ - `nivel prepare` before dev/build/typecheck
88
+ - `@import '@unterberg/nivel/tailwind-sources.css'` in the consumer Tailwind entry
88
89
 
89
90
  Algolia search is optional. When configured, `apiKey` must be a search-only public key because requests are made from the browser.
90
91
 
package/bin/nivel.mjs ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+
3
+ import '../dist/cli.js'
@@ -3,9 +3,6 @@ import {
3
3
  getResolvedPageById,
4
4
  resolveDocsConfig
5
5
  } from "./chunk-D7IAGT53.js";
6
- import {
7
- nivelPublicRoute
8
- } from "./chunk-PYYPYIBD.js";
9
6
 
10
7
  // src/runtime/node/codegen.ts
11
8
  import fs from "fs";
@@ -193,167 +190,42 @@ var isDocsSourcePath = (filePath, rootDir) => {
193
190
  return normalized === docsConfigPath || normalized.startsWith(`${docsRoot}/`);
194
191
  };
195
192
 
196
- // src/runtime/node/plugin.ts
197
- import fs3 from "fs";
198
- import path3 from "path";
199
-
200
- // src/runtime/node/publicAssets.ts
201
- import fs2 from "fs";
193
+ // src/runtime/node/loadDocsConfig.ts
202
194
  import path2 from "path";
203
- import { fileURLToPath, pathToFileURL } from "url";
204
- var toPosix2 = (value) => value.split(path2.sep).join(path2.posix.sep);
205
- var getRequestPathname = (requestUrl) => {
206
- return requestUrl?.split("?")[0]?.split("#")[0] ?? "";
207
- };
208
- var normalizeNivelAssetPathname = (pathname) => {
209
- if (pathname === nivelPublicRoute) {
210
- return pathname;
211
- }
212
- if (!pathname.startsWith(`${nivelPublicRoute}/`)) {
213
- return null;
214
- }
215
- const trimmedPathname = pathname.replace(/\/+$/g, "");
216
- if (trimmedPathname !== pathname && path2.extname(trimmedPathname)) {
217
- return trimmedPathname;
218
- }
219
- return pathname;
220
- };
221
- var getPublicAssetsRootCandidates = (runtimeDir) => {
222
- let packageRoot = null;
223
- try {
224
- const nivelConfigUrl = import.meta.resolve("@unterberg/nivel/vike");
225
- const nivelConfigPath = fileURLToPath(nivelConfigUrl);
226
- packageRoot = path2.resolve(path2.dirname(nivelConfigPath), "..");
227
- } catch {
228
- packageRoot = null;
229
- }
230
- return [
231
- ...packageRoot ? [path2.join(packageRoot, "assets")] : [],
232
- path2.resolve(runtimeDir, "../assets"),
233
- path2.resolve(runtimeDir, "../../assets")
234
- ];
235
- };
236
- var getNivelPublicAssetsRoot = () => {
237
- const runtimeUrl = import.meta.url.startsWith("/") ? pathToFileURL(import.meta.url).href : import.meta.url;
238
- const runtimeDir = path2.dirname(fileURLToPath(runtimeUrl));
239
- for (const candidate of getPublicAssetsRootCandidates(runtimeDir)) {
240
- if (fs2.existsSync(candidate) && fs2.statSync(candidate).isDirectory()) {
241
- return candidate;
242
- }
243
- }
244
- throw new Error(`Unable to locate nivel public assets from ${runtimeDir}.`);
195
+ import { pathToFileURL } from "url";
196
+ import { register } from "tsx/esm/api";
197
+ var getDocsConfigModulePath = (rootDir) => {
198
+ return path2.join(rootDir, "pages", "+docs.ts");
245
199
  };
246
- var getNivelPublicAssetFilePath = (requestUrl) => {
247
- const pathname = normalizeNivelAssetPathname(getRequestPathname(requestUrl));
248
- if (!pathname) {
249
- return null;
250
- }
251
- const assetsRoot = getNivelPublicAssetsRoot();
252
- const relativePath = pathname.replace(/^\/+/, "");
253
- const filePath = path2.resolve(assetsRoot, relativePath);
254
- const relativeToRoot = path2.relative(assetsRoot, filePath);
255
- if (relativeToRoot.startsWith("..") || path2.isAbsolute(relativeToRoot) || !fs2.existsSync(filePath) || !fs2.statSync(filePath).isFile()) {
256
- return null;
257
- }
258
- return filePath;
259
- };
260
- var getNivelPublicAssetContentType = (filePath) => {
261
- switch (path2.extname(filePath)) {
262
- case ".css":
263
- return "text/css; charset=utf-8";
264
- case ".svg":
265
- return "image/svg+xml";
266
- case ".png":
267
- return "image/png";
268
- case ".ico":
269
- return "image/x-icon";
270
- case ".woff2":
271
- return "font/woff2";
272
- default:
273
- return "application/octet-stream";
274
- }
275
- };
276
- var isNivelAssetRequestUrl = (requestUrl) => {
277
- return normalizeNivelAssetPathname(getRequestPathname(requestUrl)) !== null;
278
- };
279
- var isNivelAssetPath = (filePath) => {
280
- const normalizedFilePath = toPosix2(path2.resolve(filePath));
281
- const assetsRoot = toPosix2(getNivelPublicAssetsRoot());
282
- return normalizedFilePath.startsWith(`${assetsRoot}/`);
283
- };
284
-
285
- // src/runtime/node/plugin.ts
286
- var loadDocsConfig = async (server, rootDir) => {
287
- const modulePath = path3.join(rootDir, "pages", "+docs.ts");
288
- const loaded = await server.ssrLoadModule(modulePath);
200
+ var getDocsConfigFromLoadedModule = (loaded, modulePath) => {
289
201
  const docsConfig = loaded.default;
290
202
  if (!docsConfig) {
291
203
  throw new Error(`Expected default export from ${modulePath}`);
292
204
  }
293
205
  return docsConfig;
294
206
  };
295
- var syncAndRestart = async (server, rootDir) => {
296
- const docsConfig = await loadDocsConfig(server, rootDir);
297
- syncGeneratedDocsPages({ rootDir, docsConfig });
298
- await server.restart();
207
+ var loadDocsConfig = async (options) => {
208
+ const modulePath = getDocsConfigModulePath(options.rootDir);
209
+ const loaded = await options.loadModule(modulePath);
210
+ return getDocsConfigFromLoadedModule(loaded, modulePath);
299
211
  };
300
- var nivelPagesPlugin = () => {
301
- return {
302
- name: "nivel-pages-plugin",
303
- enforce: "pre",
304
- configureServer(server) {
305
- const rootDir = server.config.root;
306
- const assetsRoot = getNivelPublicAssetsRoot();
307
- server.watcher.add(assetsRoot);
308
- const onChange = async (filePath) => {
309
- if (!isDocsSourcePath(filePath, rootDir)) {
310
- return;
311
- }
312
- await syncAndRestart(server, rootDir);
313
- };
314
- server.watcher.on("add", onChange);
315
- server.watcher.on("change", onChange);
316
- server.watcher.on("unlink", onChange);
317
- server.watcher.on("change", (filePath) => {
318
- if (!isNivelAssetPath(filePath)) {
319
- return;
320
- }
321
- server.ws.send({ type: "full-reload" });
322
- });
323
- server.middlewares.use((req, res, next) => {
324
- const filePath = getNivelPublicAssetFilePath(req.url);
325
- if (filePath) {
326
- res.setHeader("Content-Type", getNivelPublicAssetContentType(filePath));
327
- res.setHeader("Cache-Control", "no-store");
328
- res.end(fs3.readFileSync(filePath));
329
- return;
330
- }
331
- if (isNivelAssetRequestUrl(req.url)) {
332
- res.statusCode = 404;
333
- res.setHeader("Cache-Control", "no-store");
334
- res.end();
335
- return;
336
- }
337
- next();
338
- });
339
- },
340
- handleHotUpdate(ctx) {
341
- if (isNivelAssetPath(ctx.file)) {
342
- ctx.server.ws.send({ type: "full-reload" });
343
- return [];
344
- }
345
- if (!isDocsSourcePath(ctx.file, ctx.server.config.root)) {
346
- return;
347
- }
348
- ctx.server.ws.send({ type: "full-reload" });
349
- return [];
350
- }
351
- };
212
+ var loadDocsConfigWithVite = async (rootDir) => {
213
+ const unregister = register();
214
+ const modulePath = getDocsConfigModulePath(rootDir);
215
+ const moduleUrl = pathToFileURL(modulePath).href;
216
+ try {
217
+ const loaded = await import(moduleUrl);
218
+ return getDocsConfigFromLoadedModule(loaded, modulePath);
219
+ } finally {
220
+ await unregister();
221
+ }
352
222
  };
353
223
 
354
224
  export {
355
225
  getGeneratedPagesRoot,
356
226
  syncGeneratedDocsPages,
357
- nivelPagesPlugin
227
+ isDocsSourcePath,
228
+ loadDocsConfig,
229
+ loadDocsConfigWithVite
358
230
  };
359
- //# sourceMappingURL=chunk-HXZEI3YF.js.map
231
+ //# sourceMappingURL=chunk-DNCQR5NH.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/runtime/node/codegen.ts","../src/runtime/node/loadDocsConfig.ts"],"sourcesContent":["import fs from 'node:fs'\nimport path from 'node:path'\nimport type { DocPageData, DocPageLinkData, DocsConfig, DocsGlobalContextData } from '../../docs/types.js'\nimport { extractDocHeadings } from '../../docs/docHeadings.js'\nimport { getResolvedPageById, resolveDocsConfig } from '../../docs/resolveDocsConfig.js'\n\nconst GENERATED_DIRNAME = '(nivel-generated)'\n\nconst writeFileIfChanged = (filePath: string, source: string) => {\n const current = fs.existsSync(filePath) ? fs.readFileSync(filePath, 'utf8') : null\n if (current === source) {\n return\n }\n\n fs.mkdirSync(path.dirname(filePath), { recursive: true })\n fs.writeFileSync(filePath, source)\n}\n\nconst toPosix = (value: string) => value.split(path.sep).join(path.posix.sep)\n\nconst getRelativeImportPath = (fromDirectory: string, toFile: string) => {\n const relativePath = toPosix(path.relative(fromDirectory, toFile))\n if (relativePath.startsWith('.')) {\n return relativePath\n }\n return `./${relativePath}`\n}\n\nconst serializeData = (data: DocPageData | DocsGlobalContextData) => JSON.stringify(data, null, 2)\n\nconst collectFiles = (directoryPath: string): string[] => {\n if (!fs.existsSync(directoryPath)) {\n return []\n }\n\n const entries = fs.readdirSync(directoryPath, { withFileTypes: true })\n\n return entries.flatMap((entry) => {\n const entryPath = path.join(directoryPath, entry.name)\n return entry.isDirectory() ? collectFiles(entryPath) : [entryPath]\n })\n}\n\nconst removeEmptyDirectories = (directoryPath: string, rootPath: string) => {\n if (!fs.existsSync(directoryPath)) {\n return\n }\n\n for (const entry of fs.readdirSync(directoryPath, { withFileTypes: true })) {\n if (!entry.isDirectory()) {\n continue\n }\n\n removeEmptyDirectories(path.join(directoryPath, entry.name), rootPath)\n }\n\n if (directoryPath === rootPath) {\n return\n }\n\n if (fs.readdirSync(directoryPath).length === 0) {\n fs.rmdirSync(directoryPath)\n }\n}\n\nconst getGeneratedPageSource = (contentImportPath: string) => {\n return [\n \"import { DocsPage } from '@unterberg/nivel/client'\",\n `import Content from ${JSON.stringify(contentImportPath)}`,\n '',\n 'const Page = () => {',\n ' return <DocsPage Content={Content} />',\n '}',\n '',\n 'export default Page',\n '',\n ].join('\\n')\n}\n\nconst getGeneratedDataSource = (data: DocPageData) => {\n return [\n \"import type { DocPageData } from '@unterberg/nivel'\",\n '',\n `const data: DocPageData = ${serializeData(data)}`,\n '',\n 'const pageData = () => {',\n ' return data',\n '}',\n '',\n 'export default pageData',\n '',\n ].join('\\n')\n}\n\nconst getGeneratedGlobalContextSource = (data: DocsGlobalContextData) => {\n return [\n \"import type { DocsGlobalContextData } from '@unterberg/nivel'\",\n '',\n `const docsGlobalContextData: DocsGlobalContextData = ${serializeData(data)}`,\n '',\n 'export { docsGlobalContextData }',\n '',\n ].join('\\n')\n}\n\nconst getRouteString = (href: string) => {\n if (href === '/') {\n return href\n }\n\n return href.replace(/\\/+$/g, '')\n}\n\nconst getGeneratedRouteSource = (href: string) => {\n return [`export default ${JSON.stringify(getRouteString(href))}`, ''].join('\\n')\n}\n\nconst getGeneratedTextExport = (value: string) => {\n return [`export default ${JSON.stringify(value)}`, ''].join('\\n')\n}\n\nconst toDocPageLinkData = (\n page:\n | {\n id: string\n title: string\n href: string\n documentTitle: string\n }\n | undefined,\n): DocPageLinkData | null => {\n if (!page) {\n return null\n }\n\n return {\n id: page.id,\n title: page.title,\n href: page.href,\n documentTitle: page.documentTitle,\n }\n}\n\nexport const getGeneratedPagesRoot = (rootDir: string) => path.join(rootDir, 'pages', GENERATED_DIRNAME)\n\nexport const syncGeneratedDocsPages = (options: { rootDir: string; docsConfig: DocsConfig }) => {\n const { rootDir, docsConfig } = options\n const resolved = resolveDocsConfig(docsConfig)\n const generatedPagesRoot = getGeneratedPagesRoot(rootDir)\n const docsRoot = path.join(rootDir, 'docs')\n const expectedFiles = new Set<string>()\n const globalContextFilePath = path.join(generatedPagesRoot, '_docsGlobalContext.ts')\n\n fs.mkdirSync(generatedPagesRoot, { recursive: true })\n\n const globalContextData: DocsGlobalContextData = {\n siteTitle: resolved.siteTitle,\n basePath: resolved.basePath,\n theme: resolved.theme,\n footer: resolved.footer,\n brand: resolved.brand,\n head: resolved.head,\n partners: resolved.partners,\n algolia: resolved.algolia,\n pages: resolved.pages,\n navbarItems: resolved.navbarItems,\n sidebarSections: resolved.sections,\n }\n\n writeFileIfChanged(globalContextFilePath, getGeneratedGlobalContextSource(globalContextData))\n expectedFiles.add(globalContextFilePath)\n\n for (const [pageIndex, page] of resolved.pages.entries()) {\n const contentFilePath = path.join(docsRoot, page.source)\n\n if (!fs.existsSync(contentFilePath)) {\n throw new Error(`Docs page \"${page.id}\" points to missing source file: ${contentFilePath}`)\n }\n\n const pageSource = fs.readFileSync(contentFilePath, 'utf8')\n const data: DocPageData = {\n page: getResolvedPageById(resolved, page.id),\n headings: extractDocHeadings(pageSource),\n previousPage: toDocPageLinkData(resolved.pages[pageIndex - 1]),\n nextPage: toDocPageLinkData(resolved.pages[pageIndex + 1]),\n }\n\n for (const routeHref of [page.href, ...page.aliasHrefs]) {\n const routeSlug = routeHref.replace(/^\\/docs\\//, '').replace(/\\/+$/g, '')\n const pageDir = path.join(generatedPagesRoot, ...routeSlug.split('/'))\n const contentImportPath = getRelativeImportPath(pageDir, contentFilePath)\n\n const pageFilePath = path.join(pageDir, '+Page.tsx')\n const dataFilePath = path.join(pageDir, '+data.ts')\n const routeFilePath = path.join(pageDir, '+route.ts')\n const titleFilePath = path.join(pageDir, '+title.ts')\n\n writeFileIfChanged(pageFilePath, getGeneratedPageSource(contentImportPath))\n writeFileIfChanged(dataFilePath, getGeneratedDataSource(data))\n writeFileIfChanged(routeFilePath, getGeneratedRouteSource(routeHref))\n writeFileIfChanged(titleFilePath, getGeneratedTextExport(page.documentTitle))\n\n expectedFiles.add(pageFilePath)\n expectedFiles.add(dataFilePath)\n expectedFiles.add(routeFilePath)\n expectedFiles.add(titleFilePath)\n\n if (page.description) {\n const descriptionFilePath = path.join(pageDir, '+description.ts')\n writeFileIfChanged(descriptionFilePath, getGeneratedTextExport(page.description))\n expectedFiles.add(descriptionFilePath)\n }\n }\n }\n\n for (const filePath of collectFiles(generatedPagesRoot)) {\n if (expectedFiles.has(filePath)) {\n continue\n }\n\n fs.rmSync(filePath, { force: true })\n }\n\n removeEmptyDirectories(generatedPagesRoot, generatedPagesRoot)\n}\n\nexport const isDocsSourcePath = (filePath: string, rootDir: string) => {\n const normalized = toPosix(filePath)\n const docsRoot = toPosix(path.join(rootDir, 'docs'))\n const docsConfigPath = toPosix(path.join(rootDir, 'pages', '+docs.ts'))\n const generatedRoot = toPosix(getGeneratedPagesRoot(rootDir))\n\n if (normalized.startsWith(generatedRoot)) {\n return false\n }\n\n return normalized === docsConfigPath || normalized.startsWith(`${docsRoot}/`)\n}\n","import path from 'node:path'\nimport { pathToFileURL } from 'node:url'\nimport { register } from 'tsx/esm/api'\nimport type { DocsConfig } from '../../docs/types.js'\n\nconst getDocsConfigModulePath = (rootDir: string) => {\n return path.join(rootDir, 'pages', '+docs.ts')\n}\n\nconst getDocsConfigFromLoadedModule = (loaded: unknown, modulePath: string) => {\n const docsConfig = (loaded as { default?: DocsConfig }).default\n\n if (!docsConfig) {\n throw new Error(`Expected default export from ${modulePath}`)\n }\n\n return docsConfig\n}\n\nexport const loadDocsConfig = async (options: {\n rootDir: string\n loadModule: (modulePath: string) => Promise<unknown>\n}) => {\n const modulePath = getDocsConfigModulePath(options.rootDir)\n const loaded = await options.loadModule(modulePath)\n return getDocsConfigFromLoadedModule(loaded, modulePath)\n}\n\nexport const loadDocsConfigWithVite = async (rootDir: string) => {\n const unregister = register()\n const modulePath = getDocsConfigModulePath(rootDir)\n const moduleUrl = pathToFileURL(modulePath).href\n\n try {\n const loaded = await import(moduleUrl)\n return getDocsConfigFromLoadedModule(loaded, modulePath)\n } finally {\n await unregister()\n }\n}\n"],"mappings":";;;;;;;AAAA,OAAO,QAAQ;AACf,OAAO,UAAU;AAKjB,IAAM,oBAAoB;AAE1B,IAAM,qBAAqB,CAAC,UAAkB,WAAmB;AAC/D,QAAM,UAAU,GAAG,WAAW,QAAQ,IAAI,GAAG,aAAa,UAAU,MAAM,IAAI;AAC9E,MAAI,YAAY,QAAQ;AACtB;AAAA,EACF;AAEA,KAAG,UAAU,KAAK,QAAQ,QAAQ,GAAG,EAAE,WAAW,KAAK,CAAC;AACxD,KAAG,cAAc,UAAU,MAAM;AACnC;AAEA,IAAM,UAAU,CAAC,UAAkB,MAAM,MAAM,KAAK,GAAG,EAAE,KAAK,KAAK,MAAM,GAAG;AAE5E,IAAM,wBAAwB,CAAC,eAAuB,WAAmB;AACvE,QAAM,eAAe,QAAQ,KAAK,SAAS,eAAe,MAAM,CAAC;AACjE,MAAI,aAAa,WAAW,GAAG,GAAG;AAChC,WAAO;AAAA,EACT;AACA,SAAO,KAAK,YAAY;AAC1B;AAEA,IAAM,gBAAgB,CAAC,SAA8C,KAAK,UAAU,MAAM,MAAM,CAAC;AAEjG,IAAM,eAAe,CAAC,kBAAoC;AACxD,MAAI,CAAC,GAAG,WAAW,aAAa,GAAG;AACjC,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,UAAU,GAAG,YAAY,eAAe,EAAE,eAAe,KAAK,CAAC;AAErE,SAAO,QAAQ,QAAQ,CAAC,UAAU;AAChC,UAAM,YAAY,KAAK,KAAK,eAAe,MAAM,IAAI;AACrD,WAAO,MAAM,YAAY,IAAI,aAAa,SAAS,IAAI,CAAC,SAAS;AAAA,EACnE,CAAC;AACH;AAEA,IAAM,yBAAyB,CAAC,eAAuB,aAAqB;AAC1E,MAAI,CAAC,GAAG,WAAW,aAAa,GAAG;AACjC;AAAA,EACF;AAEA,aAAW,SAAS,GAAG,YAAY,eAAe,EAAE,eAAe,KAAK,CAAC,GAAG;AAC1E,QAAI,CAAC,MAAM,YAAY,GAAG;AACxB;AAAA,IACF;AAEA,2BAAuB,KAAK,KAAK,eAAe,MAAM,IAAI,GAAG,QAAQ;AAAA,EACvE;AAEA,MAAI,kBAAkB,UAAU;AAC9B;AAAA,EACF;AAEA,MAAI,GAAG,YAAY,aAAa,EAAE,WAAW,GAAG;AAC9C,OAAG,UAAU,aAAa;AAAA,EAC5B;AACF;AAEA,IAAM,yBAAyB,CAAC,sBAA8B;AAC5D,SAAO;AAAA,IACL;AAAA,IACA,uBAAuB,KAAK,UAAU,iBAAiB,CAAC;AAAA,IACxD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,KAAK,IAAI;AACb;AAEA,IAAM,yBAAyB,CAAC,SAAsB;AACpD,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,6BAA6B,cAAc,IAAI,CAAC;AAAA,IAChD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,KAAK,IAAI;AACb;AAEA,IAAM,kCAAkC,CAAC,SAAgC;AACvE,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,wDAAwD,cAAc,IAAI,CAAC;AAAA,IAC3E;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,KAAK,IAAI;AACb;AAEA,IAAM,iBAAiB,CAAC,SAAiB;AACvC,MAAI,SAAS,KAAK;AAChB,WAAO;AAAA,EACT;AAEA,SAAO,KAAK,QAAQ,SAAS,EAAE;AACjC;AAEA,IAAM,0BAA0B,CAAC,SAAiB;AAChD,SAAO,CAAC,kBAAkB,KAAK,UAAU,eAAe,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,KAAK,IAAI;AACjF;AAEA,IAAM,yBAAyB,CAAC,UAAkB;AAChD,SAAO,CAAC,kBAAkB,KAAK,UAAU,KAAK,CAAC,IAAI,EAAE,EAAE,KAAK,IAAI;AAClE;AAEA,IAAM,oBAAoB,CACxB,SAQ2B;AAC3B,MAAI,CAAC,MAAM;AACT,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL,IAAI,KAAK;AAAA,IACT,OAAO,KAAK;AAAA,IACZ,MAAM,KAAK;AAAA,IACX,eAAe,KAAK;AAAA,EACtB;AACF;AAEO,IAAM,wBAAwB,CAAC,YAAoB,KAAK,KAAK,SAAS,SAAS,iBAAiB;AAEhG,IAAM,yBAAyB,CAAC,YAAyD;AAC9F,QAAM,EAAE,SAAS,WAAW,IAAI;AAChC,QAAM,WAAW,kBAAkB,UAAU;AAC7C,QAAM,qBAAqB,sBAAsB,OAAO;AACxD,QAAM,WAAW,KAAK,KAAK,SAAS,MAAM;AAC1C,QAAM,gBAAgB,oBAAI,IAAY;AACtC,QAAM,wBAAwB,KAAK,KAAK,oBAAoB,uBAAuB;AAEnF,KAAG,UAAU,oBAAoB,EAAE,WAAW,KAAK,CAAC;AAEpD,QAAM,oBAA2C;AAAA,IAC/C,WAAW,SAAS;AAAA,IACpB,UAAU,SAAS;AAAA,IACnB,OAAO,SAAS;AAAA,IAChB,QAAQ,SAAS;AAAA,IACjB,OAAO,SAAS;AAAA,IAChB,MAAM,SAAS;AAAA,IACf,UAAU,SAAS;AAAA,IACnB,SAAS,SAAS;AAAA,IAClB,OAAO,SAAS;AAAA,IAChB,aAAa,SAAS;AAAA,IACtB,iBAAiB,SAAS;AAAA,EAC5B;AAEA,qBAAmB,uBAAuB,gCAAgC,iBAAiB,CAAC;AAC5F,gBAAc,IAAI,qBAAqB;AAEvC,aAAW,CAAC,WAAW,IAAI,KAAK,SAAS,MAAM,QAAQ,GAAG;AACxD,UAAM,kBAAkB,KAAK,KAAK,UAAU,KAAK,MAAM;AAEvD,QAAI,CAAC,GAAG,WAAW,eAAe,GAAG;AACnC,YAAM,IAAI,MAAM,cAAc,KAAK,EAAE,oCAAoC,eAAe,EAAE;AAAA,IAC5F;AAEA,UAAM,aAAa,GAAG,aAAa,iBAAiB,MAAM;AAC1D,UAAM,OAAoB;AAAA,MACxB,MAAM,oBAAoB,UAAU,KAAK,EAAE;AAAA,MAC3C,UAAU,mBAAmB,UAAU;AAAA,MACvC,cAAc,kBAAkB,SAAS,MAAM,YAAY,CAAC,CAAC;AAAA,MAC7D,UAAU,kBAAkB,SAAS,MAAM,YAAY,CAAC,CAAC;AAAA,IAC3D;AAEA,eAAW,aAAa,CAAC,KAAK,MAAM,GAAG,KAAK,UAAU,GAAG;AACvD,YAAM,YAAY,UAAU,QAAQ,aAAa,EAAE,EAAE,QAAQ,SAAS,EAAE;AACxE,YAAM,UAAU,KAAK,KAAK,oBAAoB,GAAG,UAAU,MAAM,GAAG,CAAC;AACrE,YAAM,oBAAoB,sBAAsB,SAAS,eAAe;AAExE,YAAM,eAAe,KAAK,KAAK,SAAS,WAAW;AACnD,YAAM,eAAe,KAAK,KAAK,SAAS,UAAU;AAClD,YAAM,gBAAgB,KAAK,KAAK,SAAS,WAAW;AACpD,YAAM,gBAAgB,KAAK,KAAK,SAAS,WAAW;AAEpD,yBAAmB,cAAc,uBAAuB,iBAAiB,CAAC;AAC1E,yBAAmB,cAAc,uBAAuB,IAAI,CAAC;AAC7D,yBAAmB,eAAe,wBAAwB,SAAS,CAAC;AACpE,yBAAmB,eAAe,uBAAuB,KAAK,aAAa,CAAC;AAE5E,oBAAc,IAAI,YAAY;AAC9B,oBAAc,IAAI,YAAY;AAC9B,oBAAc,IAAI,aAAa;AAC/B,oBAAc,IAAI,aAAa;AAE/B,UAAI,KAAK,aAAa;AACpB,cAAM,sBAAsB,KAAK,KAAK,SAAS,iBAAiB;AAChE,2BAAmB,qBAAqB,uBAAuB,KAAK,WAAW,CAAC;AAChF,sBAAc,IAAI,mBAAmB;AAAA,MACvC;AAAA,IACF;AAAA,EACF;AAEA,aAAW,YAAY,aAAa,kBAAkB,GAAG;AACvD,QAAI,cAAc,IAAI,QAAQ,GAAG;AAC/B;AAAA,IACF;AAEA,OAAG,OAAO,UAAU,EAAE,OAAO,KAAK,CAAC;AAAA,EACrC;AAEA,yBAAuB,oBAAoB,kBAAkB;AAC/D;AAEO,IAAM,mBAAmB,CAAC,UAAkB,YAAoB;AACrE,QAAM,aAAa,QAAQ,QAAQ;AACnC,QAAM,WAAW,QAAQ,KAAK,KAAK,SAAS,MAAM,CAAC;AACnD,QAAM,iBAAiB,QAAQ,KAAK,KAAK,SAAS,SAAS,UAAU,CAAC;AACtE,QAAM,gBAAgB,QAAQ,sBAAsB,OAAO,CAAC;AAE5D,MAAI,WAAW,WAAW,aAAa,GAAG;AACxC,WAAO;AAAA,EACT;AAEA,SAAO,eAAe,kBAAkB,WAAW,WAAW,GAAG,QAAQ,GAAG;AAC9E;;;AC7OA,OAAOA,WAAU;AACjB,SAAS,qBAAqB;AAC9B,SAAS,gBAAgB;AAGzB,IAAM,0BAA0B,CAAC,YAAoB;AACnD,SAAOA,MAAK,KAAK,SAAS,SAAS,UAAU;AAC/C;AAEA,IAAM,gCAAgC,CAAC,QAAiB,eAAuB;AAC7E,QAAM,aAAc,OAAoC;AAExD,MAAI,CAAC,YAAY;AACf,UAAM,IAAI,MAAM,gCAAgC,UAAU,EAAE;AAAA,EAC9D;AAEA,SAAO;AACT;AAEO,IAAM,iBAAiB,OAAO,YAG/B;AACJ,QAAM,aAAa,wBAAwB,QAAQ,OAAO;AAC1D,QAAM,SAAS,MAAM,QAAQ,WAAW,UAAU;AAClD,SAAO,8BAA8B,QAAQ,UAAU;AACzD;AAEO,IAAM,yBAAyB,OAAO,YAAoB;AAC/D,QAAM,aAAa,SAAS;AAC5B,QAAM,aAAa,wBAAwB,OAAO;AAClD,QAAM,YAAY,cAAc,UAAU,EAAE;AAE5C,MAAI;AACF,UAAM,SAAS,MAAM,OAAO;AAC5B,WAAO,8BAA8B,QAAQ,UAAU;AAAA,EACzD,UAAE;AACA,UAAM,WAAW;AAAA,EACnB;AACF;","names":["path"]}
@@ -74,11 +74,54 @@ var AlertHeading = cm.header`
74
74
  // src/mdx/code-blocks/ChoiceGroup.tsx
75
75
  import { Children, isValidElement, useRef as useRef2 } from "react";
76
76
 
77
+ // src/mdx/code-blocks/CodeBlockHeaderMeta.tsx
78
+ import cm2 from "@classmatejs/react";
79
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
80
+ var CodeBlockHeaderMeta = ({ env, label }) => {
81
+ const effectiveEnv = env === "server" || env === "client" ? env : void 0;
82
+ return /* @__PURE__ */ jsxs2("div", { className: "flex min-w-0 items-center gap-2", children: [
83
+ env && /* @__PURE__ */ jsx2(StyledDivider, { $env: env === "server" || env === "client" ? env : void 0 }),
84
+ env && /* @__PURE__ */ jsx2(StyledBgShade, { $env: env === "server" || env === "client" ? env : void 0 }),
85
+ /* @__PURE__ */ jsx2("div", { className: "font-mono text-xs font-semibold text-base-muted", children: label }),
86
+ env && /* @__PURE__ */ jsx2(StyledBadge, { $env: effectiveEnv, children: env })
87
+ ] });
88
+ };
89
+ var StyledDivider = cm2.div.variants({
90
+ base: "absolute h-1 -bottom-px left-0 w-full pointer-events-none",
91
+ variants: {
92
+ $env: {
93
+ server: "border-info/50 border-b ",
94
+ client: "border-success/50 border-b"
95
+ }
96
+ },
97
+ defaultVariants: { $env: "server" }
98
+ });
99
+ var StyledBadge = cm2.div.variants({
100
+ base: "shrink-0 badge badge-sm rounded-field badge-soft border pointer-events-none",
101
+ variants: {
102
+ $env: {
103
+ server: "badge-info border-info",
104
+ client: "badge-success border-success"
105
+ }
106
+ },
107
+ defaultVariants: { $env: "server" }
108
+ });
109
+ var StyledBgShade = cm2.div.variants({
110
+ base: "absolute inset-0 opacity-5 bg-linear-to-t via-40% via-transparent pointer-events-none",
111
+ variants: {
112
+ $env: {
113
+ server: "from-info",
114
+ client: "from-success"
115
+ }
116
+ },
117
+ defaultVariants: { $env: "server" }
118
+ });
119
+
77
120
  // src/mdx/code-blocks/CopyButton.tsx
78
121
  import { cmMerge as cmMerge2 } from "@classmatejs/react";
79
122
  import { Check as Check2, Copy } from "lucide-react";
80
123
  import { useState } from "react";
81
- import { jsx as jsx2 } from "react/jsx-runtime";
124
+ import { jsx as jsx3 } from "react/jsx-runtime";
82
125
  var trimTrailingWhitespace = (text) => {
83
126
  return text.split("\n").map((line) => line.trimEnd()).join("\n");
84
127
  };
@@ -87,7 +130,7 @@ var CodeBlockCopyButton = ({
87
130
  className = ""
88
131
  }) => {
89
132
  const [copyState, setCopyState] = useState("idle");
90
- return /* @__PURE__ */ jsx2(
133
+ return /* @__PURE__ */ jsx3(
91
134
  "button",
92
135
  {
93
136
  type: "button",
@@ -98,7 +141,7 @@ var CodeBlockCopyButton = ({
98
141
  window.setTimeout(() => setCopyState("idle"), 900);
99
142
  },
100
143
  "aria-label": copyState === "idle" ? "Copy to clipboard" : copyState === "success" ? "Copied" : "Copy failed",
101
- children: copyState === "success" ? /* @__PURE__ */ jsx2(Check2, { size: 14 }) : /* @__PURE__ */ jsx2(Copy, { size: 14 })
144
+ children: copyState === "success" ? /* @__PURE__ */ jsx3(Check2, { size: 14 }) : /* @__PURE__ */ jsx3(Copy, { size: 14 })
102
145
  }
103
146
  );
104
147
  };
@@ -157,7 +200,7 @@ var useSelectedChoice = (choiceGroupName, defaultValue) => {
157
200
  };
158
201
 
159
202
  // src/mdx/code-blocks/ChoiceGroup.tsx
160
- import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
203
+ import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
161
204
  var isChoiceElement = (node) => {
162
205
  return isValidElement(node) && typeof node.props?.["data-choice-value"] === "string";
163
206
  };
@@ -170,17 +213,18 @@ var getActiveCodeBlockMeta = (node) => {
170
213
  continue;
171
214
  }
172
215
  const props = child.props;
216
+ const env = asTrimmedString(props["data-code-env"]);
173
217
  const title = asTrimmedString(props["data-code-title"]);
174
218
  const hideCopy = props["hide-menu"] === "true";
175
- if (title || hideCopy) {
176
- return { hideCopy, title };
219
+ if (title || env || hideCopy) {
220
+ return { env, hideCopy, title };
177
221
  }
178
222
  const nestedMeta = getActiveCodeBlockMeta(props.children);
179
- if (nestedMeta.title || nestedMeta.hideCopy) {
223
+ if (nestedMeta.title || nestedMeta.env || nestedMeta.hideCopy) {
180
224
  return nestedMeta;
181
225
  }
182
226
  }
183
- return { hideCopy: false, title: null };
227
+ return { env: null, hideCopy: false, title: null };
184
228
  };
185
229
  var ChoiceGroup = ({
186
230
  children,
@@ -193,28 +237,28 @@ var ChoiceGroup = ({
193
237
  const choiceElements = Children.toArray(children).filter(isChoiceElement);
194
238
  const activeChoiceElement = choiceElements.find((choiceElement) => choiceElement.props["data-choice-value"] === selectedChoice) ?? choiceElements[0];
195
239
  if (!activeChoiceElement) {
196
- return /* @__PURE__ */ jsx3(Fragment2, { children });
240
+ return /* @__PURE__ */ jsx4(Fragment2, { children });
197
241
  }
198
242
  const activeCodeBlockMeta = getActiveCodeBlockMeta(activeChoiceElement.props.children);
199
- const headerLabel = activeCodeBlockMeta.title ?? activeChoiceElement.props["data-choice-value"];
243
+ const headerLabel = activeCodeBlockMeta.title ?? activeChoiceElement.props["data-choice-value"] ?? "";
200
244
  if (hide) {
201
- return /* @__PURE__ */ jsx3(Fragment2, { children: activeChoiceElement.props.children });
245
+ return /* @__PURE__ */ jsx4(Fragment2, { children: activeChoiceElement.props.children });
202
246
  }
203
- return /* @__PURE__ */ jsxs2(
247
+ return /* @__PURE__ */ jsxs3(
204
248
  "div",
205
249
  {
206
250
  "data-choice-group-outer": true,
207
251
  className: "mt-5 mb-5 flex h-full flex-col overflow-hidden rounded-box border border-base-muted-light",
208
252
  children: [
209
- /* @__PURE__ */ jsxs2(
253
+ /* @__PURE__ */ jsxs3(
210
254
  "div",
211
255
  {
212
- className: "not-prose flex min-h-10 items-center justify-between gap-3 border-b border-base-muted-light bg-base-muted-superlight px-4",
256
+ className: "not-prose flex min-h-10 items-center relative justify-between gap-3 border-b border-base-muted-light bg-base-muted-superlight px-4",
213
257
  "data-choice-group-header": true,
214
258
  children: [
215
- /* @__PURE__ */ jsx3("div", { className: "font-mono text-xs font-semibold tracking-[0.08em] text-base-muted", children: headerLabel }),
216
- /* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-1", children: [
217
- /* @__PURE__ */ jsx3("label", { className: "select select-xs min-w-28 w-fit", children: /* @__PURE__ */ jsx3(
259
+ /* @__PURE__ */ jsx4(CodeBlockHeaderMeta, { label: headerLabel, env: activeCodeBlockMeta.env }),
260
+ /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-1", children: [
261
+ /* @__PURE__ */ jsx4("label", { className: "select select-xs min-w-28 w-fit", children: /* @__PURE__ */ jsx4(
218
262
  "select",
219
263
  {
220
264
  name: `choicesFor-${choiceGroup.name}`,
@@ -226,10 +270,10 @@ var ChoiceGroup = ({
226
270
  };
227
271
  setSelectedChoice(event.currentTarget.value);
228
272
  },
229
- children: choiceGroup.choices.map((choice) => /* @__PURE__ */ jsx3("option", { value: choice, disabled: choiceGroup.disabled.includes(choice), children: choice }, choice))
273
+ children: choiceGroup.choices.map((choice) => /* @__PURE__ */ jsx4("option", { value: choice, disabled: choiceGroup.disabled.includes(choice), children: choice }, choice))
230
274
  }
231
275
  ) }),
232
- !activeCodeBlockMeta.hideCopy && /* @__PURE__ */ jsx3(
276
+ !activeCodeBlockMeta.hideCopy && /* @__PURE__ */ jsx4(
233
277
  CodeBlockCopyButton,
234
278
  {
235
279
  onCopy: async () => {
@@ -247,26 +291,26 @@ var ChoiceGroup = ({
247
291
  ]
248
292
  }
249
293
  ),
250
- /* @__PURE__ */ jsx3("div", { ref: bodyRef, className: "h-full flex-1 bg-base-200! [&>*:first-child]:mt-0 [&>*:last-child]:mb-0", children: /* @__PURE__ */ jsx3(CodeBlockGroupProvider, { value: true, children: activeChoiceElement.props.children }) })
294
+ /* @__PURE__ */ jsx4("div", { ref: bodyRef, className: "h-full flex-1 bg-base-200! [&>*:first-child]:mt-0 [&>*:last-child]:mb-0", children: /* @__PURE__ */ jsx4(CodeBlockGroupProvider, { value: true, children: activeChoiceElement.props.children }) })
251
295
  ]
252
296
  }
253
297
  );
254
298
  };
255
299
 
256
300
  // src/mdx/code-blocks/CodeBlockTransformer.tsx
257
- import { jsx as jsx4 } from "react/jsx-runtime";
301
+ import { jsx as jsx5 } from "react/jsx-runtime";
258
302
  var CodeBlockTransformer = ({ children, lineBreak }) => {
259
303
  const className = `with-line-break_${lineBreak}`;
260
- return /* @__PURE__ */ jsx4("div", { className, children });
304
+ return /* @__PURE__ */ jsx5("div", { className, children });
261
305
  };
262
306
 
263
307
  // src/mdx/code-blocks/FileState.tsx
264
- import { jsx as jsx5 } from "react/jsx-runtime";
308
+ import { jsx as jsx6 } from "react/jsx-runtime";
265
309
  var FileAdded = ({ children }) => {
266
- return /* @__PURE__ */ jsx5("div", { className: "doc-code-file-state doc-code-file-added", children });
310
+ return /* @__PURE__ */ jsx6("div", { className: "doc-code-file-state doc-code-file-added", children });
267
311
  };
268
312
  var FileRemoved = ({ children }) => {
269
- return /* @__PURE__ */ jsx5("div", { className: "doc-code-file-state doc-code-file-removed", children });
313
+ return /* @__PURE__ */ jsx6("div", { className: "doc-code-file-state doc-code-file-removed", children });
270
314
  };
271
315
 
272
316
  // src/mdx/code-blocks/Pre.tsx
@@ -276,7 +320,7 @@ import {
276
320
  isValidElement as isValidElement2,
277
321
  useRef as useRef3
278
322
  } from "react";
279
- import { jsx as jsx6, jsxs as jsxs3 } from "react/jsx-runtime";
323
+ import { jsx as jsx7, jsxs as jsxs4 } from "react/jsx-runtime";
280
324
  var asTrimmedString2 = (value) => {
281
325
  return typeof value === "string" && value.trim() ? value.trim() : null;
282
326
  };
@@ -306,9 +350,10 @@ var Pre = ({ children, className, ...props }) => {
306
350
  const preRef = useRef3(null);
307
351
  const isInChoiceGroup = useIsInCodeBlockGroup();
308
352
  const label = asTrimmedString2(props["data-code-title"]) ?? getLanguageLabel(props);
353
+ const env = asTrimmedString2(props["data-code-env"]);
309
354
  const fileState = props["file-added"] ? "added" : props["file-removed"] ? "removed" : null;
310
355
  const hideMenu = props["hide-menu"] === "true";
311
- const copyButton = hideMenu || isInChoiceGroup ? null : /* @__PURE__ */ jsx6(
356
+ const copyButton = hideMenu || isInChoiceGroup ? null : /* @__PURE__ */ jsx7(
312
357
  CodeBlockCopyButton,
313
358
  {
314
359
  onCopy: async () => {
@@ -322,29 +367,29 @@ var Pre = ({ children, className, ...props }) => {
322
367
  }
323
368
  }
324
369
  );
325
- return /* @__PURE__ */ jsxs3(
370
+ return /* @__PURE__ */ jsxs4(
326
371
  "div",
327
372
  {
328
373
  className: cmMerge3(
329
374
  "group relative h-full not-prose overflow-hidden",
330
- isInChoiceGroup ? "" : "mb-6 rounded-box border border-base-muted-light bg-base-100/60",
375
+ isInChoiceGroup ? "" : "mb-6 rounded-box border border-base-muted-light",
331
376
  className
332
377
  ),
333
378
  "data-code-block-frame": "",
334
379
  "data-file-state": fileState ?? void 0,
335
380
  children: [
336
- !isInChoiceGroup && /* @__PURE__ */ jsxs3(
381
+ !isInChoiceGroup && /* @__PURE__ */ jsxs4(
337
382
  "div",
338
383
  {
339
- className: "flex min-h-10 items-center justify-between gap-3 border-b border-base-muted-light bg-base-muted-superlight! px-4",
384
+ className: "flex min-h-10 relative items-center justify-between gap-3 border-b border-base-muted-light bg-base-muted-superlight! px-4",
340
385
  "data-code-block-header": "",
341
386
  children: [
342
- /* @__PURE__ */ jsx6("div", { className: "font-mono text-xs font-semibold tracking-[0.08em] text-base-muted", children: label }),
387
+ /* @__PURE__ */ jsx7(CodeBlockHeaderMeta, { label, env }),
343
388
  copyButton
344
389
  ]
345
390
  }
346
391
  ),
347
- /* @__PURE__ */ jsx6(
392
+ /* @__PURE__ */ jsx7(
348
393
  "pre",
349
394
  {
350
395
  ...props,
@@ -361,7 +406,7 @@ var Pre = ({ children, className, ...props }) => {
361
406
 
362
407
  // src/mdx/components/Link.tsx
363
408
  import { cmMerge as cmMerge4 } from "@classmatejs/react";
364
- import { Fragment as Fragment3, jsx as jsx7, jsxs as jsxs4 } from "react/jsx-runtime";
409
+ import { Fragment as Fragment3, jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
365
410
  function assertUsage(condition, message) {
366
411
  if (!condition) {
367
412
  throw new Error(`[UniversalMdxMods][Wrong Usage] ${message}`);
@@ -396,8 +441,8 @@ var parseMarkdownMini = (markdown) => {
396
441
  if (current) {
397
442
  parts.push(current);
398
443
  }
399
- return /* @__PURE__ */ jsx7(Fragment3, { children: parts.map(
400
- (part, index) => part.nodeType === "code" ? /* @__PURE__ */ jsx7("code", { children: part.content }, index) : /* @__PURE__ */ jsx7("span", { children: part.content }, index)
444
+ return /* @__PURE__ */ jsx8(Fragment3, { children: parts.map(
445
+ (part, index) => part.nodeType === "code" ? /* @__PURE__ */ jsx8("code", { children: part.content }, index) : /* @__PURE__ */ jsx8("span", { children: part.content }, index)
401
446
  ) });
402
447
  };
403
448
  var determineSectionTitle = (href) => {
@@ -433,7 +478,7 @@ var getLinkText = ({
433
478
  if (noBreadcrumb || isCurrentPage) {
434
479
  return breadcrumbParts[breadcrumbParts.length - 1] ?? null;
435
480
  }
436
- return /* @__PURE__ */ jsx7(Fragment3, { children: breadcrumbParts.map((part, index) => /* @__PURE__ */ jsxs4("span", { children: [
481
+ return /* @__PURE__ */ jsx8(Fragment3, { children: breadcrumbParts.map((part, index) => /* @__PURE__ */ jsxs5("span", { children: [
437
482
  index > 0 ? " > " : null,
438
483
  part
439
484
  ] }, index)) });
@@ -451,7 +496,7 @@ var Link = ({
451
496
  const runtime = useUniversalMdxRuntime();
452
497
  if (typeof href !== "string" || href === "") {
453
498
  assertWarning(false, "<Link /> is missing `href`.");
454
- return /* @__PURE__ */ jsx7("a", { className: cmMerge4(className, "inline-flex gap-1 items-center"), ...props, children: text ?? children ?? "LINK-TARGET-NOT-FOUND" });
499
+ return /* @__PURE__ */ jsx8("a", { className: cmMerge4(className, "inline-flex gap-1 items-center"), ...props, children: text ?? children ?? "LINK-TARGET-NOT-FOUND" });
455
500
  }
456
501
  assertUsage(
457
502
  href.startsWith("/") || href.startsWith("#") || isExternalHref(href),
@@ -473,11 +518,11 @@ var Link = ({
473
518
  sectionTitle: inferredSectionTitle ?? void 0,
474
519
  title: resolvedDocLink.title
475
520
  }) : isExternalHref(href) ? href : inferredSectionTitle ?? "LINK-TARGET-NOT-FOUND");
476
- return /* @__PURE__ */ jsx7("a", { href: localizedHref, className: cmMerge4(className, ""), ...props, children: inferredText });
521
+ return /* @__PURE__ */ jsx8("a", { href: localizedHref, className: cmMerge4(className, ""), ...props, children: inferredText });
477
522
  };
478
523
 
479
524
  // src/mdx/components/Overview.tsx
480
- import { jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
525
+ import { jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
481
526
  import { createElement } from "react";
482
527
  var isOverviewDividerItem = (item) => typeof item === "object" && item !== null && "dividerText" in item;
483
528
  function assertUsage2(condition, message) {
@@ -510,14 +555,14 @@ var groupOverviewItems = (items) => {
510
555
  return groups;
511
556
  };
512
557
  var OverviewCard = ({ excerpt, href, title }) => {
513
- return /* @__PURE__ */ jsxs5(
558
+ return /* @__PURE__ */ jsxs6(
514
559
  "a",
515
560
  {
516
561
  href: withSiteBaseUrl(href),
517
562
  className: "group flex h-full flex-col gap-3 rounded-box border border-base-muted-light bg-base-muted-superlight p-5 no-underline hover:border-primary-muted-medium hover:bg-base-muted-superlight/50",
518
563
  children: [
519
- /* @__PURE__ */ jsx8("h3", { className: "text-lg font-semibold text-base-content", children: renderInlineMarkdown(title) }),
520
- excerpt ? /* @__PURE__ */ jsx8("p", { className: "text-sm leading-relaxed text-base-muted", children: renderInlineMarkdown(excerpt) }) : null
564
+ /* @__PURE__ */ jsx9("h3", { className: "text-lg font-semibold text-base-content", children: renderInlineMarkdown(title) }),
565
+ excerpt ? /* @__PURE__ */ jsx9("p", { className: "text-sm leading-relaxed text-base-muted", children: renderInlineMarkdown(excerpt) }) : null
521
566
  ]
522
567
  }
523
568
  );
@@ -541,37 +586,37 @@ var Overview = ({ items }) => {
541
586
  if (groups.length === 0) {
542
587
  return null;
543
588
  }
544
- return /* @__PURE__ */ jsx8("div", { className: "prose-headings:my-0 prose-p:my-0 my-5 flex flex-col gap-8", children: groups.map((group, groupIndex) => /* @__PURE__ */ jsxs5("section", { className: "flex flex-col gap-4", children: [
545
- group.dividerText ? /* @__PURE__ */ jsx8("p", { className: "text-sm font-semibold uppercase tracking-wide", children: renderInlineMarkdown(group.dividerText) }) : null,
546
- /* @__PURE__ */ jsx8("div", { className: "grid gap-4 sm:grid-cols-2", children: group.items.map((item, itemIndex) => /* @__PURE__ */ createElement(OverviewCard, { ...item, key: item.href || itemIndex })) })
589
+ return /* @__PURE__ */ jsx9("div", { className: "prose-headings:my-0 prose-p:my-0 my-5 flex flex-col gap-8", children: groups.map((group, groupIndex) => /* @__PURE__ */ jsxs6("section", { className: "flex flex-col gap-4", children: [
590
+ group.dividerText ? /* @__PURE__ */ jsx9("p", { className: "text-sm font-semibold uppercase tracking-wide", children: renderInlineMarkdown(group.dividerText) }) : null,
591
+ /* @__PURE__ */ jsx9("div", { className: "grid gap-4 sm:grid-cols-2", children: group.items.map((item, itemIndex) => /* @__PURE__ */ createElement(OverviewCard, { ...item, key: item.href || itemIndex })) })
547
592
  ] }, groupIndex)) });
548
593
  };
549
594
 
550
595
  // src/mdx/components/RepoLink.tsx
551
- import { jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
596
+ import { jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
552
597
  var RepoLink = ({ repo, timestamp }) => {
553
598
  if (!repo || repo.split("/").length !== 2) {
554
599
  throw new Error("Invalid repo");
555
600
  }
556
- return /* @__PURE__ */ jsxs6("span", { className: "inline-flex items-center gap-1", children: [
557
- /* @__PURE__ */ jsx9("span", { className: "bg-white font-mono font-bold h-fit px-1 text-sm!", children: timestamp }),
558
- /* @__PURE__ */ jsxs6("a", { href: `https://github.com/${repo}`, target: "_blank", rel: "noopener", children: [
601
+ return /* @__PURE__ */ jsxs7("span", { className: "inline-flex items-center gap-1", children: [
602
+ /* @__PURE__ */ jsx10("span", { className: "bg-white font-mono font-bold h-fit px-1 text-sm!", children: timestamp }),
603
+ /* @__PURE__ */ jsxs7("a", { href: `https://github.com/${repo}`, target: "_blank", rel: "noopener", children: [
559
604
  "GitHub > ",
560
- /* @__PURE__ */ jsx9("code", { children: repo })
605
+ /* @__PURE__ */ jsx10("code", { children: repo })
561
606
  ] })
562
607
  ] });
563
608
  };
564
609
 
565
610
  // src/mdx/components/Table.tsx
566
- import cm2 from "@classmatejs/react";
567
- import { jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
611
+ import cm3 from "@classmatejs/react";
612
+ import { jsx as jsx11, jsxs as jsxs8 } from "react/jsx-runtime";
568
613
  var Table = ({ size = "md", data }) => {
569
- return /* @__PURE__ */ jsxs7(StyledTable, { $size: size, children: [
570
- /* @__PURE__ */ jsx10("thead", { className: "overflow-hidden rounded-t-box bg-base-200", children: /* @__PURE__ */ jsx10("tr", { children: data.headers.map((header, index) => /* @__PURE__ */ jsx10("th", { children: header }, index)) }) }),
571
- /* @__PURE__ */ jsx10("tbody", { children: data.rows.map((row, rowIndex) => /* @__PURE__ */ jsx10("tr", { children: row.map((cell, cellIndex) => /* @__PURE__ */ jsx10("td", { children: cell }, cellIndex)) }, rowIndex)) })
614
+ return /* @__PURE__ */ jsxs8(StyledTable, { $size: size, children: [
615
+ /* @__PURE__ */ jsx11("thead", { className: "overflow-hidden rounded-t-box bg-base-200", children: /* @__PURE__ */ jsx11("tr", { children: data.headers.map((header, index) => /* @__PURE__ */ jsx11("th", { children: header }, index)) }) }),
616
+ /* @__PURE__ */ jsx11("tbody", { children: data.rows.map((row, rowIndex) => /* @__PURE__ */ jsx11("tr", { children: row.map((cell, cellIndex) => /* @__PURE__ */ jsx11("td", { children: cell }, cellIndex)) }, rowIndex)) })
572
617
  ] });
573
618
  };
574
- var StyledTable = cm2.table.variants({
619
+ var StyledTable = cm3.table.variants({
575
620
  base: `
576
621
  not-prose
577
622
  table
@@ -603,4 +648,4 @@ export {
603
648
  RepoLink,
604
649
  Table
605
650
  };
606
- //# sourceMappingURL=chunk-G37565OX.js.map
651
+ //# sourceMappingURL=chunk-FARXFRHG.js.map