diffs: share language hint validation

This commit is contained in:
Gustavo Madeira Santana 2026-03-30 16:24:30 -04:00
parent 39023edf40
commit 13b3cbd24b
No known key found for this signature in database
4 changed files with 67 additions and 58 deletions

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,39 @@
import { resolveLanguage } from "@pierre/diffs";
import type { SupportedLanguages } from "@pierre/diffs";
const PASSTHROUGH_LANGUAGE_HINTS = new Set<SupportedLanguages>(["ansi", "text"]);
export async function normalizeSupportedLanguageHint(
value?: string,
): Promise<SupportedLanguages | undefined> {
const normalized = value?.trim();
if (!normalized) {
return undefined;
}
if (PASSTHROUGH_LANGUAGE_HINTS.has(normalized as SupportedLanguages)) {
return normalized as SupportedLanguages;
}
try {
await resolveLanguage(normalized as Exclude<SupportedLanguages, "text" | "ansi">);
return normalized as SupportedLanguages;
} catch {
return undefined;
}
}
export async function filterSupportedLanguageHints(
values: Iterable<string>,
): Promise<SupportedLanguages[]> {
const supported = new Set<SupportedLanguages>();
for (const value of values) {
const normalized = await normalizeSupportedLanguageHint(value);
if (!normalized) {
continue;
}
supported.add(normalized);
}
if (supported.size === 0) {
supported.add("text");
}
return [...supported];
}

View File

@ -1,6 +1,7 @@
import type { FileContents, FileDiffMetadata, SupportedLanguages } from "@pierre/diffs";
import { parsePatchFiles, resolveLanguage } from "@pierre/diffs";
import { parsePatchFiles } from "@pierre/diffs";
import { preloadFileDiff, preloadMultiFileDiff } from "@pierre/diffs/ssr";
import { normalizeSupportedLanguageHint } from "./language-hints.js";
import { ensurePierreThemesRegistered } from "./pierre-themes.js";
import type {
DiffInput,
@ -178,22 +179,6 @@ function buildRenderVariants(params: { options: DiffRenderOptions; target: DiffR
};
}
async function normalizeSupportedLanguage(value?: string): Promise<SupportedLanguages | undefined> {
const normalized = value?.trim();
if (!normalized) {
return undefined;
}
if (normalized === "text" || normalized === "ansi") {
return normalized;
}
try {
await resolveLanguage(normalized as Exclude<SupportedLanguages, "text" | "ansi">);
return normalized as SupportedLanguages;
} catch {
return undefined;
}
}
function buildPayloadLanguages(payload: {
fileDiff?: FileDiffMetadata;
oldFile?: FileContents;
@ -363,7 +348,7 @@ async function renderBeforeAfterDiff(
): Promise<{ viewerBodyHtml?: string; imageBodyHtml?: string; fileCount: number }> {
ensurePierreThemesRegistered();
const lang = await normalizeSupportedLanguage(input.lang);
const lang = await normalizeSupportedLanguageHint(input.lang);
const fileName = resolveBeforeAfterFileName({ input, lang });
const oldFile: FileContents = {
name: fileName,

View File

@ -1,10 +1,11 @@
import { FileDiff, preloadHighlighter, resolveLanguage } from "@pierre/diffs";
import { FileDiff, preloadHighlighter } from "@pierre/diffs";
import type {
FileContents,
FileDiffMetadata,
FileDiffOptions,
SupportedLanguages,
} from "@pierre/diffs";
import { filterSupportedLanguageHints } from "./language-hints.js";
import type { DiffViewerPayload, DiffLayout, DiffTheme } from "./types.js";
import { parseViewerPayloadJson } from "./viewer-payload.js";
@ -32,23 +33,7 @@ const viewerState: ViewerState = {
export async function filterSupportedHydrationLanguages(
languages: Iterable<string>,
): Promise<SupportedLanguages[]> {
const supported = new Set<SupportedLanguages>();
for (const language of languages) {
if (language === "text" || language === "ansi") {
supported.add(language);
continue;
}
try {
await resolveLanguage(language as Exclude<SupportedLanguages, "text" | "ansi">);
supported.add(language);
} catch {
// Ignore invalid persisted hints and let the viewer fall back to plain text.
}
}
if (supported.size === 0) {
supported.add("text");
}
return [...supported];
return filterSupportedLanguageHints(languages);
}
function parsePayload(element: HTMLScriptElement): DiffViewerPayload {