TSLint deprecated and is being replaced by ESLint. Add Vue CLI plugin (@vue/cli-plugin-eslint) using: `vue add @vue/cli-plugin-eslint`. It also adds `.eslintrc.js` manually for Cypress since Vue CLI for ESLint misses it (vuejs/vue-cli#6892). Also rename `npm run lint:vue` to `npm run lint:eslint` for better clarification. This commit disables all rules that the current code is not compliant with. This allows for enabling them gradually and separating commits instead of mixing ESLint introduction with other code changes. AirBnb is chosen as base configuration. "Standard" is not chosen due to its poor defaults. It makes code cleaner but harder to maintain: - It converts interfaces to types which is harder to read. - Removes semicolons that helps to eliminate some ambigious code. "Airbnb" on the other hand helps for easier future changes and maintinability: - Includes more useful rules. - Keeps the semicolons and interfaces. - Enforces trailing commas that makes it easier to delete lines later on. - Delete branches: standard, prettier.
55 lines
2.0 KiB
TypeScript
55 lines
2.0 KiB
TypeScript
import { retryWithExponentialBackOff } from './ExponentialBackOffRetryHandler';
|
||
import { IUrlStatus } from './IUrlStatus';
|
||
import { fetchFollow, IFollowOptions } from './FetchFollow';
|
||
|
||
export async function getUrlStatus(
|
||
url: string,
|
||
options: IRequestOptions = DefaultOptions): Promise<IUrlStatus> {
|
||
options = { ...DefaultOptions, ...options };
|
||
const fetchOptions = getFetchOptions(url, options);
|
||
return retryWithExponentialBackOff(async () => {
|
||
console.log('Requesting', url);
|
||
let result: IUrlStatus;
|
||
try {
|
||
const response = await fetchFollow(url, fetchOptions, options.followOptions);
|
||
result = { url, code: response.status };
|
||
} catch (err) {
|
||
result = { url, error: err };
|
||
}
|
||
return result;
|
||
}, options.retryExponentialBaseInMs);
|
||
}
|
||
|
||
export interface IRequestOptions {
|
||
retryExponentialBaseInMs?: number;
|
||
additionalHeaders?: Record<string, string>;
|
||
additionalHeadersUrlIgnore?: string[];
|
||
followOptions?: IFollowOptions;
|
||
}
|
||
|
||
const DefaultOptions: IRequestOptions = {
|
||
retryExponentialBaseInMs: 5000,
|
||
additionalHeaders: {},
|
||
additionalHeadersUrlIgnore: [],
|
||
};
|
||
|
||
function getFetchOptions(url: string, options: IRequestOptions): RequestInit {
|
||
const additionalHeaders = options.additionalHeadersUrlIgnore.some(
|
||
(ignorePattern) => url.match(ignorePattern)) ? {} : options.additionalHeaders;
|
||
return {
|
||
method: 'GET',
|
||
headers: { ...DefaultHeaders, ...additionalHeaders },
|
||
};
|
||
}
|
||
|
||
const DefaultHeaders: Record<string, string> = {
|
||
/* Chrome on macOS */
|
||
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36',
|
||
'upgrade-insecure-requests': '1',
|
||
'connection': 'keep-alive',
|
||
'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
|
||
'accept-encoding': 'gzip, deflate, br',
|
||
'cache-control': 'max-age=0',
|
||
'accept-language': 'en-US,en;q=0.9',
|
||
};
|