next.js/packages/next/src/server/web/sandbox/fetch-inline-assets.ts
fetch-inline-assets.ts46 lines1.3 KB
import type { EdgeFunctionDefinition } from '../../../build/webpack/plugins/middleware-plugin'
import { createReadStream, promises as fs } from 'fs'
import { requestToBodyStream } from '../../body-streams'
import { resolve } from 'path'

/**
 * Short-circuits the `fetch` function
 * to return a stream for a given asset, if a user used `new URL("file", import.meta.url)`.
 * This allows to embed assets in Edge Runtime.
 */
export async function fetchInlineAsset(options: {
  input: RequestInfo | URL
  distDir: string
  assets: EdgeFunctionDefinition['assets']
  context: { Response: typeof Response; ReadableStream: typeof ReadableStream }
}): Promise<Response | undefined> {
  const inputString = String(options.input)
  if (!inputString.startsWith('blob:')) {
    return
  }

  const name = inputString.replace('blob:', '')
  const asset = options.assets
    ? options.assets.find((x) => x.name === name)
    : {
        name,
        filePath: name,
      }
  if (!asset) {
    return
  }

  const filePath = resolve(options.distDir, asset.filePath)
  const fileIsReadable = await fs.access(filePath).then(
    () => true,
    () => false
  )

  if (fileIsReadable) {
    const readStream = createReadStream(filePath)
    return new options.context.Response(
      requestToBodyStream(options.context, Uint8Array, readStream)
    )
  }
}
Quest for Codev2.0.0
/
SIGN IN