| 
									
										
										
										
											2018-05-24 15:06:53 +03:00
										 |  |  | import { resolve as resolvePath } from 'canonical-path'; | 
					
						
							| 
									
										
										
										
											2018-02-28 01:14:28 +02:00
										 |  |  | import { load as loadJson } from 'cjson'; | 
					
						
							|  |  |  | import { readFileSync } from 'fs'; | 
					
						
							| 
									
										
										
										
											2018-02-28 01:24:07 +02:00
										 |  |  | import { get as httpGet } from 'http'; | 
					
						
							|  |  |  | import { get as httpsGet } from 'https'; | 
					
						
							| 
									
										
										
										
											2018-01-25 10:13:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-24 15:06:53 +03:00
										 |  |  | import { processNavigationUrls } from '../../../../packages/service-worker/config/src/generator'; | 
					
						
							| 
									
										
										
										
											2018-02-28 01:14:28 +02:00
										 |  |  | import { FirebaseRedirector, FirebaseRedirectConfig } from '../../../tools/firebase-test-utils/FirebaseRedirector'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-24 15:06:53 +03:00
										 |  |  | const AIO_DIR = resolvePath(__dirname, '../../..'); | 
					
						
							| 
									
										
										
										
											2018-01-25 10:13:30 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | export function getRedirector() { | 
					
						
							|  |  |  |   return new FirebaseRedirector(loadRedirects()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-24 15:06:53 +03:00
										 |  |  | export function getSwNavigationUrlChecker() { | 
					
						
							|  |  |  |   const config = loadJson(`${AIO_DIR}/ngsw-config.json`); | 
					
						
							|  |  |  |   const navigationUrlSpecs = processNavigationUrls('', config.navigationUrls); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const includePatterns = navigationUrlSpecs | 
					
						
							|  |  |  |       .filter(spec => spec.positive) | 
					
						
							|  |  |  |       .map(spec => new RegExp(spec.regex)); | 
					
						
							|  |  |  |   const excludePatterns = navigationUrlSpecs | 
					
						
							|  |  |  |       .filter(spec => !spec.positive) | 
					
						
							|  |  |  |       .map(spec => new RegExp(spec.regex)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return (url: string) => | 
					
						
							|  |  |  |     includePatterns.some(regex => regex.test(url)) | 
					
						
							|  |  |  |     && !excludePatterns.some(regex => regex.test(url)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-25 10:13:30 +00:00
										 |  |  | export function loadRedirects(): FirebaseRedirectConfig[] { | 
					
						
							| 
									
										
										
										
											2018-02-28 01:14:28 +02:00
										 |  |  |   const pathToFirebaseJSON = `${AIO_DIR}/firebase.json`; | 
					
						
							|  |  |  |   const contents = loadJson(pathToFirebaseJSON); | 
					
						
							| 
									
										
										
										
											2018-01-25 10:13:30 +00:00
										 |  |  |   return contents.hosting.redirects; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export function loadLegacyUrls() { | 
					
						
							| 
									
										
										
										
											2018-02-28 01:14:28 +02:00
										 |  |  |   const pathToLegacyUrls = `${__dirname}/URLS_TO_REDIRECT.txt`; | 
					
						
							| 
									
										
										
										
											2018-01-25 10:13:30 +00:00
										 |  |  |   const urls = readFileSync(pathToLegacyUrls, 'utf8').split('\n').map(line => line.split('\t')); | 
					
						
							|  |  |  |   return urls; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2018-01-25 20:19:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-28 01:24:07 +02:00
										 |  |  | export function loadLocalSitemapUrls() { | 
					
						
							|  |  |  |   const pathToSiteMap = `${AIO_DIR}/src/generated/sitemap.xml`; | 
					
						
							|  |  |  |   const xml = readFileSync(pathToSiteMap, 'utf8'); | 
					
						
							|  |  |  |   return extractSitemapUrls(xml); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export async function loadRemoteSitemapUrls(host: string) { | 
					
						
							| 
									
										
										
										
											2018-08-23 21:24:14 +03:00
										 |  |  |   host = host.replace(/\/$/, ''); | 
					
						
							| 
									
										
										
										
											2018-02-28 01:24:07 +02:00
										 |  |  |   const urlToSiteMap = `${host}/generated/sitemap.xml`; | 
					
						
							|  |  |  |   const get = /^https:/.test(host) ? httpsGet : httpGet; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const xml = await new Promise<string>((resolve, reject) => { | 
					
						
							|  |  |  |     let responseText = ''; | 
					
						
							|  |  |  |     get(urlToSiteMap, res => res | 
					
						
							|  |  |  |         .on('data', chunk => responseText += chunk) | 
					
						
							|  |  |  |         .on('end', () => resolve(responseText)) | 
					
						
							|  |  |  |         .on('error', reject)); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-25 00:25:34 +03:00
										 |  |  |   return extractSitemapUrls(xml); | 
					
						
							| 
									
										
										
										
											2018-02-28 01:24:07 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Private functions
 | 
					
						
							| 
									
										
										
										
											2018-05-25 00:25:34 +03:00
										 |  |  | function extractSitemapUrls(xml: string) { | 
					
						
							|  |  |  |   // Currently, all sitemaps use `angular.io` as host in URLs (which is fine since we only use the
 | 
					
						
							|  |  |  |   // sitemap in `angular.io`). See also `aio/src/extra-files/*/robots.txt`.
 | 
					
						
							|  |  |  |   const host = 'https://angular.io'; | 
					
						
							| 
									
										
										
										
											2018-02-28 01:24:07 +02:00
										 |  |  |   const urls: string[] = []; | 
					
						
							| 
									
										
										
										
											2018-05-25 00:25:34 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-28 01:24:07 +02:00
										 |  |  |   xml.replace(/<loc>([^<]+)<\/loc>/g, (_, loc) => urls.push(loc.replace(host, '')) as any); | 
					
						
							| 
									
										
										
										
											2018-05-25 00:25:34 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // Ensure none of the URLs contains the scheme/host.
 | 
					
						
							|  |  |  |   // (That would mean that the URL contains a different than expected host, which can in turn lead
 | 
					
						
							|  |  |  |   // to tests passing while they shouldn't).
 | 
					
						
							|  |  |  |   urls.forEach(url => { | 
					
						
							|  |  |  |     if (url.includes('://')) { | 
					
						
							|  |  |  |       throw new Error(`Sitemap URL (${url}) contains unexpected host. Expected: ${host}`); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-28 01:24:07 +02:00
										 |  |  |   return urls; | 
					
						
							|  |  |  | } |