"use strict";exports.__esModule=true;exports.default=void 0;var _webpackSources=require("webpack-sources");var _fontUtils=require("../../../next-server/server/font-utils");var _BasicEvaluatedExpression=_interopRequireDefault(require("webpack/lib/BasicEvaluatedExpression"));var _constants=require("../../../next-server/lib/constants");function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj};}// eslint-disable-next-line import/no-extraneous-dependencies
// @ts-ignore
class FontStylesheetGatheringPlugin{constructor(){this.compiler=void 0;this.gatheredStylesheets=[];this.parserHandler=factory=>{const JS_TYPES=['auto','esm','dynamic'];// Do an extra walk per module and add interested visitors to the walk.
for(const type of JS_TYPES){factory.hooks.parser.for('javascript/'+type).tap(this.constructor.name,parser=>{/**
           * Webpack fun facts:
           * `parser.hooks.call.for` cannot catch calls for user defined identifiers like `__jsx`
           * it can only detect calls for native objects like `window`, `this`, `eval` etc.
           * In order to be able to catch calls of variables like `__jsx`, first we need to catch them as
           * Identifier and then return `BasicEvaluatedExpression` whose `id` and `type` webpack matches to
           * invoke hook for call.
           * See: https://github.com/webpack/webpack/blob/webpack-4/lib/Parser.js#L1931-L1932.
           */parser.hooks.evaluate.for('Identifier').tap(this.constructor.name,node=>{var _parser$state,_parser$state$module;// We will only optimize fonts from first party code.
if(parser===null||parser===void 0?void 0:(_parser$state=parser.state)===null||_parser$state===void 0?void 0:(_parser$state$module=_parser$state.module)===null||_parser$state$module===void 0?void 0:_parser$state$module.resource.includes('node_modules')){return;}return node.name==='__jsx'?new _BasicEvaluatedExpression.default()//@ts-ignore
.setRange(node.range).setExpression(node).setIdentifier('__jsx'):undefined;});parser.hooks.call.for('__jsx').tap(this.constructor.name,node=>{if(node.arguments.length!==2){// A font link tag has only two arguments rel=stylesheet and href='...'
return;}if(!isNodeCreatingLinkElement(node)){return;}// node.arguments[0] is the name of the tag and [1] are the props.
const propsNode=node.arguments[1];const props={};propsNode.properties.forEach(prop=>{if(prop.type!=='Property'){return;}if(prop.key.type==='Identifier'&&prop.value.type==='Literal'){props[prop.key.name]=prop.value.value;}});if(!props.rel||props.rel!=='stylesheet'||!props.href||!_constants.OPTIMIZED_FONT_PROVIDERS.some(url=>props.href.startsWith(url))){return false;}this.gatheredStylesheets.push(props.href);});});}};}apply(compiler){this.compiler=compiler;compiler.hooks.normalModuleFactory.tap(this.constructor.name,this.parserHandler);compiler.hooks.make.tapAsync(this.constructor.name,(compilation,cb)=>{compilation.hooks.finishModules.tapAsync(this.constructor.name,async(_,modulesFinished)=>{const fontDefinitionPromises=this.gatheredStylesheets.map(url=>(0,_fontUtils.getFontDefinitionFromNetwork)(url));let manifestContent=[];for(let promiseIndex in fontDefinitionPromises){manifestContent.push({url:this.gatheredStylesheets[promiseIndex],content:await fontDefinitionPromises[promiseIndex]});}compilation.assets['font-manifest.json']=new _webpackSources.RawSource(JSON.stringify(manifestContent,null,'  '));modulesFinished();});cb();});}}exports.default=FontStylesheetGatheringPlugin;function isNodeCreatingLinkElement(node){const callee=node.callee;if(callee.type!=='Identifier'){return false;}const componentNode=node.arguments[0];if(componentNode.type!=='Literal'){return false;}// Next has pragma: __jsx.
return callee.name==='__jsx'&&componentNode.value==='link';}
//# sourceMappingURL=font-stylesheet-gathering-plugin.js.map