jamdesk 1.1.30 → 1.1.31

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jamdesk",
3
- "version": "1.1.30",
3
+ "version": "1.1.31",
4
4
  "description": "CLI for Jamdesk — build, preview, and deploy documentation sites from MDX. Dev server with hot reload, 50+ components, OpenAPI support, AI search, and Mintlify migration",
5
5
  "keywords": [
6
6
  "jamdesk",
@@ -192,6 +192,10 @@ function findFirstPage(config: DocsConfig, lang?: string): string {
192
192
  return result ? result.replace(/^\//, '') : 'introduction';
193
193
  }
194
194
 
195
+ function needsSlugRewrite(slug: string[]): boolean {
196
+ return slug.length === 0 || (slug.length === 1 && isValidLanguageCode(slug[0]));
197
+ }
198
+
195
199
  function resolveSlug(normalizedSlug: string[], config: DocsConfig): string[] {
196
200
  if (normalizedSlug.length === 0) return pathToSlug(findFirstPage(config));
197
201
  if (normalizedSlug.length === 1 && isValidLanguageCode(normalizedSlug[0])) {
@@ -264,12 +268,17 @@ export async function generateMetadata({ params }: PageProps) {
264
268
  // Normalize slug: strip /docs prefix when hostAtDocs=true.
265
269
  // Empty root → resolve to first page (see DocPage for the full rationale).
266
270
  const normalizedSlug = normalizeSlugForContent(resolvedParams.slug || [], hostAtDocs);
267
- const config = await loader.getConfig();
268
- const slug = resolveSlug(normalizedSlug, config);
271
+ const configP = loader.getConfig();
272
+ const slug = needsSlugRewrite(normalizedSlug)
273
+ ? resolveSlug(normalizedSlug, await configP)
274
+ : normalizedSlug;
269
275
  const isRoot = normalizedSlug.length === 0;
270
276
  const pagePath = slug.join('/');
271
277
 
272
- const fileContents = await loader.getContent(pagePath).catch(() => null);
278
+ const [fileContents, config] = await Promise.all([
279
+ loader.getContent(pagePath).catch(() => null),
280
+ configP,
281
+ ]);
273
282
 
274
283
  if (!fileContents) {
275
284
  return {
@@ -345,11 +354,16 @@ export default async function DocPage({ params }: PageProps) {
345
354
  // redirect() emits cache-control: private, blocking CDN caching. Canonical
346
355
  // + noindex in generateMetadata prevent duplicate indexing.
347
356
  const normalizedSlug = normalizeSlugForContent(resolvedParams.slug || [], hostAtDocs);
348
- const config = await loader.getConfig();
349
- const slug = resolveSlug(normalizedSlug, config);
357
+ const configP = loader.getConfig();
358
+ const slug = needsSlugRewrite(normalizedSlug)
359
+ ? resolveSlug(normalizedSlug, await configP)
360
+ : normalizedSlug;
350
361
  const pagePath = slug.join('/');
351
362
  const currentLang = extractLanguageFromPath(`/${pagePath}`);
352
- const fileContents = await loader.getContent(pagePath).catch(() => null);
363
+ const [fileContents, config] = await Promise.all([
364
+ loader.getContent(pagePath).catch(() => null),
365
+ configP,
366
+ ]);
353
367
 
354
368
  // Check if content exists (getContent returns null via catch if not found)
355
369
  if (!fileContents) {
@@ -24,8 +24,7 @@ const ZH: Partial<UiStrings> = {
24
24
  selectLanguage: '选择语言',
25
25
  };
26
26
 
27
- const STRINGS: Partial<Record<LanguageCode, Partial<UiStrings>>> = {
28
- en: EN,
27
+ const OVERRIDES: Partial<Record<LanguageCode, Partial<UiStrings>>> = {
29
28
  fr: {
30
29
  search: 'Rechercher',
31
30
  askAi: "Demander à l'IA",
@@ -44,9 +43,12 @@ const STRINGS: Partial<Record<LanguageCode, Partial<UiStrings>>> = {
44
43
  cn: ZH,
45
44
  };
46
45
 
46
+ // Pre-merge so repeated calls return a stable object reference.
47
+ const MERGED: Partial<Record<LanguageCode, UiStrings>> = {};
48
+ for (const [code, overrides] of Object.entries(OVERRIDES) as [LanguageCode, Partial<UiStrings>][]) {
49
+ MERGED[code] = { ...EN, ...overrides };
50
+ }
51
+
47
52
  export function getUiStrings(lang: LanguageCode | undefined): UiStrings {
48
- if (!lang) return EN;
49
- const overrides = STRINGS[lang];
50
- if (!overrides) return EN;
51
- return { ...EN, ...overrides };
53
+ return (lang && MERGED[lang]) || EN;
52
54
  }
@@ -782,19 +782,19 @@ body[data-theme="jam"] .prose video {
782
782
  /* Phase 2: Touch Targets for Sidebar */
783
783
  @media (max-width: 1023px) {
784
784
  :root {
785
- --sidebar-item-spacing: 6px;
785
+ --sidebar-item-spacing: 3px;
786
786
  }
787
787
 
788
788
  .sidebar-scroll ul li a {
789
- padding-top: 10px !important;
790
- padding-bottom: 10px !important;
791
- min-height: 44px;
789
+ padding-top: 7px !important;
790
+ padding-bottom: 7px !important;
791
+ min-height: 36px;
792
792
  }
793
793
 
794
794
  .sidebar-scroll .nav-group-l1 {
795
- padding-top: 10px !important;
796
- padding-bottom: 10px !important;
797
- min-height: 44px;
795
+ padding-top: 7px !important;
796
+ padding-bottom: 7px !important;
797
+ min-height: 36px;
798
798
  }
799
799
  }
800
800
 
@@ -141,19 +141,19 @@
141
141
  /* Phase 2: Touch Targets for Sidebar */
142
142
  @media (max-width: 1023px) {
143
143
  :root {
144
- --sidebar-item-spacing: 6px;
144
+ --sidebar-item-spacing: 3px;
145
145
  }
146
146
 
147
147
  .sidebar-scroll ul li a {
148
- padding-top: 10px !important;
149
- padding-bottom: 10px !important;
150
- min-height: 44px;
148
+ padding-top: 7px !important;
149
+ padding-bottom: 7px !important;
150
+ min-height: 36px;
151
151
  }
152
152
 
153
153
  .sidebar-scroll .nav-group-l1 {
154
- padding-top: 10px !important;
155
- padding-bottom: 10px !important;
156
- min-height: 44px;
154
+ padding-top: 7px !important;
155
+ padding-bottom: 7px !important;
156
+ min-height: 36px;
157
157
  }
158
158
  }
159
159
 
@@ -896,19 +896,19 @@ body[data-theme="pulsar"] header [data-theme-toggle] {
896
896
  /* Phase 3: Touch Targets for Sidebar */
897
897
  @media (max-width: 1023px) {
898
898
  :root {
899
- --sidebar-item-spacing: 6px;
899
+ --sidebar-item-spacing: 3px;
900
900
  }
901
901
 
902
902
  .sidebar-scroll ul li a {
903
- padding-top: 10px !important;
904
- padding-bottom: 10px !important;
905
- min-height: 44px;
903
+ padding-top: 7px !important;
904
+ padding-bottom: 7px !important;
905
+ min-height: 36px;
906
906
  }
907
907
 
908
908
  .sidebar-scroll .nav-group-l1 {
909
- padding-top: 10px !important;
910
- padding-bottom: 10px !important;
911
- min-height: 44px;
909
+ padding-top: 7px !important;
910
+ padding-bottom: 7px !important;
911
+ min-height: 36px;
912
912
  }
913
913
  }
914
914