import type { ProFeature } from '@shared/types' import type { Context } from 'hono' import { createMiddleware } from 'hono/factory' import { ZPAN_CLOUD_URL_DEFAULT } from '../../shared/constants' import { hasFeature } from '../domain/licensing' import { featureBlocked } from '../usecases/ports' import { loadBindingState, normalizeHost } from '../usecases/site/licensing' import { getSitePublicOrigin } from '../usecases/site/public-origin' import type { Env } from './platform' async function configuredPublicHost(c: Context): Promise { const origin = await getSitePublicOrigin(c.get('deps')) return origin ? new URL(origin).host : null } export function requireFeature(name: ProFeature) { return createMiddleware(async (c, next) => { const cloudBaseUrl = c.get('platform').getEnv('ZPAN_CLOUD_URL') ?? ZPAN_CLOUD_URL_DEFAULT const currentHost = (await configuredPublicHost(c)) ?? normalizeHost(c.req.header('host')) ?? new URL(c.req.url).host const state = await loadBindingState(c.get('deps'), { currentHost, cloudBaseUrl }) if (!hasFeature(name, state)) { throw featureBlocked('Feature not available', { metadata: { feature: name, upgradeUrl: '/settings/billing' }, }) } await next() }) }