···11-import type { H3Event } from 'h3'
22-31/**
42 * Type for the cachedFetch function attached to event context.
53 */
···3230 * )
3331 * }
3432 * ```
3333+ * @public
3534 */
3635export function useCachedFetch(): CachedFetchFunction {
3736 // On client, return a function that just uses $fetch
···7271 return (await $fetch(url, options as Parameters<typeof $fetch>[1])) as T
7372 }
7473}
7575-7676-/**
7777- * Create a cachedFetch function from an H3Event.
7878- * Useful when you have direct access to the event.
7979- */
8080-export function getCachedFetchFromEvent(event: H3Event | undefined): CachedFetchFunction {
8181- const serverCachedFetch = event?.context?.cachedFetch
8282-8383- if (serverCachedFetch) {
8484- return serverCachedFetch as CachedFetchFunction
8585- }
8686-8787- // Fallback to regular $fetch
8888- return async <T = unknown>(
8989- url: string,
9090- options: {
9191- method?: string
9292- body?: unknown
9393- headers?: Record<string, string>
9494- } = {},
9595- _ttl?: number,
9696- ): Promise<T> => {
9797- return (await $fetch(url, options as Parameters<typeof $fetch>[1])) as T
9898- }
9999-}
+1
app/composables/useCharts.ts
···286286 return versionDates[0] ?? null
287287}
288288289289+/** @public */
289290export function useCharts() {
290291 function resolveDateRange(
291292 downloadEvolutionOptions: PackageDownloadEvolutionOptions,
···4646/**
4747 * Composable for accessing just the relative dates setting.
4848 * Useful for components that only need to read this specific setting.
4949+ * @public
4950 */
5051export function useRelativeDates() {
5152 const { settings } = useSettings()
···8485/**
8586 * Applies accent color before hydration to prevent flash of default color.
8687 * Call this from app.vue to ensure accent color is applied on every page.
8888+ * @public
8789 */
8890export function initAccentOnPrehydrate() {
8991 // Callback is stringified by Nuxt - external variables won't be available.
+1
app/composables/useVirtualInfiniteScroll.ts
···3434 * Composable for handling infinite scroll with virtua's WindowVirtualizer
3535 * Detects when user scrolls near the end and triggers loading more items
3636 * Also tracks current visible page for URL persistence
3737+ * @public
3738 */
3839export function useVirtualInfiniteScroll(options: UseVirtualInfiniteScrollOptions) {
3940 const {
+2
app/utils/charts.ts
···1010 return result
1111}
12121313+/** @public */
1314export function buildWeeklyEvolutionFromDaily(
1415 daily: Array<{ day: string; downloads: number }>,
1516): Array<{ weekStart: string; weekEnd: string; downloads: number }> {
···2223 })
2324}
24252626+/** @public */
2527export function addDays(date: Date, days: number): Date {
2628 const d = new Date(date)
2729 d.setUTCDate(d.getUTCDate() + days)
+2
app/utils/colors.ts
···3838 * Used to create light tints of accent colors for better visibility in light mode.
3939 * @param hex - The hex color to lighten (e.g., "#ff0000")
4040 * @param factor - Lighten factor from 0 to 1 (0.5 = 50% lighter, mixed with white)
4141+ * @public
4142 */
4243export function lightenHex(hex: string, factor: number = 0.5): string {
4344 const rgb = hexToRgb(hex)
···4849 return rgbToHex(...lightened)
4950}
50515252+/** @public */
5153export function oklchToHex(color: string | undefined | null): string | undefined | null {
5254 if (color == null) return color
5355
+3
app/utils/formatters.ts
···11+/** @public */
12export function formatNumber(num: number, _locale?: string): string {
23 // TODO: Support different locales (needs care to ensure hydration works correctly)
34 return new Intl.NumberFormat('en-US').format(num)
45}
5677+/** @public */
68export function toIsoDateString(date: Date): string {
79 const year = date.getUTCFullYear()
810 const month = String(date.getUTCMonth() + 1).padStart(2, '0')
···1012 return `${year}-${month}-${day}`
1113}
12141515+/** @public */
1316export function formatCompactNumber(
1417 value: number,
1518 options?: { decimals?: number; space?: boolean },
···90909191/**
9292 * Generate the full install command for a package.
9393+ * @public
9394 */
9495export function getInstallCommand(options: InstallCommandOptions): string {
9596 return getInstallCommandParts(options).join(' ')
···117118 isCreatePackage?: boolean
118119}
119120121121+/** @public */
120122export function getExecuteCommand(options: ExecuteCommandOptions): string {
121123 return getExecuteCommandParts(options).join(' ')
122124}
+4
app/utils/run-command.ts
···2121 * - Name starts with "create-" (e.g., create-vite)
2222 * - Scoped name contains "/create-" (e.g., @vue/create-app)
2323 * - Has bin field but no main, module, or exports fields
2424+ * @public
2425 */
2526export function isBinaryOnlyPackage(pkg: PackageMetadata): boolean {
2627 const baseName = pkg.name.startsWith('@') ? pkg.name.split('/')[1] : pkg.name
···40414142/**
4243 * Check if a package uses the create-* naming convention.
4444+ * @public
4345 */
4446export function isCreatePackage(packageName: string): boolean {
4547 const baseName = packageName.startsWith('@') ? packageName.split('/')[1] : packageName
···6163/**
6264 * Extract executable command information from a package's bin field.
6365 * Handles both string format ("bin": "./cli.js") and object format ("bin": { "cmd": "./cli.js" }).
6666+ * @public
6467 */
6568export function getExecutableInfo(
6669 packageName: string,
···147150148151/**
149152 * Generate the full run command for a package.
153153+ * @public
150154 */
151155export function getRunCommand(options: RunCommandOptions): string {
152156 return getRunCommandParts(options).join(' ')
+2
app/utils/versions.ts
···5555 * Sort tags with 'latest' first, then alphabetically
5656 * @param tags - Array of tag names
5757 * @returns New sorted array
5858+ * @public
5859 */
5960export function sortTags(tags: string[]): string[] {
6061 return [...tags].sort((a, b) => {
···111112 * Each unique version appears once with all its tags
112113 * @param distTags - Object mapping tag names to version strings
113114 * @returns Array of rows sorted by version (descending)
115115+ * @public
114116 */
115117export function buildTaggedVersionRows(distTags: Record<string, string>): TaggedVersionRow[] {
116118 const versionToTags = buildVersionToTagsMap(distTags)
+3
cli/src/logger.ts
···55555656/**
5757 * Log a message (generic)
5858+ * @public
5859 */
5960export function logMessage(message: string): void {
6061 p.log.message(message)
···78797980/**
8081 * Show outro message
8282+ * @public
8183 */
8284export function showOutro(message: string): void {
8385 p.outro(message)
···85878688/**
8789 * Create a spinner for async operations
9090+ * @public
8891 */
8992export function createSpinner() {
9093 return p.spinner()
+13
cli/src/schemas.ts
···59596060/**
6161 * Validates a team name (without scope prefix)
6262+ * @public
6263 */
6364export const TeamNameSchema = v.pipe(
6465 v.string(),
···330331// Type Exports
331332// ============================================================================
332333334334+/** @public */
333335export type PackageName = v.InferOutput<typeof PackageNameSchema>
336336+/** @public */
334337export type NewPackageName = v.InferOutput<typeof NewPackageNameSchema>
338338+/** @public */
335339export type Username = v.InferOutput<typeof UsernameSchema>
340340+/** @public */
336341export type OrgName = v.InferOutput<typeof OrgNameSchema>
342342+/** @public */
337343export type ScopeTeam = v.InferOutput<typeof ScopeTeamSchema>
344344+/** @public */
338345export type OrgRole = v.InferOutput<typeof OrgRoleSchema>
346346+/** @public */
339347export type Permission = v.InferOutput<typeof PermissionSchema>
348348+/** @public */
340349export type OperationType = v.InferOutput<typeof OperationTypeSchema>
350350+/** @public */
341351export type OperationStatus = v.InferOutput<typeof OperationStatusSchema>
352352+/** @public */
342353export type ConnectBody = v.InferOutput<typeof ConnectBodySchema>
354354+/** @public */
343355export type ExecuteBody = v.InferOutput<typeof ExecuteBodySchema>
356356+/** @public */
344357export type CreateOperationBody = v.InferOutput<typeof CreateOperationBodySchema>
···79798080/**
8181 * Determine the language for syntax highlighting based on file path
8282+ * @public
8283 */
8384export function getLanguageFromPath(filePath: string): string {
8485 const filename = filePath.split('/').pop() || ''
···251252/**
252253 * Highlight code using Shiki with line-by-line output for line highlighting.
253254 * Each line is wrapped in a span.line for individual line highlighting.
255255+ * @public
254256 */
255257export async function highlightCode(
256258 code: string,
+1
server/utils/error-handler.ts
···55/**
66 * Generic error handler for Nitro routes
77 * Handles H3 errors, Valibot, and fallbacks in that order
88+ * @public
89 */
910export function handleApiError(error: unknown, fallback: ErrorOptions): never {
1011 // If already a known Nuxt/H3 Error, re-throw
+1
server/utils/file-tree.ts
···6969/**
7070 * Fetch and convert file tree for a package version.
7171 * Returns the full response including tree and metadata.
7272+ * @public
7273 */
7374export async function getPackageFileTree(
7475 packageName: string,
+2
server/utils/import-resolver.ts
···8899/**
1010 * Flatten a nested file tree into a set of file paths for quick lookups.
1111+ * @public
1112 */
1213export function flattenFileTree(tree: PackageFileTree[]): FileSet {
1314 const files = new Set<string>()
···202203203204/**
204205 * Create a resolver function bound to a specific file tree and current file.
206206+ * @public
205207 */
206208export function createImportResolver(
207209 files: FileSet,
+1
server/utils/install-size.ts
···3131 * No filesystem operations - safe for serverless environments.
3232 *
3333 * Dependencies are resolved for linux-x64-glibc as a representative platform.
3434+ * @public
3435 */
3536export const calculateInstallSize = defineCachedFunction(
3637 async (name: string, version: string): Promise<InstallSizeResult> => {
+1
server/utils/jsr.ts
···1414 *
1515 * @param npmPackageName - The npm package name (e.g., "@hono/hono")
1616 * @returns JsrPackageInfo with existence status and metadata
1717+ * @public
1718 */
1819export const fetchJsrPackageInfo = defineCachedFunction(
1920 async (npmPackageName: string): Promise<JsrPackageInfo> => {
+1
server/utils/npm.ts
···6464/**
6565 * Resolve multiple dependency constraints to their best matching versions.
6666 * Returns a map of package name to resolved version.
6767+ * @public
6768 */
6869export async function resolveDependencyVersions(
6970 dependencies: Record<string, string>,
+1
server/utils/parse-package-params.ts
···11/**
22 * Parses Nitro router segments into packageName and an optional version
33 * Handles patterns: [pkg], [pkg, 'v', version], [@scope, pkg], [@scope, pkg, 'v', version]
44+ * @public
45 */
56export function parsePackageParams(segments: string[]): {
67 rawPackageName: string
···2121 * Generate an SPDX license URL for the given license identifier.
2222 * Returns null if the license is not a valid SPDX identifier.
2323 * @see https://spdx.org/licenses/
2424+ * @public
2425 */
2526export function getSpdxLicenseUrl(license: string | undefined): string | null {
2627 if (!license) return null