@@ -11,6 +11,7 @@ import {
11
11
} from "@definitelytyped/utils" ;
12
12
import { fetchTypesPackageVersionInfo } from "@definitelytyped/retag" ;
13
13
import * as pacote from "pacote" ;
14
+ import * as semver from "semver" ;
14
15
15
16
if ( ! module . parent ) {
16
17
const log = loggerWithErrors ( ) [ 0 ] ;
@@ -33,7 +34,7 @@ async function computeAndSaveChangedPackages(
33
34
changedTypings : cp . changedTypings . map (
34
35
( { pkg : { id } , version, latestVersion } ) : ChangedTypingJson => ( { id, version, latestVersion } )
35
36
) ,
36
- changedNotNeededPackages : cp . changedNotNeededPackages . map ( ( p ) => p . name ) ,
37
+ changedNotNeededPackages : cp . changedNotNeededPackages . map ( ( { pkg : { name } , version } ) => ( { name, version } ) ) ,
37
38
} ;
38
39
await writeDataFile ( versionsFilename , json ) ;
39
40
return cp ;
@@ -64,32 +65,50 @@ async function computeChangedPackages(allPackages: AllPackages, log: LoggerWithE
64
65
} ) ;
65
66
log . info ( "# Computing deprecated packages..." ) ;
66
67
const changedNotNeededPackages = await mapDefinedAsync ( allPackages . allNotNeeded ( ) , async ( pkg ) => {
67
- if ( ! ( await isAlreadyDeprecated ( pkg , log ) ) ) {
68
+ const incipientVersion = await fetchIncipientStubVersion ( pkg , log ) ;
69
+ if ( incipientVersion ) {
68
70
await pacote . manifest ( pkg . libraryName , { cache : defaultCacheDir } ) . catch ( ( cause ) => {
69
71
throw cause . code === "E404"
70
72
? new Error ( `To deprecate '@types/${ pkg . name } ', '${ pkg . libraryName } ' must exist on npm.` , { cause } )
71
73
: cause ;
72
74
} ) ;
73
75
log . info ( `To be deprecated: ${ pkg . name } ` ) ;
74
- return pkg ;
76
+ return { pkg, version : incipientVersion } ;
75
77
}
76
78
return undefined ;
77
79
} ) ;
78
80
return { changedTypings, changedNotNeededPackages } ;
79
81
}
80
82
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
+ }
95
114
}
0 commit comments