{"version":3,"sources":["../../../../src/build/webpack/loaders/next-metadata-image-loader.ts"],"sourcesContent":["/*\n * This loader is responsible for extracting the metadata image info for rendering in html\n */\n\nimport type webpack from 'webpack'\nimport type {\n  MetadataImageModule,\n  PossibleImageFileNameConvention,\n} from './metadata/types'\nimport { existsSync, promises as fs } from 'fs'\nimport path from 'path'\nimport loaderUtils from 'next/dist/compiled/loader-utils3'\nimport { getImageSize } from '../../../server/image-optimizer'\nimport { imageExtMimeTypeMap } from '../../../lib/mime-type'\nimport { WEBPACK_RESOURCE_QUERIES } from '../../../lib/constants'\nimport { normalizePathSep } from '../../../shared/lib/page-path/normalize-path-sep'\nimport type { PageExtensions } from '../../page-extensions-type'\nimport { getLoaderModuleNamedExports } from './utils'\n\ninterface Options {\n  segment: string\n  type: PossibleImageFileNameConvention\n  pageExtensions: PageExtensions\n  basePath: string\n}\n\n// [NOTE] For turbopack, refer to app_page_loader_tree's write_metadata_item for\n// corresponding features.\nasync function nextMetadataImageLoader(\n  this: webpack.LoaderContext<Options>,\n  content: Buffer\n) {\n  const options: Options = this.getOptions()\n  const { type, segment, pageExtensions, basePath } = options\n  const { resourcePath, rootContext: context } = this\n  const { name: fileNameBase, ext } = path.parse(resourcePath)\n  const useNumericSizes = type === 'twitter' || type === 'openGraph'\n\n  let extension = ext.slice(1)\n  if (extension === 'jpg') {\n    extension = 'jpeg'\n  }\n\n  const opts = { context, content }\n\n  // No hash query for favicon.ico\n  const contentHash =\n    type === 'favicon'\n      ? ''\n      : loaderUtils.interpolateName(this, '[contenthash]', opts)\n\n  const interpolatedName = loaderUtils.interpolateName(\n    this,\n    '[name].[ext]',\n    opts\n  )\n\n  const isDynamicResource = pageExtensions.includes(extension)\n  const pageSegment = isDynamicResource ? fileNameBase : interpolatedName\n  const hashQuery = contentHash ? '?' + contentHash : ''\n  const pathnamePrefix = normalizePathSep(path.join(basePath, segment))\n\n  if (isDynamicResource) {\n    const exportedFieldsExcludingDefault = (\n      await getLoaderModuleNamedExports(resourcePath, this)\n    ).filter((name) => name !== 'default')\n\n    // re-export and spread as `exportedImageData` to avoid non-exported error\n    return `\\\n    import {\n      ${exportedFieldsExcludingDefault\n        .map((field) => `${field} as _${field}`)\n        .join(',')}\n    } from ${JSON.stringify(\n      // This is an arbitrary resource query to ensure it's a new request, instead\n      // of sharing the same module with next-metadata-route-loader.\n      // Since here we only need export fields such as `size`, `alt` and\n      // `generateImageMetadata`, avoid sharing the same module can make this entry\n      // smaller.\n      resourcePath + '?' + WEBPACK_RESOURCE_QUERIES.metadataImageMeta\n    )}\n    import { fillMetadataSegment } from 'next/dist/lib/metadata/get-metadata-route'\n\n    const imageModule = {\n      ${exportedFieldsExcludingDefault\n        .map((field) => `${field}: _${field}`)\n        .join(',')}\n    }\n\n    export default async function (props) {\n      const { __metadata_id__: _, ...params } = await props.params\n      const imageUrl = fillMetadataSegment(${JSON.stringify(\n        pathnamePrefix\n      )}, params, ${JSON.stringify(pageSegment)})\n\n      const { generateImageMetadata } = imageModule\n\n      function getImageMetadata(imageMetadata, idParam) {\n        const data = {\n          alt: imageMetadata.alt,\n          type: imageMetadata.contentType || 'image/png',\n          url: imageUrl + (idParam ? ('/' + idParam) : '') + ${JSON.stringify(\n            hashQuery\n          )},\n        }\n        const { size } = imageMetadata\n        if (size) {\n          ${\n            type === 'twitter' || type === 'openGraph'\n              ? 'data.width = size.width; data.height = size.height;'\n              : 'data.sizes = size.width + \"x\" + size.height;'\n          }\n        }\n        return data\n      }\n\n      if (generateImageMetadata) {\n        const imageMetadataArray = await generateImageMetadata({ params })\n        return imageMetadataArray.map((imageMetadata, index) => {\n          const idParam = (imageMetadata.id || index) + ''\n          return getImageMetadata(imageMetadata, idParam)\n        })\n      } else {\n        return [getImageMetadata(imageModule, '')]\n      }\n    }`\n  }\n\n  const imageSize: { width?: number; height?: number } = await getImageSize(\n    content\n  ).catch((err) => err)\n\n  if (imageSize instanceof Error) {\n    const err = imageSize\n    err.name = 'InvalidImageFormatError'\n    throw err\n  }\n\n  const imageData: Omit<MetadataImageModule, 'url'> = {\n    ...(extension in imageExtMimeTypeMap && {\n      type: imageExtMimeTypeMap[extension as keyof typeof imageExtMimeTypeMap],\n    }),\n    ...(useNumericSizes && imageSize.width != null && imageSize.height != null\n      ? imageSize\n      : {\n          sizes:\n            // For SVGs, skip sizes and use \"any\" to let it scale automatically based on viewport,\n            // For the images doesn't provide the size properly, use \"any\" as well.\n            // If the size is presented, use the actual size for the image.\n            extension !== 'svg' &&\n            imageSize.width != null &&\n            imageSize.height != null\n              ? `${imageSize.width}x${imageSize.height}`\n              : 'any',\n        }),\n  }\n  if (type === 'openGraph' || type === 'twitter') {\n    const altPath = path.join(\n      path.dirname(resourcePath),\n      fileNameBase + '.alt.txt'\n    )\n\n    if (existsSync(altPath)) {\n      imageData.alt = await fs.readFile(altPath, 'utf8')\n    }\n  }\n\n  return `\\\n  import { fillMetadataSegment } from 'next/dist/lib/metadata/get-metadata-route'\n\n  export default async (props) => {\n    const imageData = ${JSON.stringify(imageData)}\n    const imageUrl = fillMetadataSegment(${JSON.stringify(\n      pathnamePrefix\n    )}, await props.params, ${JSON.stringify(pageSegment)})\n\n    return [{\n      ...imageData,\n      url: imageUrl + ${JSON.stringify(type === 'favicon' ? '' : hashQuery)},\n    }]\n  }`\n}\n\nexport const raw = true\nexport default nextMetadataImageLoader\n"],"names":["existsSync","promises","fs","path","loaderUtils","getImageSize","imageExtMimeTypeMap","WEBPACK_RESOURCE_QUERIES","normalizePathSep","getLoaderModuleNamedExports","nextMetadataImageLoader","content","options","getOptions","type","segment","pageExtensions","basePath","resourcePath","rootContext","context","name","fileNameBase","ext","parse","useNumericSizes","extension","slice","opts","contentHash","interpolateName","interpolatedName","isDynamicResource","includes","pageSegment","hashQuery","pathnamePrefix","join","exportedFieldsExcludingDefault","filter","map","field","JSON","stringify","metadataImageMeta","imageSize","catch","err","Error","imageData","width","height","sizes","altPath","dirname","alt","readFile","raw"],"mappings":"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","ignoreList":[0]}