diff --git a/src/lib/server/cloudflare.ts b/src/lib/server/cloudflare.ts index ba1f672..157f5e3 100644 --- a/src/lib/server/cloudflare.ts +++ b/src/lib/server/cloudflare.ts @@ -58,6 +58,12 @@ export async function fetchAnalytics(platform: App.Platform | undefined) { const token = platform?.env?.CF_API_TOKEN; // @ts-expect-error Cloudflare env types const zoneId = platform?.env?.CF_ZONE_ID; + // @ts-expect-error Cloudflare env types + const accountId = platform?.env?.CF_ACCOUNT_ID; + // @ts-expect-error Cloudflare env types + const d1Id = platform?.env?.CF_D1_ID; + // @ts-expect-error Cloudflare env types + const r2Bucket = platform?.env?.CF_R2_BUCKET; if (!token || !zoneId) { return null; @@ -65,6 +71,50 @@ export async function fetchAnalytics(platform: App.Platform | undefined) { const thirtyDaysAgo = new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString().split('T')[0]; + let accountQuery = ''; + if (accountId) { + let d1Query = ''; + if (d1Id) { + d1Query = ` + d1AnalyticsAdaptiveGroups( + limit: 10000, + filter: { datetime_geq: "${thirtyDaysAgo}T00:00:00Z", databaseId: "${d1Id}" } + ) { + sum { + readQueries + writeQueries + rowsRead + rowsWritten + } + } + `; + } + + let r2Query = ''; + if (r2Bucket) { + r2Query = ` + r2StorageAdaptiveGroups( + limit: 1, + filter: { datetime_geq: "${thirtyDaysAgo}T00:00:00Z", bucketName: "${r2Bucket}" }, + orderBy: [datetime_DESC] + ) { + sum { + payloadSize + } + } + `; + } + + if (d1Query || r2Query) { + accountQuery = ` + accounts(filter: { accountTag: "${accountId}" }) { + ${d1Query} + ${r2Query} + } + `; + } + } + const query = ` query { viewer { @@ -84,8 +134,12 @@ export async function fetchAnalytics(platform: App.Platform | undefined) { requests pageViews } + uniq { + uniques + } } } + ${accountQuery} } } `; @@ -101,7 +155,16 @@ export async function fetchAnalytics(platform: App.Platform | undefined) { }); const result = (await response.json()) as any; - return result?.data?.viewer?.zones?.[0]?.httpRequests1dGroups || []; + + const trafficData = result?.data?.viewer?.zones?.[0]?.httpRequests1dGroups || []; + const accountData = result?.data?.viewer?.accounts?.[0]; + + return { + traffic: trafficData, + d1: accountData?.d1AnalyticsAdaptiveGroups || [], + r2: accountData?.r2StorageAdaptiveGroups || [], + missingEnvVars: !accountId || !d1Id || !r2Bucket + }; } catch (err) { console.error('Failed to fetch analytics', err); return null;