// adapted from https://github.com/distribution/distribution/issues/1252#issuecomment-274944254

const IMAGE = 'example/foo'
const TAG = 'latest'

const authorise = async () => {
  const url = new URL('https://auth.docker.io/token')
  url.searchParams.set('scope', `repository:${IMAGE}:pull`)
  url.searchParams.set('service', 'registry.docker.io')
  const response = await fetch(url)
  return response.json()
}

const { token } = await authorise()

const manifest = async () => {
  const url = new URL(
    `https://registry-1.docker.io/v2/${IMAGE}/manifests/${TAG}`
  )
  const response = await fetch(url, {
    headers: {
      Accept: 'application/vnd.docker.distribution.manifest.v2+json',
      Authorization: `Bearer ${token}`,
    },
  })
  return response.json()
}

const { config } = await manifest()

const blob = async (digest) => {
  const url = new URL(
    `https://registry-1.docker.io/v2/${IMAGE}/blobs/${digest}`
  )
  const response = await fetch(url, {
    headers: {
      Authorization: `Bearer ${token}`,
    },
  })
  return response.json()
}

const data = await blob(config.digest)

console.log(data)