80 lines
3.3 KiB
Plaintext
80 lines
3.3 KiB
Plaintext
"use strict";
|
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.fetchCSSFromGoogleFonts = void 0;
|
|
// @ts-ignore
|
|
const node_fetch_1 = __importDefault(require("next/dist/compiled/node-fetch"));
|
|
const next_font_error_1 = require("../next-font-error");
|
|
const get_proxy_agent_1 = require("./get-proxy-agent");
|
|
async function retry(fn, attempts) {
|
|
let cnt = attempts;
|
|
while (true) {
|
|
try {
|
|
return await fn();
|
|
}
|
|
catch (err) {
|
|
cnt--;
|
|
if (cnt <= 0)
|
|
throw err;
|
|
console.error(err.message + `\n\nRetrying ${attempts - cnt}/3...`);
|
|
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
}
|
|
}
|
|
}
|
|
/**
|
|
* Fetches the CSS containing the @font-face declarations from Google Fonts.
|
|
* The fetch has a user agent header with a modern browser to ensure we'll get .woff2 files.
|
|
*
|
|
* The env variable NEXT_FONT_GOOGLE_MOCKED_RESPONSES may be set containing a path to mocked data.
|
|
* It's used to define mocked data to avoid hitting the Google Fonts API during tests.
|
|
*/
|
|
async function fetchCSSFromGoogleFonts(url, fontFamily, isDev) {
|
|
// Check if mocked responses are defined, if so use them instead of fetching from Google Fonts
|
|
let mockedResponse;
|
|
if (process.env.NEXT_FONT_GOOGLE_MOCKED_RESPONSES) {
|
|
const mockFile = require(process.env.NEXT_FONT_GOOGLE_MOCKED_RESPONSES);
|
|
mockedResponse = mockFile[url];
|
|
if (!mockedResponse) {
|
|
(0, next_font_error_1.nextFontError)('Missing mocked response for URL: ' + url);
|
|
}
|
|
}
|
|
let cssResponse;
|
|
if (mockedResponse) {
|
|
// Just use the mocked CSS if it's set
|
|
cssResponse = mockedResponse;
|
|
}
|
|
else {
|
|
// Retry the fetch a few times in case of network issues as some font files
|
|
// are quite large:
|
|
// https://github.com/vercel/next.js/issues/45080
|
|
cssResponse = await retry(async () => {
|
|
const controller = isDev && typeof AbortController !== 'undefined'
|
|
? new AbortController()
|
|
: undefined;
|
|
const signal = controller === null || controller === void 0 ? void 0 : controller.signal;
|
|
const timeoutId = controller
|
|
? setTimeout(() => controller.abort(), 3000)
|
|
: undefined;
|
|
const res = await (0, node_fetch_1.default)(url, {
|
|
agent: (0, get_proxy_agent_1.getProxyAgent)(),
|
|
// Add a timeout in dev
|
|
signal,
|
|
headers: {
|
|
// The file format is based off of the user agent, make sure woff2 files are fetched
|
|
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36',
|
|
},
|
|
}).finally(() => {
|
|
timeoutId && clearTimeout(timeoutId);
|
|
});
|
|
if (!res.ok) {
|
|
(0, next_font_error_1.nextFontError)(`Failed to fetch font \`${fontFamily}\`.\nURL: ${url}\n\nPlease check if the network is available.`);
|
|
}
|
|
return res.text();
|
|
}, 3);
|
|
}
|
|
return cssResponse;
|
|
}
|
|
exports.fetchCSSFromGoogleFonts = fetchCSSFromGoogleFonts;
|