| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112 |
- import { z } from 'zod'
- import { NEW_NAMESPACE_MARKER } from './CreateTableSheet.constants'
- const getValidRegex = (type: 'namespace' | 'table') =>
- type === 'namespace'
- ? /^(?!aws)[a-z0-9](?:[a-z0-9_]*[a-z0-9])?$/
- : /^[a-z0-9](?:[a-z0-9_]*[a-z0-9])?$/
- const getErrorRegex = (type: 'namespace' | 'table') =>
- type === 'namespace'
- ? /^(?:(?<starts_with_reserved>aws.*)|(?<invalid_start>[^a-z0-9].*)|(?<invalid_char>.*[^a-z0-9_].*)|(?<invalid_end>.*[^a-z0-9]))$/
- : /^(?:(?<invalid_start>[^a-z0-9].*)|(?<invalid_char>.*[^a-z0-9_].*)|(?<invalid_end>.*[^a-z0-9]))$/
- const validateName = ({ name, type }: { name: string; type: 'namespace' | 'table' }) => {
- const validRe = getValidRegex(type)
- if (validRe.test(name)) return undefined
- const errorRe = getErrorRegex(type)
- const match = name.match(errorRe)?.groups || {}
- if (match.starts_with_reserved) return "Namespace must not start with 'aws'"
- if (match.invalid_start) return 'Name must begin with a lowercase letter or number'
- if (match.invalid_end) return 'Name must end with a lowercase letter or number'
- if (match.invalid_char) return 'Name may only contain lowercase letters, numbers, and underscores'
- return 'Invalid name'
- }
- export const createFormSchema = () =>
- z
- .object({
- namespace: z.string().min(1, 'Please select a namespace'),
- newNamespace: z.string().max(255, 'Name must be within 255 characters').optional(),
- name: z
- .string()
- .min(1, 'Provide a name for your table')
- .max(255, 'Name must be within 255 characters'),
- columns: z
- .object({
- name: z.string().min(1, 'Provide a name for your column'),
- type: z.string().min(1, 'Select a type for your column'),
- // For decimal type
- precision: z.number().optional(),
- scale: z.number().int().optional(),
- // For fixed type
- length: z.number().int().optional(),
- })
- .array()
- .default([]),
- })
- .superRefine((data, ctx) => {
- if (data.namespace === NEW_NAMESPACE_MARKER) {
- if (data.newNamespace) {
- const newNamespaceError = validateName({
- name: data.newNamespace,
- type: 'namespace',
- })
- if (newNamespaceError) {
- ctx.addIssue({
- code: z.ZodIssueCode.custom,
- message: newNamespaceError,
- path: ['newNamespace'],
- })
- }
- } else {
- ctx.addIssue({
- code: z.ZodIssueCode.custom,
- message: 'Provide a name for your new namespace',
- path: ['newNamespace'],
- })
- }
- }
- data.columns.forEach((column, index) => {
- if (column.type === 'decimal') {
- if (column.precision == null) {
- ctx.addIssue({
- code: z.ZodIssueCode.custom,
- message: 'Required',
- path: [`columns.${index}.precision`],
- })
- }
- if (column.scale == null) {
- ctx.addIssue({
- code: z.ZodIssueCode.custom,
- message: 'Required',
- path: [`columns.${index}.scale`],
- })
- }
- }
- if (column.type === 'fixed') {
- if (column.length == null) {
- ctx.addIssue({
- code: z.ZodIssueCode.custom,
- message: 'Required',
- path: [`columns.${index}.length`],
- })
- }
- }
- })
- if (data.name) {
- const newTableError = validateName({ name: data.name, type: 'table' })
- if (newTableError) {
- ctx.addIssue({
- code: z.ZodIssueCode.custom,
- message: newTableError,
- path: ['name'],
- })
- }
- }
- })
|