jamdesk 1.1.90 → 1.1.91

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 (46) hide show
  1. package/package.json +1 -1
  2. package/vendored/app/api/r2/[project]/[...path]/route.ts +14 -9
  3. package/vendored/app/layout.tsx +2 -2
  4. package/vendored/components/HtmlLangSync.tsx +3 -2
  5. package/vendored/components/mdx/Accordion.tsx +1 -1
  6. package/vendored/components/mdx/Card.tsx +1 -1
  7. package/vendored/components/mdx/CodeGroup.tsx +18 -23
  8. package/vendored/components/mdx/Color.tsx +0 -1
  9. package/vendored/components/mdx/Icon.tsx +1 -1
  10. package/vendored/components/mdx/MDXComponents.tsx +92 -66
  11. package/vendored/components/mdx/OpenApiEndpoint.tsx +0 -1
  12. package/vendored/components/mdx/ParamField.tsx +0 -1
  13. package/vendored/components/mdx/RequestExample.tsx +0 -1
  14. package/vendored/components/mdx/ResponseExample.tsx +0 -1
  15. package/vendored/components/mdx/Steps.tsx +12 -3
  16. package/vendored/components/mdx/Table.tsx +8 -2
  17. package/vendored/components/mdx/Tabs.tsx +1 -1
  18. package/vendored/components/mdx/Tree.tsx +6 -4
  19. package/vendored/components/navigation/Header.tsx +7 -5
  20. package/vendored/components/navigation/LanguageSelector.tsx +32 -7
  21. package/vendored/components/navigation/TableOfContents.tsx +1 -1
  22. package/vendored/components/navigation/TabsNav.tsx +17 -5
  23. package/vendored/components/search/SearchModal.tsx +41 -36
  24. package/vendored/components/ui/CodePanel.tsx +2 -2
  25. package/vendored/hooks/useChat.ts +1 -1
  26. package/vendored/hooks/useShikiHighlight.ts +7 -1
  27. package/vendored/lib/code-utils.ts +6 -2
  28. package/vendored/lib/health-checks.ts +2 -2
  29. package/vendored/lib/language-utils.ts +53 -2
  30. package/vendored/lib/layout-helpers.tsx +2 -1
  31. package/vendored/lib/mdx-inline-components.ts +1 -1
  32. package/vendored/lib/navigation-resolver.ts +0 -69
  33. package/vendored/lib/normalize-config.ts +1 -1
  34. package/vendored/lib/openapi/generator.ts +3 -3
  35. package/vendored/lib/openapi/parser.ts +14 -6
  36. package/vendored/lib/openapi/validator.ts +2 -2
  37. package/vendored/lib/openapi-isr.ts +4 -1
  38. package/vendored/lib/public-paths-resolver.ts +7 -6
  39. package/vendored/lib/redis.ts +2 -2
  40. package/vendored/lib/rehype-code-meta.ts +2 -2
  41. package/vendored/lib/render-doc-page.tsx +2 -2
  42. package/vendored/lib/seo.ts +21 -6
  43. package/vendored/lib/shiki-highlighter.ts +1 -1
  44. package/vendored/lib/snippet-loader-isr.ts +1 -1
  45. package/vendored/lib/validate-config.ts +1 -0
  46. package/vendored/workspace-package-lock.json +10 -10
@@ -22,10 +22,11 @@ function collectPublicGroupPages(
22
22
  if (!nav || typeof nav !== 'object') return out;
23
23
 
24
24
  const node = nav as Record<string, unknown>;
25
+ const pages = node.pages;
25
26
 
26
- if ('group' in node && Array.isArray((node as any).pages)) {
27
+ if ('group' in node && Array.isArray(pages)) {
27
28
  const isPublic = inPublicGroup || node.public === true;
28
- for (const p of (node as any).pages) {
29
+ for (const p of pages) {
29
30
  if (typeof p === 'string') {
30
31
  if (isPublic) out.push(`/${p}`);
31
32
  } else {
@@ -35,14 +36,14 @@ function collectPublicGroupPages(
35
36
  return out;
36
37
  }
37
38
 
38
- if (Array.isArray((node as any).pages)) {
39
- for (const p of (node as any).pages) {
39
+ if (Array.isArray(pages)) {
40
+ for (const p of pages) {
40
41
  collectPublicGroupPages(p, inPublicGroup, out);
41
42
  }
42
43
  }
43
44
 
44
45
  for (const key of ['groups', 'tabs', 'anchors', 'versions', 'languages']) {
45
- const arr = (node as any)[key];
46
+ const arr = node[key];
46
47
  if (Array.isArray(arr)) {
47
48
  for (const item of arr) {
48
49
  collectPublicGroupPages(item, inPublicGroup, out);
@@ -72,7 +73,7 @@ export function resolvePublicPaths(input: Input): string[] {
72
73
  set.add(path);
73
74
  }
74
75
 
75
- const globs = (input.docsConfig as any).auth?.password?.public;
76
+ const globs = input.docsConfig.auth?.password?.public;
76
77
  if (Array.isArray(globs)) {
77
78
  for (const g of globs) {
78
79
  if (typeof g === 'string' && g.startsWith('/')) {
@@ -44,9 +44,9 @@ async function upstashCommand(
44
44
  headers: { Authorization: `Bearer ${kvToken}` },
45
45
  });
46
46
  const bodyText = await response.text();
47
- let data: any = null;
47
+ let data: { error?: string; result?: unknown } | null = null;
48
48
  try {
49
- data = bodyText ? JSON.parse(bodyText) : null;
49
+ data = bodyText ? (JSON.parse(bodyText) as { error?: string; result?: unknown }) : null;
50
50
  } catch {
51
51
  data = { result: bodyText };
52
52
  }
@@ -154,7 +154,7 @@ export function rehypeCodeMeta() {
154
154
 
155
155
  // Store parsed data in node.data so Shiki transformers can access it
156
156
  node.data = node.data || {};
157
- (node.data as any).parsedMeta = parsed;
157
+ (node.data as { parsedMeta?: unknown }).parsedMeta = parsed;
158
158
 
159
159
  if (parsed.icon) {
160
160
  node.properties['data-icon'] = parsed.icon;
@@ -182,7 +182,7 @@ export function rehypeCodeMeta() {
182
182
  preNode.properties['data-title'] = parsed.title;
183
183
  // Store in parent data as well
184
184
  preNode.data = preNode.data || {};
185
- (preNode.data as any).parsedTitle = parsed.title;
185
+ (preNode.data as { parsedTitle?: string }).parsedTitle = parsed.title;
186
186
  }
187
187
  }
188
188
  });
@@ -13,7 +13,7 @@
13
13
  import { notFound } from 'next/navigation';
14
14
  import { MDXRemote } from 'next-mdx-remote/rsc';
15
15
  import type { Metadata } from 'next';
16
- import type { ReactElement } from 'react';
16
+ import type { AnchorHTMLAttributes, ReactElement } from 'react';
17
17
  import { MDXComponents } from '@/components/mdx/MDXComponents';
18
18
  import { Breadcrumb } from '@/components/navigation/Breadcrumb';
19
19
  import { TableOfContents } from '@/components/navigation/TableOfContents';
@@ -360,7 +360,7 @@ export async function renderDocPage(input: RenderInput): Promise<ReactElement> {
360
360
  ...snippetAliases,
361
361
  ...inlineComponents,
362
362
  ...(hostAtDocs ? {
363
- a: ({ ariaLabel, href, ...props }: any) => {
363
+ a: ({ ariaLabel, href, ...props }: AnchorHTMLAttributes<HTMLAnchorElement> & { ariaLabel?: string }) => {
364
364
  const needsPrefix = href?.startsWith('/') && !href.startsWith('/docs/') && href !== '/docs';
365
365
  return (
366
366
  <a
@@ -8,9 +8,14 @@
8
8
  */
9
9
 
10
10
  import type { Metadata } from 'next';
11
- import type { DocsConfig, Logo, LogoConfig, Favicon, FaviconConfig, LanguageConfig, LanguageCode } from './docs-types';
11
+ import type { DocsConfig, Logo, LogoConfig, Favicon, LanguageConfig, LanguageCode } from './docs-types';
12
12
  import { transformConfigImagePath } from './docs-types';
13
- import { transformLanguagePath, extractLanguageFromPath, isValidLanguageCode } from './language-utils';
13
+ import { findHreflangAliasCollisions, transformLanguagePath, toHreflang } from './language-utils';
14
+ import { logger } from '../shared/logger';
15
+
16
+ // Dedupe per-process: same docs.json shape produces the same collision
17
+ // signature on every page render, so we'd otherwise spam logs.
18
+ const warnedCollisionSignatures = new Set<string>();
14
19
 
15
20
  const HAS_DOCS_SUFFIX = /\b(?:Documentation|Docs)\s*$/i;
16
21
 
@@ -197,14 +202,12 @@ function buildHreflangAlternates(
197
202
  const defaultLang = languages.find((l) => l.default)?.language || languages[0]?.language || 'en';
198
203
 
199
204
  // Detect current language from path
200
- const currentLang = extractLanguageFromPath(pagePath) || defaultLang;
201
-
202
205
  // Keep only languages whose navigation declares this page — capturing the
203
206
  // language-relative path so the build loop and x-default branch don't have
204
207
  // to recompute it via transformLanguagePath.
205
208
  const supported: Array<{ lang: LanguageCode; cleanPath: string }> = [];
206
209
  for (const langConfig of languages) {
207
- const langPath = transformLanguagePath(pagePath, currentLang, langConfig.language, defaultLang);
210
+ const langPath = transformLanguagePath(pagePath, langConfig.language, defaultLang);
208
211
  const cleanPath = langPath.replace(/^\//, '');
209
212
  if (getLanguagePagePaths(langConfig).has(cleanPath)) {
210
213
  supported.push({ lang: langConfig.language, cleanPath });
@@ -217,9 +220,21 @@ function buildHreflangAlternates(
217
220
  return undefined;
218
221
  }
219
222
 
223
+ const collisions = findHreflangAliasCollisions(supported.map((s) => s.lang));
224
+ for (const { tag, codes } of collisions) {
225
+ const signature = `${tag}:${codes.join(',')}`;
226
+ if (warnedCollisionSignatures.has(signature)) continue;
227
+ warnedCollisionSignatures.add(signature);
228
+ logger.warn('hreflang alias collision — last entry wins, earlier translations dropped', {
229
+ bcp47Tag: tag,
230
+ internalCodes: codes,
231
+ remedy: 'Remove one of the duplicate entries from navigation.languages in docs.json',
232
+ });
233
+ }
234
+
220
235
  const alternates: Record<string, string> = {};
221
236
  for (const { lang, cleanPath } of supported) {
222
- alternates[lang] = cleanPath ? `${baseUrl}/${cleanPath}` : baseUrl;
237
+ alternates[toHreflang(lang)] = cleanPath ? `${baseUrl}/${cleanPath}` : baseUrl;
223
238
  }
224
239
 
225
240
  // x-default points to the default language only when it has the page; absence
@@ -8,7 +8,7 @@ import { PRELOADED_LANGUAGES, SUPPORTED_THEMES, type SupportedTheme } from './sh
8
8
 
9
9
  // Extend globalThis type for highlighter caching
10
10
  declare global {
11
- // eslint-disable-next-line no-var
11
+
12
12
  var __shikiHighlighterPromise: Promise<Highlighter> | undefined;
13
13
  }
14
14
 
@@ -322,7 +322,7 @@ async function compileSnippet(
322
322
  try {
323
323
  // Create function that returns the component
324
324
  // NOTE: new Function() is intentionally used here to compile user-provided snippets
325
- // eslint-disable-next-line @typescript-eslint/no-implied-eval
325
+
326
326
  const createComponent = new Function(
327
327
  'React',
328
328
  '_jsx',
@@ -12,6 +12,7 @@
12
12
  import AjvModule, { ErrorObject } from 'ajv';
13
13
  import addFormatsModule from 'ajv-formats';
14
14
  // ESM compatibility - ajv-formats exports differently under NodeNext resolution
15
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- ajv-formats ESM/CJS interop default-export shape varies by bundler
15
16
  const addFormats = (addFormatsModule as any).default || addFormatsModule;
16
17
  // ESM compatibility - Ajv exports differently in Node.js ESM
17
18
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -1921,12 +1921,12 @@
1921
1921
  }
1922
1922
  },
1923
1923
  "node_modules/@types/node": {
1924
- "version": "25.7.0",
1925
- "resolved": "https://registry.npmjs.org/@types/node/-/node-25.7.0.tgz",
1926
- "integrity": "sha512-z+pdZyxE+RTQE9AcboAZCb4otwcrvgHD+GlBpPgn0emDVt0ohrTMhAwlr2Wd9nZ+nihhYFxO2pThz3C5qSu2Eg==",
1924
+ "version": "25.8.0",
1925
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-25.8.0.tgz",
1926
+ "integrity": "sha512-TCFSk8IZh+iLX1xtksoBVtdmgL+1IX0fC9BeU4QqFSuNdN/K+HUlhqOzEmSYYpZUVsLYcPqc9KX+60iDuninSQ==",
1927
1927
  "license": "MIT",
1928
1928
  "dependencies": {
1929
- "undici-types": "~7.21.0"
1929
+ "undici-types": ">=7.24.0 <7.24.7"
1930
1930
  }
1931
1931
  },
1932
1932
  "node_modules/@types/react": {
@@ -2928,9 +2928,9 @@
2928
2928
  "license": "MIT"
2929
2929
  },
2930
2930
  "node_modules/electron-to-chromium": {
2931
- "version": "1.5.354",
2932
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.354.tgz",
2933
- "integrity": "sha512-JaBHwWcfIdmSAfWM5l3uwjGd431j8YEMikZ+K/2nXVuBqJKyZ0f+2h4n4JY5AyNiZmnY9qQr2RU3v9DxDmHMNg==",
2931
+ "version": "1.5.355",
2932
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.355.tgz",
2933
+ "integrity": "sha512-LUPZhKzZPYSPme1jEYohpkA+ybYCJztr1quAdBd7E7h3+VOBVcKkwwtBJu41nrjawrRzfb8mtMfzWozoaK0ZIQ==",
2934
2934
  "license": "ISC"
2935
2935
  },
2936
2936
  "node_modules/enhanced-resolve": {
@@ -6279,9 +6279,9 @@
6279
6279
  "license": "MIT"
6280
6280
  },
6281
6281
  "node_modules/undici-types": {
6282
- "version": "7.21.0",
6283
- "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.21.0.tgz",
6284
- "integrity": "sha512-w9IMgQrz4O0YN1LtB7K5P63vhlIOvC7opSmouCJ+ZywlPAlO9gIkJ+otk6LvGpAs2wg4econaCz3TvQ9xPoyuQ==",
6282
+ "version": "7.24.6",
6283
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.24.6.tgz",
6284
+ "integrity": "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==",
6285
6285
  "license": "MIT"
6286
6286
  },
6287
6287
  "node_modules/unified": {