@@ -11,6 +11,7 @@ import {
1111} from "@definitelytyped/utils" ;
1212import { fetchTypesPackageVersionInfo } from "@definitelytyped/retag" ;
1313import * as pacote from "pacote" ;
14+ import * as semver from "semver" ;
1415
1516if ( ! module . parent ) {
1617 const log = loggerWithErrors ( ) [ 0 ] ;
@@ -33,7 +34,7 @@ async function computeAndSaveChangedPackages(
3334 changedTypings : cp . changedTypings . map (
3435 ( { pkg : { id } , version, latestVersion } ) : ChangedTypingJson => ( { id, version, latestVersion } )
3536 ) ,
36- changedNotNeededPackages : cp . changedNotNeededPackages . map ( ( p ) => p . name ) ,
37+ changedNotNeededPackages : cp . changedNotNeededPackages . map ( ( { pkg : { name } , version } ) => ( { name, version } ) ) ,
3738 } ;
3839 await writeDataFile ( versionsFilename , json ) ;
3940 return cp ;
@@ -64,32 +65,50 @@ async function computeChangedPackages(allPackages: AllPackages, log: LoggerWithE
6465 } ) ;
6566 log . info ( "# Computing deprecated packages..." ) ;
6667 const changedNotNeededPackages = await mapDefinedAsync ( allPackages . allNotNeeded ( ) , async ( pkg ) => {
67- if ( ! ( await isAlreadyDeprecated ( pkg , log ) ) ) {
68+ const incipientVersion = await fetchIncipientStubVersion ( pkg , log ) ;
69+ if ( incipientVersion ) {
6870 await pacote . manifest ( pkg . libraryName , { cache : defaultCacheDir } ) . catch ( ( cause ) => {
6971 throw cause . code === "E404"
7072 ? new Error ( `To deprecate '@types/${ pkg . name } ', '${ pkg . libraryName } ' must exist on npm.` , { cause } )
7173 : cause ;
7274 } ) ;
7375 log . info ( `To be deprecated: ${ pkg . name } ` ) ;
74- return pkg ;
76+ return { pkg, version : incipientVersion } ;
7577 }
7678 return undefined ;
7779 } ) ;
7880 return { changedTypings, changedNotNeededPackages } ;
7981}
8082
81- async function isAlreadyDeprecated ( pkg : NotNeededPackage , log : LoggerWithErrors ) : Promise < unknown > {
82- const offline = await pacote . manifest ( pkg . fullNpmName , {
83- cache : defaultCacheDir ,
84- fullMetadata : true ,
85- preferOffline : true ,
86- } ) ;
87- if ( ! offline . _cached || offline . deprecated ) return offline . deprecated ;
88- log . info ( `Version info not cached for deprecated package ${ pkg . desc } ` ) ;
89- const online = await pacote . manifest ( pkg . fullNpmName , {
90- cache : defaultCacheDir ,
91- fullMetadata : true ,
92- preferOnline : true ,
93- } ) ;
94- return online . deprecated ;
83+ /**
84+ * Return the version of the stub @types package we're about to publish and deprecate, if we haven't already deprecated that package.
85+ * It's the max of the not-needed version and the max published version + 1, in case we already published a not-needed-versioned stub but failed to deprecate it, for whatever reason.
86+ */
87+ export async function fetchIncipientStubVersion ( pkg : NotNeededPackage , log : LoggerWithErrors ) : Promise < string | false > {
88+ const packument = await revalidate ( ) ;
89+ return (
90+ ! packument . deprecated &&
91+ String (
92+ semver . maxSatisfying (
93+ [ pkg . version , semver . inc ( semver . maxSatisfying ( Object . keys ( packument . versions ) , "*" ) ! , "patch" ) ! ] ,
94+ "*"
95+ )
96+ )
97+ ) ;
98+
99+ async function revalidate ( ) {
100+ const offline = await pacote . packument ( pkg . fullNpmName , {
101+ cache : defaultCacheDir ,
102+ fullMetadata : true ,
103+ preferOffline : true ,
104+ } ) ;
105+ if ( ! offline . _cached || offline . deprecated ) return offline ;
106+ log . info ( `Version info not cached for deprecated package ${ pkg . desc } ` ) ;
107+ const online = await pacote . packument ( pkg . fullNpmName , {
108+ cache : defaultCacheDir ,
109+ fullMetadata : true ,
110+ preferOnline : true ,
111+ } ) ;
112+ return online ;
113+ }
95114}
0 commit comments