1const puppeteer = require('puppeteer'); 2 3const url = process.argv[2]; 4 5if (!url) { 6 console.error(`You need to provide the base URL for links as a parameter.`); 7 process.exit(-1); 8} 9 10const externalLinks = [ 11 '/versions/latest/workflow/expo-cli/', // https://github.com/expo/expo-cli/blob/main/packages/expo-cli/README.md and https://github.com/expo/expo-cli/blob/main/README.md 12 '/versions/latest/workflow/configuration/', // https://github.com/expo/expo-cli/blob/main/CONTRIBUTING.md and https://github.com/expo/expo-cli/blob/main/packages/expo-cli/src/commands/init.js and https://github.com/expo/expo-cli/blob/main/packages/xdl/src/project/Doctor.js 13 // https://github.com/expo/expo-cli/blob/4e16a55e98e0612f71685ed16b3b5f8405219d4a/packages/xdl/README.md#xdl [Documentation](https://docs.expo.dev/versions/devdocs/index.html) 14 '/versions/latest/distribution/building-standalone-apps/#switch-to-push-notification-key-on-ios', // https://github.com/expo/expo-cli/blob/main/packages/expo-cli/src/commands/build/ios/credentials/constants.js 15 '/versions/latest/distribution/building-standalone-apps/#2-configure-appjson', // https://github.com/expo/expo-cli/blob/main/packages/expo-cli/src/commands/build/AndroidBuilder.js 16 '/versions/latest/distribution/building-standalone-apps/#if-you-choose-to-build-for-android', // https://github.com/expo/expo-cli/blob/main/packages/expo-cli/src/commands/build/AndroidBuilder.js 17 '/versions/latest/distribution/uploading-apps/', // https://github.com/expo/expo-cli/blob/main/packages/expo-cli/src/commands/upload/BaseUploader.js 18 '/versions/latest/workflow/linking/', // https://github.com/expo/expo-cli/blob/main/packages/xdl/src/detach/Detach.js 19 '/versions/latest/workflow/configuration/#ios', // https://github.com/expo/expo-cli/blob/main/packages/xdl/src/detach/Detach.js 20 '/versions/latest/guides/splash-screens/#differences-between-environments---android', // https://github.com/expo/expo-cli/blob/main/packages/xdl/src/Android.js 21 '/versions/latest/sdk/overview/', // https://github.com/expo/expo-cli/blob/main/packages/xdl/src/project/Convert.js 22 '/versions/latest/distribution/building-standalone-apps/#2-configure-appjson', // https://github.com/expo/expo-cli/blob/main/packages/expo-cli/src/commands/build/ios/IOSBuilder.js 23 '/versions/latest/expokit/eject/', // https://github.com/expo/expo-cli/blob/main/packages/expo-cli/src/commands/eject/Eject.js 24 '/versions/latest/introduction/faq/#can-i-use-nodejs-packages-with-expo', // https://github.com/expo/expo-cli/blob/main/packages/xdl/src/logs/PackagerLogsStream.js 25]; 26 27(async () => { 28 try { 29 const notFound = []; 30 const redirectsFailed = []; 31 32 const browser = await puppeteer.launch(); 33 const page = await browser.newPage(); 34 35 for (const link of externalLinks) { 36 const response = await page.goto(`${url}${link}`); 37 if (response.status() === 404) { 38 await page.waitForFunction( 39 () => document.querySelector('#redirect-link') || document.querySelector('#__not_found'), 40 { timeout: 500 } 41 ); 42 if (await page.$('#redirect-link')) { 43 await Promise.all([page.waitForNavigation(), page.click('#redirect-link')]); 44 console.info(`Redirected from ${link} to ${page.url()}`); 45 try { 46 await page.waitForFunction( 47 () => 48 document.querySelector('#__redirect_failed') || 49 document.querySelector('#__not_found'), 50 { timeout: 500 } 51 ); 52 console.debug(`Redirect failed`); 53 redirectsFailed.push(link); 54 } catch { 55 console.debug(`Redirect successful`); 56 } 57 } else { 58 console.debug(`Couldn't find ${link}`); 59 notFound.push(link); 60 } 61 } 62 } 63 await browser.close(); 64 65 if (notFound.length || redirectsFailed.length) { 66 if (notFound.length) { 67 console.error(`Pages not found for links: ${notFound.join(',')}`); 68 } else if (redirectsFailed.length) { 69 console.error(`Redirects failed for links: ${redirectsFailed.join(',')}`); 70 } 71 process.exit(-1); 72 } 73 } catch (e) { 74 console.error(e); 75 process.exit(-1); 76 } 77})(); 78