snapshot of https://github.com/shadcn-ui/ui.git (main, 2026-09-15; blobs > 131072B omitted)
This commit is contained in:
203
apps/v4/app/r/registries.json/route.test.ts
Normal file
203
apps/v4/app/r/registries.json/route.test.ts
Normal file
@@ -0,0 +1,203 @@
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"
|
||||
|
||||
import { loadRegistryHealthSnapshot } from "@/lib/registry-health/blob"
|
||||
import type {
|
||||
RegistryHealth,
|
||||
RegistryHealthSnapshot,
|
||||
} from "@/lib/registry-health/schema"
|
||||
import directory from "@/registry/directory.json"
|
||||
|
||||
import { dynamic, GET, revalidate } from "./route"
|
||||
|
||||
vi.mock("@/lib/registry-health/blob", () => ({
|
||||
loadRegistryHealthSnapshot: vi.fn(),
|
||||
}))
|
||||
|
||||
const GENERATED_AT = "2026-08-24T12:00:00.000Z"
|
||||
const loadSnapshot = vi.mocked(loadRegistryHealthSnapshot)
|
||||
|
||||
function createHealth(overrides: Partial<RegistryHealth> = {}) {
|
||||
return {
|
||||
schemaVersion: 1,
|
||||
scoreVersion: 1,
|
||||
status: "healthy",
|
||||
statusReason: {
|
||||
code: "healthy_thresholds",
|
||||
message: "Recent checks are within healthy thresholds",
|
||||
},
|
||||
score: 90,
|
||||
breakdown: {
|
||||
reliability: 40,
|
||||
correctness: 23,
|
||||
installability: 18,
|
||||
hygiene: 9,
|
||||
},
|
||||
availability7d: 0.99,
|
||||
availability30d: 0.98,
|
||||
monitoringLimited: false,
|
||||
firstObservedAt: "2026-08-01T00:00:00.000Z",
|
||||
checkedAt: GENERATED_AT,
|
||||
lastSuccessfulCheck: GENERATED_AT,
|
||||
hidden: false,
|
||||
...overrides,
|
||||
} satisfies RegistryHealth
|
||||
}
|
||||
|
||||
function createSnapshot(registries: RegistryHealthSnapshot["registries"]) {
|
||||
return {
|
||||
schemaVersion: 1,
|
||||
scoreVersion: 1,
|
||||
generatedAt: GENERATED_AT,
|
||||
globalMeans: {
|
||||
availability7d: 0.85,
|
||||
availability30d: 0.85,
|
||||
indexSchema: 0.9,
|
||||
itemValidity: 0.9,
|
||||
dryRun: 0.9,
|
||||
},
|
||||
registries,
|
||||
} satisfies RegistryHealthSnapshot
|
||||
}
|
||||
|
||||
describe("GET /r/registries.json", () => {
|
||||
beforeEach(() => {
|
||||
vi.useFakeTimers()
|
||||
vi.setSystemTime(new Date("2026-08-24T13:00:00.000Z"))
|
||||
vi.stubEnv("REGISTRY_HEALTH_ENABLED", "1")
|
||||
vi.stubEnv("BLOB_READ_WRITE_TOKEN", "test-token")
|
||||
vi.stubEnv("REGISTRY_HEALTH_BLOB_STORE_ID", "test-store-id")
|
||||
loadSnapshot.mockReset()
|
||||
vi.spyOn(console, "warn").mockImplementation(() => {})
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
vi.useRealTimers()
|
||||
vi.unstubAllEnvs()
|
||||
vi.restoreAllMocks()
|
||||
})
|
||||
|
||||
it("uses static ISR so requests do not read Blob directly", () => {
|
||||
expect(dynamic).toBe("force-static")
|
||||
expect(revalidate).toBe(300)
|
||||
})
|
||||
|
||||
it("merges fresh health by exact namespace", async () => {
|
||||
const first = directory[0]
|
||||
loadSnapshot.mockResolvedValue(
|
||||
createSnapshot({ [first.name]: createHealth() })
|
||||
)
|
||||
|
||||
const response = await GET()
|
||||
const payload = await response.json()
|
||||
|
||||
expect(response.status).toBe(200)
|
||||
expect(payload[0]).toMatchObject({
|
||||
name: first.name,
|
||||
homepage: first.homepage,
|
||||
url: first.url,
|
||||
description: first.description,
|
||||
health: {
|
||||
score: 90,
|
||||
statusReason: {
|
||||
code: "healthy_thresholds",
|
||||
message: "Recent checks are within healthy thresholds",
|
||||
},
|
||||
},
|
||||
})
|
||||
expect(loadSnapshot).toHaveBeenCalledWith({
|
||||
token: "test-token",
|
||||
storeId: "test-store-id",
|
||||
abortSignal: expect.any(AbortSignal),
|
||||
})
|
||||
})
|
||||
|
||||
it("falls back to the default Blob store ID", async () => {
|
||||
vi.stubEnv("REGISTRY_HEALTH_BLOB_STORE_ID", "")
|
||||
vi.stubEnv("BLOB_STORE_ID", "default-store-id")
|
||||
loadSnapshot.mockResolvedValue(createSnapshot({}))
|
||||
|
||||
await GET()
|
||||
|
||||
expect(loadSnapshot).toHaveBeenCalledWith({
|
||||
token: "test-token",
|
||||
storeId: "default-store-id",
|
||||
abortSignal: expect.any(AbortSignal),
|
||||
})
|
||||
})
|
||||
|
||||
it("omits health for a registry missing from the snapshot", async () => {
|
||||
loadSnapshot.mockResolvedValue(createSnapshot({}))
|
||||
|
||||
const response = await GET()
|
||||
const payload = await response.json()
|
||||
|
||||
expect(payload[0]).not.toHaveProperty("health")
|
||||
})
|
||||
|
||||
it("returns the original payload when health is disabled", async () => {
|
||||
vi.stubEnv("REGISTRY_HEALTH_ENABLED", "0")
|
||||
|
||||
const response = await GET()
|
||||
const payload = await response.json()
|
||||
|
||||
expect(loadSnapshot).not.toHaveBeenCalled()
|
||||
expect(payload[0]).toEqual({
|
||||
name: directory[0].name,
|
||||
homepage: directory[0].homepage,
|
||||
url: directory[0].url,
|
||||
description: directory[0].description,
|
||||
})
|
||||
})
|
||||
|
||||
it("fails open for a stale snapshot", async () => {
|
||||
vi.setSystemTime(new Date("2026-08-25T00:00:00.000Z"))
|
||||
loadSnapshot.mockResolvedValue(createSnapshot({}))
|
||||
|
||||
const response = await GET()
|
||||
const payload = await response.json()
|
||||
|
||||
expect(response.status).toBe(200)
|
||||
expect(payload[0]).not.toHaveProperty("health")
|
||||
})
|
||||
|
||||
it.each(["a malformed snapshot", "an unknown version", "a Blob 500"])(
|
||||
"fails open for %s",
|
||||
async (failure) => {
|
||||
loadSnapshot.mockRejectedValue(new Error(failure))
|
||||
|
||||
const response = await GET()
|
||||
const payload = await response.json()
|
||||
|
||||
expect(response.status).toBe(200)
|
||||
expect(payload[0]).not.toHaveProperty("health")
|
||||
}
|
||||
)
|
||||
|
||||
it("fails open when the snapshot request times out", async () => {
|
||||
loadSnapshot.mockImplementation(
|
||||
({ abortSignal }) =>
|
||||
new Promise((_resolve, reject) => {
|
||||
abortSignal?.addEventListener("abort", () => {
|
||||
reject(new DOMException("Aborted", "AbortError"))
|
||||
})
|
||||
})
|
||||
)
|
||||
|
||||
const responsePromise = GET()
|
||||
await vi.advanceTimersByTimeAsync(2500)
|
||||
const response = await responsePromise
|
||||
const payload = await response.json()
|
||||
|
||||
expect(response.status).toBe(200)
|
||||
expect(payload[0]).not.toHaveProperty("health")
|
||||
})
|
||||
|
||||
it("fails open when the snapshot is missing", async () => {
|
||||
loadSnapshot.mockResolvedValue(null)
|
||||
|
||||
const response = await GET()
|
||||
const payload = await response.json()
|
||||
|
||||
expect(payload[0]).not.toHaveProperty("health")
|
||||
})
|
||||
})
|
||||
65
apps/v4/app/r/registries.json/route.ts
Normal file
65
apps/v4/app/r/registries.json/route.ts
Normal file
@@ -0,0 +1,65 @@
|
||||
import { NextResponse } from "next/server"
|
||||
|
||||
import {
|
||||
createPublicRegistryDirectory,
|
||||
registryDirectorySchema,
|
||||
} from "@/lib/registry-directory"
|
||||
import { loadRegistryHealthSnapshot } from "@/lib/registry-health/blob"
|
||||
import directory from "@/registry/directory.json"
|
||||
|
||||
export const dynamic = "force-static"
|
||||
export const revalidate = 300
|
||||
|
||||
const SNAPSHOT_STALE_AFTER_MS = 6 * 60 * 60 * 1000
|
||||
const SNAPSHOT_TIMEOUT_MS = 2500
|
||||
const registries = createPublicRegistryDirectory(
|
||||
registryDirectorySchema.parse(directory)
|
||||
)
|
||||
|
||||
async function getHealthSnapshot() {
|
||||
const controller = new AbortController()
|
||||
const timeout = setTimeout(() => controller.abort(), SNAPSHOT_TIMEOUT_MS)
|
||||
|
||||
try {
|
||||
const snapshot = await loadRegistryHealthSnapshot({
|
||||
token: process.env.BLOB_READ_WRITE_TOKEN,
|
||||
storeId:
|
||||
process.env.REGISTRY_HEALTH_BLOB_STORE_ID || process.env.BLOB_STORE_ID,
|
||||
abortSignal: controller.signal,
|
||||
})
|
||||
if (!snapshot) throw new Error("missing_snapshot")
|
||||
|
||||
const age = Date.now() - new Date(snapshot.generatedAt).getTime()
|
||||
if (age < 0 || age > SNAPSHOT_STALE_AFTER_MS) {
|
||||
throw new Error("stale_snapshot")
|
||||
}
|
||||
|
||||
return snapshot
|
||||
} catch (error) {
|
||||
console.warn(
|
||||
"Registry health snapshot unavailable:",
|
||||
error instanceof Error ? error.message : "unknown_error"
|
||||
)
|
||||
return null
|
||||
} finally {
|
||||
clearTimeout(timeout)
|
||||
}
|
||||
}
|
||||
|
||||
export async function GET() {
|
||||
if (process.env.REGISTRY_HEALTH_ENABLED !== "1") {
|
||||
return NextResponse.json(registries)
|
||||
}
|
||||
|
||||
const snapshot = await getHealthSnapshot()
|
||||
if (!snapshot) {
|
||||
return NextResponse.json(registries)
|
||||
}
|
||||
|
||||
return NextResponse.json(
|
||||
registries.map((registry) => {
|
||||
const health = snapshot.registries[registry.name]
|
||||
return health ? { ...registry, health } : registry
|
||||
})
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user