Files
Stephen MorganandIvan Vasilov 4c4083b951 fix: Validate queue names (#40290)
* fix: input validation for queue name

* grammar

* fix: whitespacing issue

* Reuse the validation logic for queue name.

* Reuse the query name schema in the create queue sheet.

---------

Co-authored-by: Ivan Vasilov <vasilov.ivan@gmail.com>
2025-11-10 11:12:17 +01:00

128 lines
3.3 KiB
TypeScript

import { Column } from 'react-data-grid'
import z from 'zod'
import { PostgresQueue } from 'data/database-queues/database-queues-query'
import { cn } from 'ui'
import {
QueueCreatedAtCell,
QueueNameCell,
QueueRLSCell,
QueueSizeCell,
QueueTypeCell,
QueueWithMetrics,
} from './QueueCells'
export const formatQueueColumns = (): Column<QueueWithMetrics>[] => {
return [
{
key: 'queue_name',
name: 'Name',
resizable: true,
minWidth: 200,
headerCellClass: undefined,
renderHeaderCell: () => {
return (
<div className={cn('flex items-center justify-between font-normal text-xs w-full ml-8')}>
<p className="!text-foreground">Name</p>
</div>
)
},
renderCell: (props) => {
return <QueueNameCell queue={props.row} />
},
},
{
key: 'type',
name: 'Type',
resizable: true,
minWidth: 120,
headerCellClass: undefined,
renderHeaderCell: () => {
return (
<div className={cn('flex items-center justify-between font-normal text-xs w-full')}>
<p className="!text-foreground">Type</p>
</div>
)
},
renderCell: (props) => {
return <QueueTypeCell queue={props.row} />
},
},
{
key: 'rls_enabled',
name: 'RLS enabled',
resizable: true,
minWidth: 120,
headerCellClass: undefined,
renderHeaderCell: () => {
return (
<div className={cn('flex items-center justify-between font-normal text-xs w-full')}>
<p className="!text-foreground">RLS enabled</p>
</div>
)
},
renderCell: (props) => {
return <QueueRLSCell queue={props.row} />
},
},
{
key: 'created_at',
name: 'Created at',
resizable: true,
minWidth: 180,
headerCellClass: undefined,
renderHeaderCell: () => {
return (
<div className={cn('flex items-center justify-between font-normal text-xs w-full')}>
<p className="!text-foreground">Created at</p>
</div>
)
},
renderCell: (props) => {
return <QueueCreatedAtCell queue={props.row} />
},
},
{
key: 'queue_size',
name: 'Size',
resizable: true,
minWidth: 120,
headerCellClass: undefined,
renderHeaderCell: () => {
return (
<div className={cn('flex items-center justify-between font-normal text-xs w-full')}>
<p className="!text-foreground">Size</p>
</div>
)
},
renderCell: (props) => {
return <QueueSizeCell queue={props.row} />
},
},
]
}
export const prepareQueuesForDataGrid = (queues: PostgresQueue[]): QueueWithMetrics[] => {
return queues.map((queue) => ({
...queue,
id: queue.queue_name, // Use queue_name as unique id
}))
}
export const QueryNameSchema = z
.string()
.trim()
.min(1, 'Please provide a name for your queue')
.max(47, "The name can't be longer than 47 characters")
.regex(
/^[a-zA-Z0-9_-]+$/,
'Name must contain only alphanumeric characters, underscores, and hyphens'
)
/**
* Checks if the queue name is valid. Returns a boolean.
*/
export const isQueueNameValid = (queueName: string) => {
return QueryNameSchema.safeParse(queueName).success
}