refactor(form-schema): inline validators to remove @core transitive dep

Resolves TECH-07. Copies the four validators actually used
(requiredValidator, emailValidator, urlValidator, regexValidator) from
@core/utils/validators into packages/form-schema/src/utils/validators.ts
as pure boolean functions. Vuexy template copies in apps/*/src/@core/
remain for non-form UI use. Package is now genuinely standalone —
grep -rn "@core/" packages/form-schema/ returns zero matches.

Also corrects two documentation inconsistencies from commit 42dd626e:
dev-guide heading translated to Dutch for style consistency, and the
BACKLOG entry renumbered from TECH-DEBT-01 to TECH-07 to match the
flat numbering in the Technische schuld section.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-24 00:20:15 +02:00
parent 42dd626e37
commit 214a2debee
4 changed files with 60 additions and 18 deletions

View File

@@ -1,4 +1,4 @@
import { emailValidator, regexValidator, requiredValidator, urlValidator } from '@core/utils/validators'
import { emailValidator, regexValidator, requiredValidator, urlValidator } from './validators'
import { FormFieldType } from '../types/formBuilder'
import type { PublicFormField } from '../types/formBuilder'

View File

@@ -0,0 +1,54 @@
// Pure boolean validators used as gates by formValidation.ts. Error
// messages (in Dutch) are produced by the caller, not by these validators.
// This file deliberately has no external imports — the package must be
// standalone and free of cross-app coupling.
function isNullOrUndefined(value: unknown): boolean {
return value === null || value === undefined
}
function isEmptyArray(value: unknown): boolean {
return Array.isArray(value) && value.length === 0
}
function isEmpty(value: unknown): boolean {
if (isNullOrUndefined(value)) return true
if (typeof value === 'string') return value.trim() === ''
if (Array.isArray(value)) return value.length === 0
return false
}
export function requiredValidator(value: unknown): boolean {
if (isNullOrUndefined(value) || isEmptyArray(value) || value === false) return false
return String(value).trim().length > 0
}
export function emailValidator(value: unknown): boolean {
if (isEmpty(value)) return true
const re = /^(?:[^<>()[\]\\.,;:\s@"]+(?:\.[^<>()[\]\\.,;:\s@"]+)*|".+")@(?:\[\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\]|(?:[a-z\-\d]+\.)+[a-z]{2,})$/i
if (Array.isArray(value)) return value.every(val => re.test(String(val)))
return re.test(String(value))
}
export function urlValidator(value: unknown): boolean {
if (isEmpty(value)) return true
const re = /^https?:\/\/[^\s$.?#].\S*$/
return re.test(String(value))
}
export function regexValidator(value: unknown, regex: RegExp | string): boolean {
if (isEmpty(value)) return true
const regEx = typeof regex === 'string' ? new RegExp(regex) : regex
if (Array.isArray(value)) return value.every(val => regexValidator(val, regEx))
return regEx.test(String(value))
}