@@ -84,33 +84,6 @@ export async function getLatestVersionFromNpm(): Promise<string> {
8484 }
8585}
8686
87- /**
88- * Checks if the provided version is available on the CDN.
89- * @param {string } version - The version to check.
90- * @returns {Promise<boolean> } A promise resolving to a boolean indicating if the version is available on the CDN.
91- */
92- async function isVersionAvailableOnCDN ( version : string ) : Promise < boolean > {
93- const files = [ 'widgets-esm.js' , 'widgets.js' ] ;
94- const baseUrl = `https://cdn.jsdelivr.net/npm/@imtbl/sdk@${ version } /dist/browser/checkout/` ;
95-
96- try {
97- const checks = files . map ( async ( file ) => {
98- const response = await fetch ( `${ baseUrl } ${ file } ` , { method : 'HEAD' } ) ;
99- if ( ! response . ok ) {
100- return false ;
101- }
102- return true ;
103- } ) ;
104-
105- const results = await Promise . all ( checks ) ;
106- const allFilesAvailable = results . every ( ( isAvailable ) => isAvailable ) ;
107-
108- return allFilesAvailable ;
109- } catch {
110- return false ;
111- }
112- }
113-
11487/**
11588 * Returns the latest compatible version based on the provided checkout version config.
11689 * If no compatible version markers are provided, it returns 'latest'.
@@ -127,6 +100,40 @@ function latestCompatibleVersion(
127100 return 'latest' ;
128101}
129102
103+ /**
104+ * Checks if the last_updated.json file exists on the CDN and validates its timestamp.
105+ * @param {string } version - The version to check.
106+ * @returns {Promise<boolean> } A promise resolving to `true` if last_updated.json exists and is older than 15 minutes, `false` otherwise.
107+ */
108+ async function checkLastUpdatedTimestamp ( version : string ) : Promise < boolean > {
109+ const WAIT_TIME_IN_MINUTES = 20 ;
110+
111+ const lastUpdatedJsonUrl = `https://cdn.jsdelivr.net/npm/@imtbl/sdk@${ version } /dist/last_updated.json` ;
112+
113+ try {
114+ const response = await fetch ( lastUpdatedJsonUrl ) ;
115+
116+ if ( ! response . ok ) {
117+ return false ;
118+ }
119+
120+ const lastUpdatedData = await response . json ( ) ;
121+
122+ if ( lastUpdatedData . timestamp ) {
123+ const timestamp = new Date ( lastUpdatedData . timestamp ) ;
124+ const now = new Date ( ) ;
125+ const diffInMs = now . getTime ( ) - timestamp . getTime ( ) ;
126+ const diffInMinutes = diffInMs / ( 1000 * 60 ) ;
127+
128+ return diffInMinutes > WAIT_TIME_IN_MINUTES ;
129+ }
130+ } catch ( error ) {
131+ return false ;
132+ }
133+
134+ return false ;
135+ }
136+
130137/**
131138 * Determines the version of the widgets to use based on the provided validated build version and checkout version config.
132139 * If a version is provided in the widget init parameters, it uses that version.
@@ -158,13 +165,14 @@ export async function determineWidgetsVersion(
158165 versionConfig . compatibleVersionMarkers ,
159166 ) ;
160167
161- // If `latest` is returned, query NPM registry for the actual latest version and check if it's available on the CDN
168+ // If `latest` is returned, query NPM registry for the actual latest version and check timestamp
162169 if ( compatibleVersion === 'latest' ) {
163170 const latestVersion = await getLatestVersionFromNpm ( ) ;
164- const isAvailable = await isVersionAvailableOnCDN ( latestVersion ) ;
165- if ( isAvailable ) {
171+
172+ if ( await checkLastUpdatedTimestamp ( latestVersion ) ) {
166173 return latestVersion ;
167174 }
175+
168176 return 'latest' ;
169177 }
170178
0 commit comments