| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749 |
- import { BlockFieldConfig } from '../types'
- import { getStorageMetadata } from '../utils/storageUtils'
- import { formatBytes } from '@/lib/helpers'
- // Helper functions that avoid duplication with existing storage utilities
- const getFileName = (path: string): string => {
- if (!path) return ''
- // Remove query parameters and hash
- const cleanPath = path.split('?')[0].split('#')[0]
- // Get the last part after the last slash
- const segments = cleanPath.split('/')
- return segments[segments.length - 1] || ''
- }
- const formatStorageDate = (dateString: string): string => {
- try {
- return new Date(dateString).toLocaleString()
- } catch {
- return dateString
- }
- }
- // =============================================================================
- // NETWORK FIELDS
- // =============================================================================
- // Field configurations - using filterable field IDs where possible
- export const originFields: BlockFieldConfig[] = [
- {
- id: 'date', // Matches filterFields 'date' (timerange) - FILTERABLE
- label: 'Time',
- getValue: (data) => {
- if (!data?.timestamp && !data?.date) return null
- try {
- const timestamp = data?.timestamp || data?.date
- return new Date(timestamp).toLocaleString()
- } catch {
- return 'Invalid date'
- }
- },
- },
- ]
- // Primary Network Fields (Always Visible) - FILTERABLE
- export const networkPrimaryFields: BlockFieldConfig[] = [
- {
- id: 'host', // Matches filterFields 'host' (input) - FILTERABLE
- label: 'Host',
- getValue: (data, enrichedData) =>
- enrichedData?.request_host || enrichedData?.host || data?.host,
- },
- {
- id: 'method', // Matches filterFields 'method' (checkbox) - FILTERABLE
- label: 'Method',
- getValue: (data, enrichedData) =>
- enrichedData?.request_method || enrichedData?.method || data?.method,
- },
- {
- id: 'pathname', // Matches filterFields 'pathname' (input) - FILTERABLE
- label: 'Path',
- getValue: (data, enrichedData) =>
- enrichedData?.request_path || enrichedData?.pathname || data?.pathname,
- },
- {
- id: 'user_agent',
- label: 'Client',
- getValue: (_data, enrichedData) => {
- const userAgent = enrichedData?.headers_user_agent
- if (!userAgent) return null
- // TODO: Parse user agent for nice display with icons
- return userAgent.length > 50 ? userAgent.substring(0, 50) + '...' : userAgent
- },
- requiresEnrichedData: true,
- },
- ]
- // Primary API Key Field (Always Visible) - Shows API key type only
- export const apiKeyPrimaryField: BlockFieldConfig = {
- id: 'api_key_role',
- label: 'API Key',
- getValue: (_data, enrichedData) => {
- const prefix = enrichedData?.api_key_prefix
- const jwtRole = enrichedData?.jwt_key_role
- const authRole = enrichedData?.authorization_role
- if (prefix) {
- // Extract key type from prefix
- if (prefix.includes('publishable')) return 'publishable'
- else if (prefix.includes('secret')) return 'secret'
- return 'unknown'
- }
- // Fallback to JWT apikey postgres role if no API key prefix
- if (jwtRole) {
- return jwtRole
- }
- // Fallback to authorization postgres role if no apikey JWT
- if (authRole) {
- return authRole
- }
- return null
- },
- requiresEnrichedData: true,
- }
- // Additional API Key Fields (Collapsible)
- export const apiKeyAdditionalFields: BlockFieldConfig[] = [
- {
- id: 'api_key_prefix_full',
- label: 'API Key Prefix',
- getValue: (_data, enrichedData) => {
- const prefix = enrichedData?.api_key_prefix
- return prefix || null
- },
- requiresEnrichedData: true,
- },
- {
- id: 'postgres_role',
- label: 'Postgres Role',
- getValue: (_data, enrichedData) => enrichedData?.jwt_key_role,
- requiresEnrichedData: true,
- },
- {
- id: 'api_key_error',
- label: 'API Key Error',
- getValue: (_data, enrichedData) => enrichedData?.api_key_error,
- requiresEnrichedData: true,
- },
- {
- id: 'api_key_hash',
- label: 'API Key Hash',
- getValue: (_data, enrichedData) => {
- const hash = enrichedData?.api_key_hash
- return hash ? `${hash.substring(0, 12)}...` : null
- },
- requiresEnrichedData: true,
- },
- {
- id: 'authorization_role',
- label: 'Postgres Role',
- getValue: (_data, enrichedData) => enrichedData?.authorization_role,
- requiresEnrichedData: true,
- },
- ]
- // Primary User Field (Always Visible)
- export const userPrimaryField: BlockFieldConfig = {
- id: 'user_id',
- label: 'User',
- getValue: (_data, enrichedData) => {
- const userId = enrichedData?.user_id
- return userId ? `${userId.substring(0, 8)}...` : null
- },
- requiresEnrichedData: true,
- }
- // Additional User Fields (Collapsible)
- export const userAdditionalFields: BlockFieldConfig[] = [
- {
- id: 'auth_user', // Matches filterFields 'auth_user' (input) - FILTERABLE
- label: 'Auth User',
- getValue: (data, enrichedData) => enrichedData?.auth_user || data?.auth_user,
- },
- {
- id: 'user_email',
- label: 'User Email',
- getValue: (_data, enrichedData) => enrichedData?.user_email,
- requiresEnrichedData: true,
- },
- ]
- // Primary Location Field (Always Visible)
- export const locationPrimaryField: BlockFieldConfig = {
- id: 'client_country',
- label: 'Location',
- getValue: (_data, enrichedData) => {
- const country = enrichedData?.client_country || enrichedData?.cf_country
- const city = enrichedData?.client_city
- if (country && city) return `${city}, ${country}`
- if (country) return country
- if (city) return city
- return null
- },
- requiresEnrichedData: true,
- }
- // Additional Location Fields (Collapsible) - includes IP addresses
- export const locationAdditionalFields: BlockFieldConfig[] = [
- {
- id: 'client_continent',
- label: 'Continent',
- getValue: (_data, enrichedData) => enrichedData?.client_continent,
- requiresEnrichedData: true,
- },
- {
- id: 'client_region',
- label: 'Region',
- getValue: (_data, enrichedData) => enrichedData?.client_region,
- requiresEnrichedData: true,
- },
- {
- id: 'client_timezone',
- label: 'Timezone',
- getValue: (_data, enrichedData) => enrichedData?.client_timezone,
- requiresEnrichedData: true,
- },
- {
- id: 'x_real_ip',
- label: 'Real IP',
- getValue: (_data, enrichedData) => enrichedData?.headers_x_real_ip,
- requiresEnrichedData: true,
- },
- {
- id: 'client_ip',
- label: 'Client IP',
- getValue: (_data, enrichedData) => enrichedData?.client_ip,
- requiresEnrichedData: true,
- },
- ]
- // Authorization Fields (Collapsible) - JWT authorization details
- export const authorizationFields: BlockFieldConfig[] = [
- {
- id: 'jwt_auth_key_id',
- label: 'Key ID',
- getValue: (_data, enrichedData) =>
- enrichedData?.jwt_auth_key_id || enrichedData?.jwt_apikey_key_id,
- requiresEnrichedData: true,
- },
- {
- id: 'jwt_auth_session_id',
- label: 'Session ID',
- getValue: (_data, enrichedData) =>
- enrichedData?.jwt_auth_session_id || enrichedData?.jwt_apikey_session_id,
- requiresEnrichedData: true,
- },
- {
- id: 'jwt_auth_subject',
- label: 'Subject',
- getValue: (_data, enrichedData) =>
- enrichedData?.jwt_auth_subject || enrichedData?.jwt_apikey_subject,
- requiresEnrichedData: true,
- },
- {
- id: 'jwt_auth_issuer',
- label: 'Issuer',
- getValue: (_data, enrichedData) =>
- enrichedData?.jwt_auth_issuer || enrichedData?.jwt_apikey_issuer,
- requiresEnrichedData: true,
- },
- {
- id: 'jwt_auth_algorithm',
- label: 'Algorithm',
- getValue: (_data, enrichedData) =>
- enrichedData?.jwt_auth_algorithm || enrichedData?.jwt_apikey_algorithm,
- requiresEnrichedData: true,
- },
- {
- id: 'jwt_auth_expires_at',
- label: 'Expires At',
- getValue: (_data, enrichedData) => {
- const expiresAt = enrichedData?.jwt_auth_expires_at || enrichedData?.jwt_apikey_expires_at
- if (!expiresAt) return null
- try {
- return new Date(expiresAt * 1000).toLocaleString()
- } catch {
- return expiresAt
- }
- },
- requiresEnrichedData: true,
- },
- ]
- // Tech Details Fields (Collapsible)
- export const techDetailsFields: BlockFieldConfig[] = [
- {
- id: 'network_protocol',
- label: 'Protocol',
- getValue: (_data, enrichedData) => enrichedData?.network_protocol,
- requiresEnrichedData: true,
- },
- {
- id: 'cf_datacenter',
- label: 'Datacenter',
- getValue: (_data, enrichedData) =>
- enrichedData?.network_datacenter || enrichedData?.cf_datacenter,
- requiresEnrichedData: true,
- },
- {
- id: 'cache_status',
- label: 'Cache Status',
- getValue: (_data, enrichedData) => enrichedData?.response_cache_status,
- requiresEnrichedData: true,
- },
- {
- id: 'cf_ray',
- label: 'CF-Ray',
- getValue: (_data, enrichedData) => enrichedData?.cf_ray,
- requiresEnrichedData: true,
- },
- {
- id: 'x_client_info',
- label: 'SDK',
- getValue: (_data, enrichedData) => enrichedData?.headers_x_client_info,
- requiresEnrichedData: true,
- },
- {
- id: 'x_forwarded_proto',
- label: 'Forwarded Proto',
- getValue: (_data, enrichedData) => enrichedData?.headers_x_forwarded_proto,
- requiresEnrichedData: true,
- },
- ]
- // =============================================================================
- // POSTGREST FIELDS
- // =============================================================================
- // Primary PostgREST Fields (Always Visible) - FILTERABLE
- export const postgrestPrimaryFields: BlockFieldConfig[] = [
- {
- id: 'status', // Matches filterFields 'status' (checkbox) - FILTERABLE
- label: 'Status',
- getValue: (data, enrichedData) => enrichedData?.status || data?.status,
- },
- {
- id: 'postgres_role',
- label: 'Postgres Role',
- getValue: (_data, enrichedData) => enrichedData?.api_role,
- requiresEnrichedData: true,
- },
- {
- id: 'response_time',
- label: 'Response Time',
- getValue: (data, enrichedData) => {
- const time = enrichedData?.response_origin_time || data?.response_time_ms
- return time ? `${time}ms` : null
- },
- requiresEnrichedData: true,
- },
- ]
- // PostgREST Response Details (Collapsible)
- export const postgrestResponseFields: BlockFieldConfig[] = [
- {
- id: 'query_params',
- label: 'Query',
- getValue: (_data, enrichedData) => enrichedData?.request_search,
- requiresEnrichedData: true,
- },
- {
- id: 'content_type',
- label: 'Content Type',
- getValue: (_data, enrichedData) => enrichedData?.response_content_type,
- requiresEnrichedData: true,
- },
- {
- id: 'message',
- label: 'Message',
- getValue: (_data, enrichedData) => enrichedData?.message,
- requiresEnrichedData: true,
- },
- ]
- // =============================================================================
- // AUTH FIELDS
- // =============================================================================
- // Primary GoTrue/Auth Fields (Always Visible)
- export const authPrimaryFields: BlockFieldConfig[] = [
- {
- id: 'auth_path',
- label: 'Auth Path',
- getValue: (data, enrichedData) => {
- return enrichedData?.path || enrichedData?.request_path || data?.path
- },
- requiresEnrichedData: true,
- },
- {
- id: 'log_id',
- label: 'Log ID',
- getValue: (data, enrichedData) => {
- const logId = data?.id || enrichedData?.id
- return logId ? `${logId.substring(0, 8)}...` : null
- },
- },
- {
- id: 'referer',
- label: 'Referer',
- getValue: (_data, enrichedData) => {
- return enrichedData?.headers_referer || null
- },
- requiresEnrichedData: true,
- },
- ]
- // =============================================================================
- // EDGE FUNCTION FIELDS
- // =============================================================================
- // Primary Edge Function Fields (Always Visible)
- export const edgeFunctionPrimaryFields: BlockFieldConfig[] = [
- {
- id: 'status',
- label: 'Status',
- getValue: (data, enrichedData) => enrichedData?.status || data?.status,
- },
- {
- id: 'function_path',
- label: 'Function Path',
- getValue: (data, enrichedData) => {
- return (
- enrichedData?.path || enrichedData?.request_path || data?.path || enrichedData?.request_url
- )
- },
- requiresEnrichedData: false,
- },
- {
- id: 'execution_time',
- label: 'Execution Time',
- getValue: (data, enrichedData) => {
- const time = enrichedData?.execution_time_ms || data?.execution_time_ms
- return time ? `${time}ms` : null
- },
- requiresEnrichedData: false,
- },
- {
- id: 'execution_id',
- label: 'Execution ID',
- getValue: (data, enrichedData) => {
- const execId = enrichedData?.execution_id || data?.execution_id
- return execId ? `${execId.substring(0, 8)}...` : null
- },
- requiresEnrichedData: false,
- },
- ]
- // Edge Function Details (Collapsible)
- export const edgeFunctionDetailsFields: BlockFieldConfig[] = [
- {
- id: 'function_id',
- label: 'Function ID',
- getValue: (data, enrichedData) => {
- const funcId = enrichedData?.function_id || data?.function_id
- return funcId ? `${funcId.substring(0, 8)}...` : null
- },
- requiresEnrichedData: false,
- },
- {
- id: 'execution_region',
- label: 'Execution Region',
- getValue: (data, enrichedData) => {
- return enrichedData?.execution_region || data?.execution_region || null
- },
- requiresEnrichedData: false,
- },
- {
- id: 'function_log_count',
- label: 'Function Logs',
- getValue: (data, enrichedData) => {
- const count = enrichedData?.function_log_count || data?.function_log_count || data?.log_count
- return count ? `${count} logs` : 'No logs'
- },
- requiresEnrichedData: false,
- },
- {
- id: 'method',
- label: 'Method',
- getValue: (data, enrichedData) => enrichedData?.method || data?.method,
- requiresEnrichedData: false,
- },
- {
- id: 'user_agent',
- label: 'User Agent',
- getValue: (data, enrichedData) => {
- const ua = enrichedData?.headers_user_agent || data?.headers_user_agent
- return ua ? (ua.length > 30 ? `${ua.substring(0, 30)}...` : ua) : null
- },
- requiresEnrichedData: false,
- },
- ]
- // =============================================================================
- // STORAGE FIELDS
- // =============================================================================
- // Primary Storage Fields (Always Visible)
- export const storagePrimaryFields: BlockFieldConfig[] = [
- {
- id: 'status',
- label: 'Status',
- getValue: (data, enrichedData) => enrichedData?.status || data?.status,
- },
- {
- id: 'filename',
- label: 'File Name',
- getValue: (data, enrichedData) => {
- const path = enrichedData?.path || enrichedData?.request_path || data?.path
- return path ? getFileName(path) : null
- },
- requiresEnrichedData: false,
- },
- {
- id: 'content_type_size',
- label: 'Type & Size',
- getValue: (data, enrichedData) => {
- const status = enrichedData?.status || data?.status
- const isObjectDeleted = status === 404 || status === '404'
- const hasError = status && Number(status) >= 400
- // For deleted objects, show status message
- if (isObjectDeleted) {
- return 'Object deleted'
- } else if (hasError) {
- return `Error ${status}`
- }
- // Try to get metadata like PreviewPane does
- const metadata = getStorageMetadata(data, enrichedData)
- const mimeType = metadata?.mimetype
- const size = metadata?.size
- // Fallback to headers if metadata not available
- const contentType =
- mimeType ||
- enrichedData?.response_content_type ||
- enrichedData?.storage_request_content_type
- const contentLength =
- size ||
- (enrichedData?.storage_content_length
- ? parseInt(enrichedData.storage_content_length)
- : null)
- if (contentType && contentLength) {
- return `${contentType} - ${formatBytes(contentLength)}`
- } else if (contentType) {
- return contentType
- } else if (contentLength) {
- return formatBytes(contentLength)
- }
- return 'Unknown type'
- },
- requiresEnrichedData: true,
- },
- {
- id: 'response_time',
- label: 'Response Time',
- getValue: (data, enrichedData) => {
- const time = enrichedData?.response_origin_time || data?.response_time_ms
- return time ? `${time}ms` : null
- },
- requiresEnrichedData: true,
- },
- ]
- // Storage Details (Collapsible)
- export const storageDetailsFields: BlockFieldConfig[] = [
- {
- id: 'storage_path',
- label: 'Storage Path',
- getValue: (data, enrichedData) => {
- const path = enrichedData?.path || enrichedData?.request_path || data?.path
- // Extract just the object path from the full storage path
- const match = path?.match(/\/storage\/v1\/object\/([^\/]+)\/(.+)/)
- if (match) {
- const [, bucketName, objectPath] = match
- return `${bucketName}/${objectPath}`
- }
- return path
- },
- requiresEnrichedData: false,
- },
- {
- id: 'last_modified',
- label: 'Last Modified',
- getValue: (data, enrichedData) => {
- const status = enrichedData?.status || data?.status
- const isObjectDeleted = status === 404 || status === '404'
- const hasError = status && Number(status) >= 400
- if (isObjectDeleted) {
- return 'Object deleted'
- } else if (hasError) {
- return 'Unavailable'
- }
- // Try to get dates from metadata like PreviewPane does
- const metadata = getStorageMetadata(data, enrichedData)
- const updatedAt = metadata?.updated_at || data?.updated_at || enrichedData?.updated_at
- const lastModified = enrichedData?.storage_last_modified || updatedAt
- return lastModified ? formatStorageDate(lastModified) : null
- },
- requiresEnrichedData: true,
- },
- {
- id: 'etag',
- label: 'ETag',
- getValue: (data, enrichedData) => {
- const status = enrichedData?.status || data?.status
- const isObjectDeleted = status === 404 || status === '404'
- const hasError = status && Number(status) >= 400
- if (isObjectDeleted) {
- return 'Object deleted'
- } else if (hasError) {
- return 'Unavailable'
- }
- const etag = enrichedData?.storage_etag
- return etag ? `${etag.substring(0, 12)}...` : null
- },
- requiresEnrichedData: true,
- },
- {
- id: 'content_disposition',
- label: 'Content Disposition',
- getValue: (data, enrichedData) => {
- const status = enrichedData?.status || data?.status
- const isObjectDeleted = status === 404 || status === '404'
- const hasError = status && Number(status) >= 400
- if (isObjectDeleted) {
- return 'Object deleted'
- } else if (hasError) {
- return 'Unavailable'
- }
- return enrichedData?.storage_content_disposition || null
- },
- requiresEnrichedData: true,
- },
- {
- id: 'method',
- label: 'Method',
- getValue: (data, enrichedData) => enrichedData?.method || data?.method,
- requiresEnrichedData: false,
- },
- {
- id: 'user_agent',
- label: 'User Agent',
- getValue: (data, enrichedData) => {
- const ua = enrichedData?.headers_user_agent || data?.headers_user_agent
- return ua ? (ua.length > 30 ? `${ua.substring(0, 30)}...` : ua) : null
- },
- requiresEnrichedData: false,
- },
- ]
- // =============================================================================
- // POSTGRES FIELDS
- // =============================================================================
- // Primary Postgres Fields (Always Visible)
- export const postgresPrimaryFields: BlockFieldConfig[] = [
- {
- id: 'event_message',
- label: 'Message',
- getValue: (data, enrichedData) => enrichedData?.event_message || data?.event_message,
- wrap: true,
- },
- {
- id: 'status',
- label: 'Status',
- getValue: (data, enrichedData) => enrichedData?.status || data?.status,
- },
- {
- id: 'command_tag',
- label: 'Command',
- getValue: (data, enrichedData) => enrichedData?.command_tag || data?.command_tag,
- requiresEnrichedData: true,
- },
- {
- id: 'database_name',
- label: 'Database',
- getValue: (data, enrichedData) => enrichedData?.database_name || data?.database_name,
- requiresEnrichedData: true,
- },
- {
- id: 'database_user',
- label: 'User',
- getValue: (data, enrichedData) => enrichedData?.database_user || data?.database_user,
- requiresEnrichedData: true,
- },
- ]
- // Postgres Details (Collapsible)
- export const postgresDetailsFields: BlockFieldConfig[] = [
- {
- id: 'backend_type',
- label: 'Backend Type',
- getValue: (data, enrichedData) => enrichedData?.backend_type || data?.backend_type,
- requiresEnrichedData: true,
- },
- {
- id: 'connection_from',
- label: 'Connection From',
- getValue: (data, enrichedData) => enrichedData?.connection_from || data?.connection_from,
- requiresEnrichedData: true,
- },
- {
- id: 'session_id',
- label: 'Session ID',
- getValue: (data, enrichedData) => enrichedData?.session_id || data?.session_id,
- requiresEnrichedData: true,
- },
- {
- id: 'process_id',
- label: 'Process ID',
- getValue: (data, enrichedData) => enrichedData?.process_id || data?.process_id,
- requiresEnrichedData: true,
- },
- {
- id: 'query_id',
- label: 'Query ID',
- getValue: (data, enrichedData) => {
- const queryId = enrichedData?.query_id || data?.query_id
- return queryId ? String(queryId) : null
- },
- requiresEnrichedData: true,
- },
- {
- id: 'transaction_id',
- label: 'Transaction ID',
- getValue: (data, enrichedData) => {
- const txId = enrichedData?.transaction_id || data?.transaction_id
- return txId ? String(txId) : null
- },
- requiresEnrichedData: true,
- },
- {
- id: 'virtual_transaction_id',
- label: 'Virtual TX ID',
- getValue: (data, enrichedData) =>
- enrichedData?.virtual_transaction_id || data?.virtual_transaction_id,
- requiresEnrichedData: true,
- },
- {
- id: 'session_start_time',
- label: 'Session Started',
- getValue: (data, enrichedData) => {
- const startTime = enrichedData?.session_start_time || data?.session_start_time
- return startTime ? new Date(startTime).toLocaleString() : null
- },
- requiresEnrichedData: true,
- },
- ]
|