jamdesk 1.1.197 → 1.1.199

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.
@@ -1 +1 @@
1
- {"version":3,"file":"frontmatter-utils.d.ts","sourceRoot":"","sources":["../../src/lib/frontmatter-utils.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAkE7D;AAmED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG;IAExD,IAAI,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,CAAC;IAC7B,OAAO,EAAE,MAAM,CAAC;CACjB,CAIA;AAMD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC"}
1
+ {"version":3,"file":"frontmatter-utils.d.ts","sourceRoot":"","sources":["../../src/lib/frontmatter-utils.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAkE7D;AAyFD;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG;IAExD,IAAI,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,CAAC;IAC7B,OAAO,EAAE,MAAM,CAAC;CACjB,CAoBA;AAMD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC"}
@@ -107,7 +107,8 @@ function markContinuationLines(lines) {
107
107
  continue;
108
108
  const [, indent, , value] = match;
109
109
  // A block scalar always has a body; a plain value only sometimes wraps.
110
- if (!isBlockScalar(value) && !hasFoldedContinuation(lines, i))
110
+ const block = isBlockScalar(value);
111
+ if (!block && !hasFoldedContinuation(lines, i))
111
112
  continue;
112
113
  for (let j = i + 1; j < lines.length; j++) {
113
114
  // A blank line inside a block scalar is part of it; one at the end is
@@ -118,11 +119,32 @@ function markContinuationLines(lines) {
118
119
  }
119
120
  if (lines[j].search(/\S/) <= indent.length)
120
121
  break;
122
+ // A block body is opaque text to the last line — `see mode: dark` in a
123
+ // `>-` description is prose and must survive verbatim. Outside one, an
124
+ // indented `key: value` really is a nested entry, and swallowing it was
125
+ // a regression: `seo:` has an empty value, which `hasFoldedContinuation`
126
+ // reads as a wrap whenever the child's name holds a `-` or `.` (its
127
+ // sibling test allows neither), so `seo:\n meta-description: A: B` had
128
+ // its colon left unquoted and js-yaml rejected the file — the very bug
129
+ // this function exists to prevent, re-entered through the back door.
130
+ if (!block && isYamlKeyLine(lines[j]))
131
+ break;
121
132
  out[j] = true;
122
133
  }
123
134
  }
124
135
  return out;
125
136
  }
137
+ /**
138
+ * True if YAML itself would read this line as a mapping entry: a colon
139
+ * followed by whitespace or end-of-line. That trailing space is the whole
140
+ * distinction between `meta-description: A guide` (a key) and `Kotlin-SDK:er`
141
+ * (prose), and it is why this cannot reuse `KEY_LINE`, whose `\s*` makes the
142
+ * separator optional. The lazy `.*?` lets a colon-compound key like
143
+ * `og:title: Social` match on its real separator rather than its first colon.
144
+ */
145
+ function isYamlKeyLine(line) {
146
+ return /^\s*[^\s#].*?:(\s|$)/.test(line);
147
+ }
126
148
  /**
127
149
  * True if the value on `lines[i]` continues onto a subsequent indented line
128
150
  * (a YAML folded scalar without an explicit `|` or `>` indicator). The next
@@ -149,7 +171,23 @@ function hasFoldedContinuation(lines, i) {
149
171
  export function parseFrontmatterLenient(content) {
150
172
  const processed = preprocessFrontmatter(content);
151
173
  const { data, content: rawContent } = matter(processed);
152
- return { data, content: rawContent };
174
+ // Copied, never handed out by reference. gray-matter caches by content string
175
+ // and returns Object.assign({}, cached) on a hit — a SHALLOW copy, so `data`
176
+ // is ONE object shared by every parse of the same page, process-wide. A caller
177
+ // that wrote to it changed what every other caller read: a <meta> back-fill in
178
+ // buildDocMetadata surfaced as a duplicated page subtitle on every
179
+ // description-less page (#7). Callers get their own object; the cache stays
180
+ // pristine.
181
+ //
182
+ // Bounded on purpose, and NOT a guarantee that the whole class is closed:
183
+ // this protects TOP-LEVEL keys for callers who come through this function.
184
+ // Nested values (`data.seo`, tag arrays) are still shared by the spread, and
185
+ // three sites call `matter()` directly and bypass this entirely — build.ts,
186
+ // lib/docs.ts's readFrontmatterOnly, lib/api-page-panel-validator.ts. All are
187
+ // read-only today; a future writer through any of them re-opens the hole. A
188
+ // deep clone would cost a full walk on every page view of a force-dynamic
189
+ // route, which is the wrong trade for a leak that was one top-level key.
190
+ return { data: { ...data }, content: rawContent };
153
191
  }
154
192
  // frontmatterText lives in its own import-free leaf so ApiMarkdown.tsx (a
155
193
  // `'use client'` module) can share it without pulling gray-matter into the
@@ -1 +1 @@
1
- {"version":3,"file":"frontmatter-utils.js","sourceRoot":"","sources":["../../src/lib/frontmatter-utils.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"frontmatter-utils.js","sourceRoot":"","sources":["../../src/lib/frontmatter-utils.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jamdesk",
3
- "version": "1.1.197",
3
+ "version": "1.1.199",
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",
@@ -117,18 +117,40 @@ function markContinuationLines(lines: string[]): boolean[] {
117
117
  if (!match) continue;
118
118
  const [, indent, , value] = match;
119
119
  // A block scalar always has a body; a plain value only sometimes wraps.
120
- if (!isBlockScalar(value) && !hasFoldedContinuation(lines, i)) continue;
120
+ const block = isBlockScalar(value);
121
+ if (!block && !hasFoldedContinuation(lines, i)) continue;
121
122
  for (let j = i + 1; j < lines.length; j++) {
122
123
  // A blank line inside a block scalar is part of it; one at the end is
123
124
  // harmless to mark, since the mapper skips blank lines anyway.
124
125
  if (!lines[j].trim()) { out[j] = true; continue; }
125
126
  if (lines[j].search(/\S/) <= indent.length) break;
127
+ // A block body is opaque text to the last line — `see mode: dark` in a
128
+ // `>-` description is prose and must survive verbatim. Outside one, an
129
+ // indented `key: value` really is a nested entry, and swallowing it was
130
+ // a regression: `seo:` has an empty value, which `hasFoldedContinuation`
131
+ // reads as a wrap whenever the child's name holds a `-` or `.` (its
132
+ // sibling test allows neither), so `seo:\n meta-description: A: B` had
133
+ // its colon left unquoted and js-yaml rejected the file — the very bug
134
+ // this function exists to prevent, re-entered through the back door.
135
+ if (!block && isYamlKeyLine(lines[j])) break;
126
136
  out[j] = true;
127
137
  }
128
138
  }
129
139
  return out;
130
140
  }
131
141
 
142
+ /**
143
+ * True if YAML itself would read this line as a mapping entry: a colon
144
+ * followed by whitespace or end-of-line. That trailing space is the whole
145
+ * distinction between `meta-description: A guide` (a key) and `Kotlin-SDK:er`
146
+ * (prose), and it is why this cannot reuse `KEY_LINE`, whose `\s*` makes the
147
+ * separator optional. The lazy `.*?` lets a colon-compound key like
148
+ * `og:title: Social` match on its real separator rather than its first colon.
149
+ */
150
+ function isYamlKeyLine(line: string): boolean {
151
+ return /^\s*[^\s#].*?:(\s|$)/.test(line);
152
+ }
153
+
132
154
  /**
133
155
  * True if the value on `lines[i]` continues onto a subsequent indented line
134
156
  * (a YAML folded scalar without an explicit `|` or `>` indicator). The next
@@ -159,7 +181,23 @@ export function parseFrontmatterLenient(content: string): {
159
181
  } {
160
182
  const processed = preprocessFrontmatter(content);
161
183
  const { data, content: rawContent } = matter(processed);
162
- return { data, content: rawContent };
184
+ // Copied, never handed out by reference. gray-matter caches by content string
185
+ // and returns Object.assign({}, cached) on a hit — a SHALLOW copy, so `data`
186
+ // is ONE object shared by every parse of the same page, process-wide. A caller
187
+ // that wrote to it changed what every other caller read: a <meta> back-fill in
188
+ // buildDocMetadata surfaced as a duplicated page subtitle on every
189
+ // description-less page (#7). Callers get their own object; the cache stays
190
+ // pristine.
191
+ //
192
+ // Bounded on purpose, and NOT a guarantee that the whole class is closed:
193
+ // this protects TOP-LEVEL keys for callers who come through this function.
194
+ // Nested values (`data.seo`, tag arrays) are still shared by the spread, and
195
+ // three sites call `matter()` directly and bypass this entirely — build.ts,
196
+ // lib/docs.ts's readFrontmatterOnly, lib/api-page-panel-validator.ts. All are
197
+ // read-only today; a future writer through any of them re-opens the hole. A
198
+ // deep clone would cost a full walk on every page view of a force-dynamic
199
+ // route, which is the wrong trade for a leak that was one top-level key.
200
+ return { data: { ...data }, content: rawContent };
163
201
  }
164
202
 
165
203
  // frontmatterText lives in its own import-free leaf so ApiMarkdown.tsx (a
@@ -413,7 +413,20 @@ export async function buildDocMetadata(input: RenderInput): Promise<Metadata> {
413
413
  const parsed = parseFrontmatter(fileContents);
414
414
  const data = parsed.data as FrontmatterData;
415
415
 
416
- if (!data.description) {
416
+ // DERIVED for <meta>/OG/Twitter/OG-card only — never written back onto
417
+ // `data`. `parseFrontmatter` is gray-matter, whose cache returns a shallow
418
+ // copy that SHARES one `data` object per content string, so an assignment
419
+ // here reached `renderDocPage`'s own parse of the same page and rendered as
420
+ // the page SUBTITLE: the operation description twice on every spec-backed
421
+ // page, and the first paragraph twice on every description-less prose page.
422
+ // The cache is module-global, so it persisted across requests rather than
423
+ // being a within-request ordering race. (#7 follow-up.)
424
+ //
425
+ // The gate stays on the RAW value, not frontmatterText(): YAML hands back a
426
+ // Date for `description: 2026-01-01` and a number for `description: 404`.
427
+ // Both are truthy and must keep suppressing the fallbacks exactly as before.
428
+ let metaDescription: string | undefined = data.description;
429
+ if (!metaDescription) {
417
430
  if (typeof data.openapi === 'string' && data.openapi && config.api?.openapi) {
418
431
  // Source the description from the OpenAPI operation before falling back to
419
432
  // first-paragraph extraction (which is empty for prose-less API pages).
@@ -447,18 +460,23 @@ export async function buildDocMetadata(input: RenderInput): Promise<Metadata> {
447
460
  const sourced = await resolveOpenApiMetaDescription(
448
461
  data.openapi, specPaths, loadSpecForMeta,
449
462
  );
450
- if (sourced) data.description = sourced;
463
+ if (sourced) metaDescription = sourced;
451
464
  }
452
- if (!data.description) {
453
- data.description = generateAutoDescription(parsed.content);
465
+ if (!metaDescription) {
466
+ metaDescription = generateAutoDescription(parsed.content);
454
467
  }
455
468
  }
456
469
 
470
+ // buildSeoMetadata reads `frontmatter.description` for og:, twitter: and the
471
+ // OG card, so it must see the RESOLVED text — via a copy, never by mutating
472
+ // the shared `data`.
473
+ const seoFrontmatter = { ...data, description: metaDescription };
474
+
457
475
  const baseUrl = resolveBaseUrl(requestHeaders, projectSlug, hostAtDocs);
458
476
  const languages = config.navigation?.languages;
459
477
 
460
478
  const seoMetadata = buildSeoMetadata(
461
- config, data, pagePath, baseUrl, languages, isRootAlias, linkPrefix,
479
+ config, seoFrontmatter, pagePath, baseUrl, languages, isRootAlias, linkPrefix,
462
480
  localeFallback?.englishPath,
463
481
  );
464
482
 
@@ -488,7 +506,7 @@ export async function buildDocMetadata(input: RenderInput): Promise<Metadata> {
488
506
  title: titleValue,
489
507
  // Plain-texted, not just coerced: page descriptions render markdown, and
490
508
  // <meta name="description"> is read verbatim by every crawler and unfurler.
491
- description: metaDescriptionText(data.description),
509
+ description: metaDescriptionText(metaDescription),
492
510
  ...seoMetadata,
493
511
  ...robotsOverride,
494
512
  alternates: {
@@ -266,16 +266,23 @@ function markContinuationLines(lines) {
266
266
  const match = lines[i].match(KEY_LINE);
267
267
  if (!match) continue;
268
268
  const [, indent, , value] = match;
269
- if (!isBlockScalar(value) && !hasFoldedContinuation(lines, i)) continue;
269
+ const block = isBlockScalar(value);
270
+ if (!block && !hasFoldedContinuation(lines, i)) continue;
270
271
  for (let j = i + 1; j < lines.length; j++) {
271
272
  if (!lines[j].trim()) { out[j] = true; continue; }
272
273
  if (lines[j].search(/\S/) <= indent.length) break;
274
+ if (!block && isYamlKeyLine(lines[j])) break;
273
275
  out[j] = true;
274
276
  }
275
277
  }
276
278
  return out;
277
279
  }
278
280
 
281
+ /** Mirror of isYamlKeyLine in lib/frontmatter-utils.ts. */
282
+ function isYamlKeyLine(line) {
283
+ return /^\s*[^\s#].*?:(\s|$)/.test(line);
284
+ }
285
+
279
286
  /** Mirror of hasFoldedContinuation in lib/frontmatter-utils.ts. */
280
287
  function hasFoldedContinuation(lines, i) {
281
288
  for (let j = i + 1; j < lines.length; j++) {
@@ -834,9 +834,9 @@
834
834
  }
835
835
  },
836
836
  "node_modules/@jridgewell/sourcemap-codec": {
837
- "version": "1.5.5",
838
- "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
839
- "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
837
+ "version": "1.6.0",
838
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.6.0.tgz",
839
+ "integrity": "sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==",
840
840
  "license": "MIT"
841
841
  },
842
842
  "node_modules/@jridgewell/trace-mapping": {
@@ -1918,9 +1918,9 @@
1918
1918
  }
1919
1919
  },
1920
1920
  "node_modules/@types/node": {
1921
- "version": "26.3.0",
1922
- "resolved": "https://registry.npmjs.org/@types/node/-/node-26.3.0.tgz",
1923
- "integrity": "sha512-L3fgrnchriRC2ExBflb8j4uZZURHZfQsmQeyVzhjcHW4kkwVyo8/0h1B2MVzMTrYUJYu6G7EWs14hW/L9putqw==",
1921
+ "version": "26.4.0",
1922
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-26.4.0.tgz",
1923
+ "integrity": "sha512-faiGnoIrLH/V8cibOMEAZ8pMw6oXqSukl29ra4mN8GdaB2ZewzeaLj+INpV5N+Z1eKWzY+IzaIZH2EIR6YZRNQ==",
1924
1924
  "license": "MIT",
1925
1925
  "dependencies": {
1926
1926
  "undici-types": "~8.3.0"
@@ -1958,9 +1958,9 @@
1958
1958
  "license": "MIT"
1959
1959
  },
1960
1960
  "node_modules/@ungap/structured-clone": {
1961
- "version": "1.3.4",
1962
- "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.4.tgz",
1963
- "integrity": "sha512-JL+CF0GeLHyPWI0rXu7UnxgiuOm9UQWzadi0OYOJNhNO2q6EZElpwlgXkNkfU1PzANDHq3YcwKVZprdvS+BrbQ==",
1961
+ "version": "1.4.0",
1962
+ "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.4.0.tgz",
1963
+ "integrity": "sha512-1mEZtMKPM09vDmQt5y7YvmN2+DFTP7Tg0EWXdic8/C6VRnpb33e4ghisCIE3WZjsE2N8mf+QV1Zqh7ZFYLWInQ==",
1964
1964
  "license": "ISC"
1965
1965
  },
1966
1966
  "node_modules/@upsetjs/venn.js": {
@@ -2131,9 +2131,9 @@
2131
2131
  }
2132
2132
  },
2133
2133
  "node_modules/baseline-browser-mapping": {
2134
- "version": "2.11.19",
2135
- "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.19.tgz",
2136
- "integrity": "sha512-Grytf1xOxOEMTGRwx6rLGKkTabd4vMg3VrKdj/7joCmV0qgh4QwMMO6xh34YEXQqirAuUdgQGa5orJQQ+69RBw==",
2134
+ "version": "2.11.20",
2135
+ "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.20.tgz",
2136
+ "integrity": "sha512-H0ulySigv6icDJ1F7SjtdCD6PrhTpdYCmP0CactWy1+ekh0AFd0o1Wn5T8b+hnTmdBx19u9yhL6wvCylXMY7zw==",
2137
2137
  "license": "Apache-2.0",
2138
2138
  "bin": {
2139
2139
  "baseline-browser-mapping": "dist/cli.cjs"
@@ -2925,9 +2925,9 @@
2925
2925
  "license": "MIT"
2926
2926
  },
2927
2927
  "node_modules/electron-to-chromium": {
2928
- "version": "1.5.415",
2929
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.415.tgz",
2930
- "integrity": "sha512-958V+Kbhtgz+SxXeEVKBjrlKRBIDAYvUJfwhjxMZ5S6ut9jAl7l9ZKBkBrvjyjZE36PabLUo2L8kEeV5O4vgJg==",
2928
+ "version": "1.5.417",
2929
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.417.tgz",
2930
+ "integrity": "sha512-4T+DTDWuMPM4aHlHwWdAVCVWwp7LDilnhzkj+c/Lbj91XSQrLuOmZSLtS9Q4iIqjlPUbPOnC624zDVVHCHaolQ==",
2931
2931
  "license": "ISC"
2932
2932
  },
2933
2933
  "node_modules/enhanced-resolve": {
@@ -2956,9 +2956,9 @@
2956
2956
  }
2957
2957
  },
2958
2958
  "node_modules/es-toolkit": {
2959
- "version": "1.51.0",
2960
- "resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.51.0.tgz",
2961
- "integrity": "sha512-zC2lQGkM7QX+Gm6iM3+WIdZJzthsEd14LvRNJneSO2hzyz/zNBENR8+YXWo1cKxgPBtV6ksPYHELbcwBRzmdCw==",
2959
+ "version": "1.52.0",
2960
+ "resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.52.0.tgz",
2961
+ "integrity": "sha512-XTNEJQh1tY1ZJVcf6ayP/2n4ZPyaHlW2FWs7xvw5ddPuhUVjLD3olQVQS7kf58JbAB48iL0uL/jerTrjtV3lDA==",
2962
2962
  "license": "MIT",
2963
2963
  "workspaces": [
2964
2964
  "docs",
@@ -5418,9 +5418,9 @@
5418
5418
  }
5419
5419
  },
5420
5420
  "node_modules/node-releases": {
5421
- "version": "2.0.53",
5422
- "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.53.tgz",
5423
- "integrity": "sha512-D9UOmYG3UH1V+ENW56t5QXBwJw1YEY18ruVeus89Rw+SyIgjPkCO84bRzO3uNIYosJbNwiabWVn48o3uJLjxFQ==",
5421
+ "version": "2.0.54",
5422
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.54.tgz",
5423
+ "integrity": "sha512-YHs7BmmcsdAI5Ozuf8JZo6PT0mv2GIWC9vMfvUC3dp65M8hn7Ux8CPL+2oBI7juNuj9d0ndhTcznq2ODBps9cQ==",
5424
5424
  "license": "MIT",
5425
5425
  "engines": {
5426
5426
  "node": ">=18"
@@ -6539,9 +6539,9 @@
6539
6539
  }
6540
6540
  },
6541
6541
  "node_modules/update-browserslist-db": {
6542
- "version": "1.3.1",
6543
- "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.3.1.tgz",
6544
- "integrity": "sha512-ZZ61DsRsOnakl74HAmp3oSN4aXUmEWXf+i/yv0h7tIBfICc3VdrFErQKUUKPgu3AMsTUMbcongALEN4l6GSUrQ==",
6542
+ "version": "1.3.2",
6543
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.3.2.tgz",
6544
+ "integrity": "sha512-UQ+MSxlhRm1bzjhU+DcuXfjFO1FzNtqhK5+9Yvlp90ItDLk5vT932A0rFu619nf7RVS+Y/VeaUW1jaRDqZ8VJw==",
6545
6545
  "funding": [
6546
6546
  {
6547
6547
  "type": "opencollective",