mirror of
https://github.com/saltbo/zpan.git
synced 2026-11-01 20:33:14 +08:00
Flatten the instance `runtime` object into two fields: `runtime` (the JS engine,
node | workerd) and `platform` (the deployment host). The About page shows each
as its own row with friendly labels (e.g. "workerd" + "Cloudflare Workers",
"Node.js" + "Docker").
- Detect the platform from the entry file (entry === target): each serverless
entry declares it; entry-node sniffs Cloud Run (K_SERVICE) / Docker
(ZPAN_RUNTIME, set in the Dockerfile) / bare node. Cloudflare is detected from
the D1 binding.
- Decouple the cloud payload: zpan-cloud-sdk fixes runtime { provider, target },
so CloudInstanceInfo keeps that shape and buildCloudInstanceInfo maps to it;
buildInstanceInfo serves the richer flat shape to the About API.
- Migrate PostHog instance telemetry to the runtime/platform shape and merge the
duplicate runtimeInfo in licensing-admin into the shared one.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
78 lines
2.5 KiB
TypeScript
78 lines
2.5 KiB
TypeScript
import { release as osRelease } from 'node:os'
|
|
import { eq } from 'drizzle-orm'
|
|
import type { InstanceInfo } from '../../shared/types'
|
|
import { systemOptions } from '../db/schema'
|
|
import type { Database, Platform } from '../platform/interface'
|
|
import { getDeployPlatform } from '../runtime-platform'
|
|
import type { CloudInstanceInfo } from '../services/licensing-cloud'
|
|
import { getAppCommit, getAppVersion } from '../version'
|
|
import { getOrCreateInstanceId } from './instance-id'
|
|
|
|
type RuntimeInfo = Pick<InstanceInfo, 'runtime' | 'platform' | 'server' | 'node'>
|
|
|
|
export function runtimeInfo(platform: Platform): RuntimeInfo {
|
|
if (platform.getBinding('DB')) {
|
|
return { runtime: 'workerd', platform: 'cloudflare-workers' }
|
|
}
|
|
return {
|
|
runtime: 'node',
|
|
platform: getDeployPlatform() ?? 'node',
|
|
server: { os: { platform: process.platform, arch: process.arch, release: osRelease() } },
|
|
node: { version: process.version },
|
|
}
|
|
}
|
|
|
|
export async function getInstanceDisplayName(db: Database): Promise<string> {
|
|
const rows = await db
|
|
.select({ value: systemOptions.value })
|
|
.from(systemOptions)
|
|
.where(eq(systemOptions.key, 'site_title'))
|
|
.limit(1)
|
|
|
|
return rows[0]?.value ?? 'ZPan'
|
|
}
|
|
|
|
// Shown on the admin About page: flat runtime engine + deployment platform.
|
|
export async function buildInstanceInfo(
|
|
db: Database,
|
|
params: { url: string; runtime?: RuntimeInfo },
|
|
): Promise<InstanceInfo> {
|
|
return {
|
|
id: await getOrCreateInstanceId(db),
|
|
name: await getInstanceDisplayName(db),
|
|
url: params.url,
|
|
version: getAppVersion(),
|
|
commit: getAppCommit(),
|
|
...params.runtime,
|
|
}
|
|
}
|
|
|
|
// Reported to ZPan Cloud. The cloud SDK fixes the coarse `runtime { provider,
|
|
// target }` shape, so collapse the richer platform back to it here.
|
|
function toCloudRuntime(info?: RuntimeInfo): Pick<CloudInstanceInfo, 'runtime' | 'server' | 'node'> {
|
|
if (!info?.runtime) return {}
|
|
const cloudflare = info.runtime === 'workerd'
|
|
return {
|
|
runtime: {
|
|
provider: cloudflare ? 'cloudflare' : 'node',
|
|
target: cloudflare ? 'cloudflare-worker' : 'node/docker',
|
|
},
|
|
server: info.server,
|
|
node: info.node,
|
|
}
|
|
}
|
|
|
|
export async function buildCloudInstanceInfo(
|
|
db: Database,
|
|
params: { url: string; runtime?: RuntimeInfo },
|
|
): Promise<CloudInstanceInfo> {
|
|
return {
|
|
id: await getOrCreateInstanceId(db),
|
|
name: await getInstanceDisplayName(db),
|
|
url: params.url,
|
|
version: getAppVersion(),
|
|
commit: getAppCommit(),
|
|
...toCloudRuntime(params.runtime),
|
|
}
|
|
}
|