@@ -44,38 +44,7 @@ export default defineCachedEventHandler(
4444 packageName : decodeURIComponent ( rawPackageName ) ,
4545 version : rawVersion ,
4646 } )
47-
48- // Fetch package data
49- const encodedName = encodePackageName ( packageName )
50- const versionSuffix = version ? `/${ version } ` : '/latest'
51- const pkg = await $fetch < AnalysisPackageJson > (
52- `${ NPM_REGISTRY } /${ encodedName } ${ versionSuffix } ` ,
53- )
54-
55- let typesPackage : TypesPackageInfo | undefined
56- let files : Set < string > | undefined
57-
58- // Only check for @types and files when the package doesn't ship its own types
59- if ( ! hasBuiltInTypes ( pkg ) ) {
60- const typesPkgName = getTypesPackageName ( packageName )
61- const resolvedVersion = pkg . version ?? version ?? 'latest'
62-
63- // Fetch @types info and file tree in parallel — they are independent
64- const [ typesResult , fileTreeResult ] = await Promise . allSettled ( [
65- fetchTypesPackageInfo ( typesPkgName ) ,
66- getPackageFileTree ( packageName , resolvedVersion ) ,
67- ] )
68-
69- if ( typesResult . status === 'fulfilled' ) {
70- typesPackage = typesResult . value
71- }
72- if ( fileTreeResult . status === 'fulfilled' ) {
73- files = flattenFileTree ( fileTreeResult . value . tree )
74- }
75- }
76-
77- // Check for associated create-* package (e.g., vite -> create-vite, next -> create-next-app)
78- // Only show if the packages are actually associated (same maintainers or same org)
47+ const { pkg, typesPackage, files } = await fetchPackageWithTypesAndFiles ( packageName , version )
7948 const createPackage = await findAssociatedCreatePackage ( packageName , pkg )
8049 const analysis = analyzePackage ( pkg , {
8150 typesPackage,
@@ -107,6 +76,46 @@ export default defineCachedEventHandler(
10776 } ,
10877)
10978
79+ export async function fetchPackageWithTypesAndFiles (
80+ packageName : string ,
81+ version ?: string ,
82+ ) : Promise < {
83+ pkg : AnalysisPackageJson
84+ typesPackage ?: TypesPackageInfo
85+ files ?: Set < string >
86+ } > {
87+ // Fetch main package data
88+ const encodedName = encodePackageName ( packageName )
89+ const versionSuffix = version ? `/${ version } ` : '/latest'
90+
91+ const pkg = await $fetch < AnalysisPackageJson > ( `${ NPM_REGISTRY } /${ encodedName } ${ versionSuffix } ` )
92+
93+ let typesPackage : TypesPackageInfo | undefined
94+ let files : Set < string > | undefined
95+
96+ // Only attempt to fetch @types + file tree when the package doesn't ship its own types
97+ if ( ! hasBuiltInTypes ( pkg ) ) {
98+ const typesPkgName = getTypesPackageName ( packageName )
99+ const resolvedVersion = pkg . version ?? version ?? 'latest'
100+
101+ // Fetch both in parallel — they're independent
102+ const [ typesResult , fileTreeResult ] = await Promise . allSettled ( [
103+ fetchTypesPackageInfo ( typesPkgName ) ,
104+ getPackageFileTree ( packageName , resolvedVersion ) ,
105+ ] )
106+
107+ if ( typesResult . status === 'fulfilled' ) {
108+ typesPackage = typesResult . value
109+ }
110+
111+ if ( fileTreeResult . status === 'fulfilled' ) {
112+ files = flattenFileTree ( fileTreeResult . value . tree )
113+ }
114+ }
115+
116+ return { pkg, typesPackage, files }
117+ }
118+
110119/**
111120 * Fetch @types package info including deprecation status using fast-npm-meta.
112121 * Returns undefined if the package doesn't exist.
0 commit comments