1- import { auth } from '@databuddy/auth' ;
2- import { db , userPreferences , websites } from '@databuddy/db' ;
3- import { cacheable } from '@databuddy/redis' ;
4- import { eq } from 'drizzle-orm' ;
51import { Elysia , t } from 'elysia' ;
2+ import {
3+ deriveWebsiteContext ,
4+ getCachedWebsiteDomain ,
5+ getWebsiteDomain ,
6+ } from '../lib/website-utils' ;
67import { createRateLimitMiddleware } from '../middleware/rate-limit' ;
78import { compileQuery , executeQuery } from '../query' ;
89import { QueryBuilders } from '../query/builders' ;
@@ -23,66 +24,9 @@ interface QueryParams {
2324 timezone ?: string ;
2425}
2526
26- async function getTimezone (
27- request : Request ,
28- session : { user ?: { id : string } } | null
29- ) {
30- const url = new URL ( request . url ) ;
31- const headerTimezone = request . headers . get ( 'x-timezone' ) ;
32- const paramTimezone = url . searchParams . get ( 'timezone' ) ;
33-
34- if ( session ?. user ) {
35- const pref = await db . query . userPreferences . findFirst ( {
36- where : eq ( userPreferences . userId , session . user . id ) ,
37- } ) ;
38- if ( pref ?. timezone && pref . timezone !== 'auto' ) {
39- return pref . timezone ;
40- }
41- }
42-
43- return headerTimezone || paramTimezone || 'UTC' ;
44- }
45-
46- async function deriveContext ( { request } : { request : Request } ) {
47- const session = await auth . api . getSession ( {
48- headers : request . headers ,
49- } ) ;
50-
51- const url = new URL ( request . url ) ;
52- const website_id = url . searchParams . get ( 'website_id' ) ;
53-
54- if ( ! website_id ) {
55- if ( ! session ?. user ) {
56- throw new Error ( 'Unauthorized' ) ;
57- }
58- const timezone = await getTimezone ( request , session ) ;
59- return { user : session . user , session, timezone } ;
60- }
61-
62- const website = await db . query . websites . findFirst ( {
63- where : eq ( websites . id , website_id ) ,
64- } ) ;
65-
66- if ( ! website ) {
67- throw new Error ( 'Website not found' ) ;
68- }
69-
70- if ( website . isPublic ) {
71- const timezone = await getTimezone ( request , null ) ;
72- return { user : null , session : null , website, timezone } ;
73- }
74-
75- if ( ! session ?. user ) {
76- throw new Error ( 'Unauthorized' ) ;
77- }
78-
79- const timezone = await getTimezone ( request , session ) ;
80- return { user : session . user , session, website, timezone } ;
81- }
82-
8327export const query = new Elysia ( { prefix : '/v1/query' } )
8428 . use ( createRateLimitMiddleware ( { type : 'api' } ) )
85- . derive ( deriveContext )
29+ . derive ( deriveWebsiteContext )
8630 . get ( '/types' , ( ) => ( {
8731 success : true ,
8832 types : Object . keys ( QueryBuilders ) ,
@@ -199,45 +143,6 @@ export const query = new Elysia({ prefix: '/v1/query' })
199143 }
200144 ) ;
201145
202- const getWebsiteDomain = cacheable (
203- async ( websiteId : string ) : Promise < string | null > => {
204- try {
205- const website = await db . query . websites . findFirst ( {
206- where : eq ( websites . id , websiteId ) ,
207- } ) ;
208- return website ?. domain || null ;
209- } catch {
210- return null ;
211- }
212- } ,
213- {
214- expireInSec : 300 ,
215- prefix : 'website-domain' ,
216- staleWhileRevalidate : true ,
217- staleTime : 60 ,
218- }
219- ) ;
220-
221- const getCachedWebsiteDomain = cacheable (
222- async ( websiteIds : string [ ] ) : Promise < Record < string , string | null > > => {
223- const results : Record < string , string | null > = { } ;
224-
225- await Promise . all (
226- websiteIds . map ( async ( id ) => {
227- results [ id ] = await getWebsiteDomain ( id ) ;
228- } )
229- ) ;
230-
231- return results ;
232- } ,
233- {
234- expireInSec : 300 ,
235- prefix : 'website-domains-batch' ,
236- staleWhileRevalidate : true ,
237- staleTime : 60 ,
238- }
239- ) ;
240-
241146async function executeDynamicQuery (
242147 request : DynamicQueryRequestType ,
243148 queryParams : QueryParams ,
0 commit comments