storipress/karbon

View on GitHub
packages/karbon/src/runtime/routes/_snapshot.ts

Summary

Maintainability
B
4 hrs
Test Coverage
import { encodePath } from 'ufo'
import type { H3Event } from 'h3'
import { setHeader } from 'h3'
import type { ResourcePageContext } from '../types'

// @ts-expect-error generated file
import urls from '#sp-internal/storipress-urls.mjs'

// @ts-expect-error no type
import { defineCachedEventHandler, useNitroApp, useRuntimeConfig } from '#imports'

const RESOURCE = new Set(['article', 'author', 'desk', 'tag'])
interface ResourceScope {
  payloadScope: 'posts' | 'desks' | 'authors' | 'tags'
  urlKey: string
  filter?: (item: any) => boolean
}

const payloadScopes: ResourceScope[] = [
  {
    payloadScope: 'posts',
    urlKey: 'article',
  },
  {
    payloadScope: 'desks',
    urlKey: 'desk',
    filter: (item: { published_articles_count: number }) => item.published_articles_count > 0,
  },
  {
    payloadScope: 'authors',
    urlKey: 'author',
    filter: (item: { suspended: boolean; slug: string }) => !item.suspended && Boolean(item.slug),
  },
  { payloadScope: 'tags', urlKey: 'tag' },
  ...Object.keys(urls).flatMap((key) => (RESOURCE.has(key) ? [] : [{ payloadScope: 'tags' as const, urlKey: key }])),
]

const invalidContext: ResourcePageContext = import.meta.env.DEV
  ? new Proxy({} as ResourcePageContext, {
      get(_obj, key) {
        console.warn(`Forbid to access internal context object key ${String(key)} without using \`getResourceOption\``)
        throw new Error('accessing internal context')
      },
    })
  : ({ identity: 'invalid', prefix: '', resource: 'invalid' } as unknown as ResourcePageContext)

export default defineCachedEventHandler(async (event: H3Event) => {
  const runtimeConfig = useRuntimeConfig()

  if (!runtimeConfig.storipress?.fullStatic) {
    setHeader(event, 'content-type', 'text/html')

    return '<div>Internal Page</div>'
  }

  const nitro = useNitroApp()
  const links: string[] = []
  const groupsResponse = await nitro.localFetch('/_storipress/_custom-field-group.json', {
    method: 'GET',
  })
  const groups: Record<string, string[]> = await groupsResponse.json()

  await Promise.all(
    payloadScopes.map(async ({ payloadScope, urlKey, filter }) => {
      const res = await nitro.localFetch(`/_storipress/${payloadScope}/__all.json`, { method: 'GET' })
      const items = await res.json()
      const ctx = urls[urlKey]._context ?? invalidContext
      const groupKey = urls[urlKey].groupKey
      const group = groupKey ? groups[groupKey] : null
      for (const item of items) {
        if (filter && !filter(item)) {
          continue
        }
        links.push(
          `/_storipress/${payloadScope}/${item.id}.js`,
          ...(urls[urlKey].enable && !groupKey ? [encodePath(urls[urlKey].toURL(item, ctx))] : []),
        )
        if (urls[urlKey].enable && group && group.includes(item.id)) {
          links.push(encodePath(urls[urlKey].toURL(item, ctx)))
        }
      }
    }),
  )

  setHeader(event, 'content-type', 'text/html')
  setHeader(event, 'x-nitro-prerender', links.join(','))

  return '<div>Internal Page</div>'
})