Skip to content

Commit d898203

Browse files
committed
feat(devtools): update package.json scripts and enhance JSON-LD and links preview functionality
This commit modifies the package.json to improve testing scripts by adding a command to clear the NX daemon and updating the size limit for the devtools package. Additionally, it refactors the JSON-LD and links preview components to enhance readability and maintainability, including changes to function declarations and formatting for better code clarity. These updates aim to improve the overall user experience and accessibility in the SEO tab.
1 parent bad6287 commit d898203

4 files changed

Lines changed: 83 additions & 44 deletions

File tree

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{ "configPath": "../../dist/server/wrangler.json", "auxiliaryWorkers": [] }
1+
{"configPath":"../../dist/server/wrangler.json","auxiliaryWorkers":[]}

packages/devtools/src/tabs/seo-tab/json-ld-preview.tsx

Lines changed: 64 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
import { For, Show } from 'solid-js'
22
import { Section, SectionDescription } from '@tanstack/devtools-ui'
33
import { useStyles } from '../../styles/use-styles'
4-
import { pickSeverityClass, seoHealthTier, type SeoSeverity } from './seo-severity'
4+
import {
5+
pickSeverityClass,
6+
seoHealthTier,
7+
type SeoSeverity,
8+
} from './seo-severity'
59
import type { SeoSectionSummary } from './seo-section-summary'
610

711
type JsonLdValue = Record<string, unknown>
@@ -69,7 +73,7 @@ const SUPPORTED_RULES: Record<string, SchemaRule> = {
6973
}
7074

7175
/** Types that get field previews, structured validation, and expandable raw JSON. */
72-
export const JSON_LD_SUPPORTED_SCHEMA_TYPES: ReadonlyArray<string> = Object.keys(
76+
const JSON_LD_SUPPORTED_SCHEMA_TYPES: ReadonlyArray<string> = Object.keys(
7377
SUPPORTED_RULES,
7478
).sort((a, b) => a.localeCompare(b))
7579

@@ -110,7 +114,10 @@ function getEntities(payload: unknown): Array<JsonLdValue> {
110114
return [payload]
111115
}
112116

113-
function hasMissingKeys(entity: JsonLdValue, keys: Array<string>): Array<string> {
117+
function hasMissingKeys(
118+
entity: JsonLdValue,
119+
keys: Array<string>,
120+
): Array<string> {
114121
return keys.filter((key) => {
115122
const value = entity[key]
116123
if (value === undefined || value === null) return true
@@ -156,7 +163,10 @@ function validateTypes(entity: JsonLdValue): Array<ValidationIssue> {
156163
return []
157164
}
158165

159-
function validateEntityByType(entity: JsonLdValue, typeName: string): Array<ValidationIssue> {
166+
function validateEntityByType(
167+
entity: JsonLdValue,
168+
typeName: string,
169+
): Array<ValidationIssue> {
160170
const rules = SUPPORTED_RULES[typeName]
161171
if (!rules) {
162172
return [
@@ -251,7 +261,8 @@ function stringifyPreviewValue(value: unknown, maxLen = 200): string {
251261
if (typeof value === 'string') {
252262
return value.length > maxLen ? `${value.slice(0, maxLen)}…` : value
253263
}
254-
if (typeof value === 'number' || typeof value === 'boolean') return String(value)
264+
if (typeof value === 'number' || typeof value === 'boolean')
265+
return String(value)
255266
if (Array.isArray(value)) {
256267
if (value.length === 0) return '(empty)'
257268
if (value.length <= 3 && value.every((v) => typeof v === 'string')) {
@@ -273,9 +284,7 @@ function stringifyPreviewValue(value: unknown, maxLen = 200): string {
273284
if (isRecord(value)) {
274285
if (typeof value['@type'] === 'string' && (value.name ?? value.headline)) {
275286
const label =
276-
typeof value.name === 'string'
277-
? value.name
278-
: String(value.headline)
287+
typeof value.name === 'string' ? value.name : String(value.headline)
279288
return `${value['@type']}: ${label}`
280289
}
281290
const json = JSON.stringify(value)
@@ -313,9 +322,11 @@ function getEntityPreviewRows(
313322
}))
314323
}
315324

316-
export function analyzeJsonLdScripts(): Array<JsonLdEntry> {
325+
function analyzeJsonLdScripts(): Array<JsonLdEntry> {
317326
const scripts = Array.from(
318-
document.querySelectorAll<HTMLScriptElement>('script[type="application/ld+json"]'),
327+
document.querySelectorAll<HTMLScriptElement>(
328+
'script[type="application/ld+json"]',
329+
),
319330
)
320331

321332
return scripts.map((script, index) => {
@@ -391,22 +402,32 @@ export function getJsonLdPreviewSummary(): SeoSectionSummary {
391402
/**
392403
* Counts individual schema property names called out in missing-* validation messages.
393404
*/
394-
function sumMissingSchemaFieldCounts(
395-
entries: Array<JsonLdEntry>,
396-
): { required: number; recommended: number; optional: number } {
405+
function sumMissingSchemaFieldCounts(entries: Array<JsonLdEntry>): {
406+
required: number
407+
recommended: number
408+
optional: number
409+
} {
397410
const out = { required: 0, recommended: 0, optional: 0 }
398411
const rules: Array<{
399412
severity: SeoSeverity
400413
prefix: string
401414
key: keyof typeof out
402415
}> = [
403-
{ severity: 'error', prefix: 'Missing required attributes:', key: 'required' },
416+
{
417+
severity: 'error',
418+
prefix: 'Missing required attributes:',
419+
key: 'required',
420+
},
404421
{
405422
severity: 'warning',
406423
prefix: 'Missing recommended attributes:',
407424
key: 'recommended',
408425
},
409-
{ severity: 'info', prefix: 'Missing optional attributes:', key: 'optional' },
426+
{
427+
severity: 'info',
428+
prefix: 'Missing optional attributes:',
429+
key: 'optional',
430+
},
410431
]
411432

412433
for (const entry of entries) {
@@ -416,7 +437,10 @@ function sumMissingSchemaFieldCounts(
416437
if (!issue.message.startsWith(r.prefix)) continue
417438
const rest = issue.message.slice(r.prefix.length).trim()
418439
const n = rest
419-
? rest.split(',').map((x) => x.trim()).filter(Boolean).length
440+
? rest
441+
.split(',')
442+
.map((x) => x.trim())
443+
.filter(Boolean).length
420444
: 0
421445
out[r.key] += n
422446
}
@@ -459,7 +483,9 @@ function JsonLdEntityPreviewCard(props: { entity: JsonLdValue }) {
459483
when={rows.length > 0}
460484
fallback={
461485
<div class={s.seoJsonLdEntityCardRows}>
462-
<span class={s.seoJsonLdEntityCardValue}>(no fields to preview)</span>
486+
<span class={s.seoJsonLdEntityCardValue}>
487+
(no fields to preview)
488+
</span>
463489
</div>
464490
}
465491
>
@@ -516,16 +542,18 @@ function JsonLdBlock(props: { entry: JsonLdEntry; index: number }) {
516542
<div>
517543
<div class={s.serpPreviewLabelSub}>Block #{props.index + 1}</div>
518544
<div class={s.seoJsonLdBlockTypes}>
519-
{props.entry.types.length > 0 ? props.entry.types.join(', ') : 'Unknown type'}
520-
{showPreview ? (
521-
<span> · preview</span>
522-
) : (
523-
<span> · raw JSON</span>
524-
)}
545+
{props.entry.types.length > 0
546+
? props.entry.types.join(', ')
547+
: 'Unknown type'}
548+
{showPreview ? <span> · preview</span> : <span> · raw JSON</span>}
525549
</div>
526550
</div>
527551
<Show when={props.entry.parsed}>
528-
<button type="button" class={s.seoJsonLdCopyButton} onClick={copyParsed}>
552+
<button
553+
type="button"
554+
class={s.seoJsonLdCopyButton}
555+
onClick={copyParsed}
556+
>
529557
Copy
530558
</button>
531559
</Show>
@@ -605,7 +633,8 @@ export function JsonLdPreviewSection() {
605633
)
606634
const warningCount = entries.reduce(
607635
(total, entry) =>
608-
total + entry.issues.filter((issue) => issue.severity === 'warning').length,
636+
total +
637+
entry.issues.filter((issue) => issue.severity === 'warning').length,
609638
0,
610639
)
611640
const infoCount = entries.reduce(
@@ -639,27 +668,27 @@ export function JsonLdPreviewSection() {
639668
})()
640669
const missingFieldsLine = (() => {
641670
const bits: Array<string> = []
642-
if (fieldGaps.required > 0)
643-
bits.push(`${fieldGaps.required} required`)
671+
if (fieldGaps.required > 0) bits.push(`${fieldGaps.required} required`)
644672
if (fieldGaps.recommended > 0)
645673
bits.push(`${fieldGaps.recommended} recommended`)
646-
if (fieldGaps.optional > 0)
647-
bits.push(`${fieldGaps.optional} optional`)
674+
if (fieldGaps.optional > 0) bits.push(`${fieldGaps.optional} optional`)
648675
if (bits.length === 0) return null
649676
return `Missing schema fields: ${bits.join(' · ')}`
650677
})()
651678

652679
return (
653680
<Section>
654681
<SectionDescription>
655-
Reads every <code>{`<script type="application/ld+json">`}</code> block when
656-
you open this section. Blocks where every <code>@type</code> is in the list
657-
below get compact preview cards and expandable raw JSON; any other{' '}
658-
<code>@type</code> uses the full JSON view so you can inspect and copy it
659-
as before. Validation messages still apply in both cases.
682+
Reads every <code>{`<script type="application/ld+json">`}</code> block
683+
when you open this section. Blocks where every <code>@type</code> is in
684+
the list below get compact preview cards and expandable raw JSON; any
685+
other <code>@type</code> uses the full JSON view so you can inspect and
686+
copy it as before. Validation messages still apply in both cases.
660687
</SectionDescription>
661688
<div class={s.seoJsonLdSupportedIntro}>
662-
<span class={s.seoJsonLdSupportedIntroLabel}>Supported schema types</span>
689+
<span class={s.seoJsonLdSupportedIntroLabel}>
690+
Supported schema types
691+
</span>
663692
<div class={s.seoJsonLdSupportedChips}>
664693
<For each={[...JSON_LD_SUPPORTED_SCHEMA_TYPES]}>
665694
{(name) => <span class={s.seoJsonLdSupportedChip}>{name}</span>}

packages/devtools/src/tabs/seo-tab/links-preview.tsx

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ function classifyLink(anchor: HTMLAnchorElement): LinkRow {
102102

103103
const LINK_SUMMARY_ISSUE_CAP = 32
104104

105-
export function analyzeLinks(): Array<LinkRow> {
105+
function analyzeLinks(): Array<LinkRow> {
106106
const anchors = Array.from(
107107
document.body.querySelectorAll<HTMLAnchorElement>('a[href]'),
108108
)
@@ -123,7 +123,7 @@ const LINK_KIND_DISPLAY_ORDER: Record<LinkKind, number> = {
123123
invalid: 3,
124124
}
125125

126-
export function sortLinksForDisplay(links: Array<LinkRow>): Array<LinkRow> {
126+
function sortLinksForDisplay(links: Array<LinkRow>): Array<LinkRow> {
127127
return [...links].sort(
128128
(a, b) => LINK_KIND_DISPLAY_ORDER[a.kind] - LINK_KIND_DISPLAY_ORDER[b.kind],
129129
)
@@ -206,7 +206,10 @@ export function LinksPreviewSection() {
206206
acc[row.kind] += 1
207207
return acc
208208
},
209-
{ internal: 0, external: 0, 'non-web': 0, invalid: 0 } as Record<LinkKind, number>,
209+
{ internal: 0, external: 0, 'non-web': 0, invalid: 0 } as Record<
210+
LinkKind,
211+
number
212+
>,
210213
)
211214

212215
const s = styles()
@@ -236,7 +239,9 @@ export function LinksPreviewSection() {
236239
<div class={s.serpPreviewBlock}>
237240
<div class={s.serpPreviewLabel}>Links summary</div>
238241
<div class={s.seoChipRow}>
239-
<span class={`${s.seoPill} ${s.seoPillMuted}`}>{links.length} total</span>
242+
<span class={`${s.seoPill} ${s.seoPillMuted}`}>
243+
{links.length} total
244+
</span>
240245
<span class={`${s.seoPill} ${s.seoPillInternal}`}>
241246
{counts.internal} internal
242247
</span>
@@ -264,7 +269,9 @@ export function LinksPreviewSection() {
264269
<Show
265270
when={links.length > 0}
266271
fallback={
267-
<div class={s.seoMissingTagsSection}>No links found on this page.</div>
272+
<div class={s.seoMissingTagsSection}>
273+
No links found on this page.
274+
</div>
268275
}
269276
>
270277
<div class={s.serpPreviewBlock}>
@@ -288,7 +295,8 @@ export function LinksPreviewSection() {
288295
{KIND_LABEL[group.kind]}
289296
</span>
290297
<span class={s.seoHealthLabelMuted}>
291-
{group.items.length} link{group.items.length === 1 ? '' : 's'}
298+
{group.items.length} link
299+
{group.items.length === 1 ? '' : 's'}
292300
</span>
293301
</span>
294302
<span

packages/devtools/src/tabs/seo-tab/serp-preview.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ function truncateToChars(text: string, maxChars: number): string {
8888
return text.slice(0, maxChars - ELLIPSIS.length) + ELLIPSIS
8989
}
9090

91-
export function getSerpFromHead(): SerpData {
91+
function getSerpFromHead(): SerpData {
9292
const title = document.title || ''
9393
const url = typeof window !== 'undefined' ? window.location.href : ''
9494

@@ -255,7 +255,9 @@ function SerpSnippetPreview(props: {
255255
<ul class={styles().serpErrorList}>
256256
<For each={props.issues}>
257257
{(issue) => (
258-
<li class={`${styles().seoIssueText} ${styles().seoSerpIssueListItem}`}>
258+
<li
259+
class={`${styles().seoIssueText} ${styles().seoSerpIssueListItem}`}
260+
>
259261
{issue}
260262
</li>
261263
)}

0 commit comments

Comments
 (0)