Skip to content

Commit 375eb65

Browse files
committed
chore: show a warning when arguments are missing
1 parent 163de52 commit 375eb65

File tree

1 file changed

+62
-38
lines changed

1 file changed

+62
-38
lines changed

packages/core/src/validation.ts

Lines changed: 62 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import { z } from "zod";
2-
import type { DynamicValue, DataModel, LogicExpression } from "./types";
3-
import { DynamicValueSchema, resolveDynamicValue } from "./types";
4-
import { LogicExpressionSchema, evaluateLogicExpression } from "./visibility";
1+
import { z } from 'zod';
2+
import type { DynamicValue, DataModel, LogicExpression } from './types';
3+
import { DynamicValueSchema, resolveDynamicValue } from './types';
4+
import { LogicExpressionSchema, evaluateLogicExpression } from './visibility';
55

66
/**
77
* Validation check definition
@@ -22,7 +22,7 @@ export interface ValidationConfig {
2222
/** Array of checks to run */
2323
checks?: ValidationCheck[];
2424
/** When to run validation */
25-
validateOn?: "change" | "blur" | "submit";
25+
validateOn?: 'change' | 'blur' | 'submit';
2626
/** Condition for when validation is enabled */
2727
enabled?: LogicExpression;
2828
}
@@ -41,7 +41,7 @@ export const ValidationCheckSchema = z.object({
4141
*/
4242
export const ValidationConfigSchema = z.object({
4343
checks: z.array(ValidationCheckSchema).optional(),
44-
validateOn: z.enum(["change", "blur", "submit"]).optional(),
44+
validateOn: z.enum(['change', 'blur', 'submit']).optional(),
4545
enabled: LogicExpressionSchema.optional(),
4646
});
4747

@@ -50,7 +50,7 @@ export const ValidationConfigSchema = z.object({
5050
*/
5151
export type ValidationFunction = (
5252
value: unknown,
53-
args?: Record<string, unknown>,
53+
args?: Record<string, unknown>
5454
) => boolean;
5555

5656
/**
@@ -72,7 +72,7 @@ export const builtInValidationFunctions: Record<string, ValidationFunction> = {
7272
*/
7373
required: (value: unknown) => {
7474
if (value === null || value === undefined) return false;
75-
if (typeof value === "string") return value.trim().length > 0;
75+
if (typeof value === 'string') return value.trim().length > 0;
7676
if (Array.isArray(value)) return value.length > 0;
7777
return true;
7878
},
@@ -81,37 +81,49 @@ export const builtInValidationFunctions: Record<string, ValidationFunction> = {
8181
* Check if value is a valid email address
8282
*/
8383
email: (value: unknown) => {
84-
if (typeof value !== "string") return false;
84+
if (typeof value !== 'string') return false;
8585
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value);
8686
},
8787

8888
/**
8989
* Check minimum string length
9090
*/
9191
minLength: (value: unknown, args?: Record<string, unknown>) => {
92-
if (typeof value !== "string") return false;
92+
if (typeof value !== 'string') return false;
9393
const min = args?.min;
94-
if (typeof min !== "number") return false;
94+
if (min === undefined) {
95+
console.warn('minLength validation requires a min argument');
96+
return false;
97+
}
98+
if (typeof min !== 'number') return false;
9599
return value.length >= min;
96100
},
97101

98102
/**
99103
* Check maximum string length
100104
*/
101105
maxLength: (value: unknown, args?: Record<string, unknown>) => {
102-
if (typeof value !== "string") return false;
106+
if (typeof value !== 'string') return false;
103107
const max = args?.max;
104-
if (typeof max !== "number") return false;
108+
if (max === undefined) {
109+
console.warn('maxLength validation requires a max argument');
110+
return false;
111+
}
112+
if (typeof max !== 'number') return false;
105113
return value.length <= max;
106114
},
107115

108116
/**
109117
* Check if string matches a regex pattern
110118
*/
111119
pattern: (value: unknown, args?: Record<string, unknown>) => {
112-
if (typeof value !== "string") return false;
120+
if (typeof value !== 'string') return false;
113121
const pattern = args?.pattern;
114-
if (typeof pattern !== "string") return false;
122+
if (pattern === undefined) {
123+
console.warn('pattern validation requires a pattern argument');
124+
return false;
125+
}
126+
if (typeof pattern !== 'string') return false;
115127
try {
116128
return new RegExp(pattern).test(value);
117129
} catch {
@@ -123,36 +135,44 @@ export const builtInValidationFunctions: Record<string, ValidationFunction> = {
123135
* Check minimum numeric value
124136
*/
125137
min: (value: unknown, args?: Record<string, unknown>) => {
126-
if (typeof value !== "number") return false;
138+
if (typeof value !== 'number') return false;
127139
const min = args?.min;
128-
if (typeof min !== "number") return false;
140+
if (min === undefined) {
141+
console.warn('min validation requires a value argument');
142+
return false;
143+
}
144+
if (typeof min !== 'number') return false;
129145
return value >= min;
130146
},
131147

132148
/**
133149
* Check maximum numeric value
134150
*/
135151
max: (value: unknown, args?: Record<string, unknown>) => {
136-
if (typeof value !== "number") return false;
152+
if (typeof value !== 'number') return false;
137153
const max = args?.max;
138-
if (typeof max !== "number") return false;
154+
if (max === undefined) {
155+
console.warn('max validation requires a value argument');
156+
return false;
157+
}
158+
if (typeof max !== 'number') return false;
139159
return value <= max;
140160
},
141161

142162
/**
143163
* Check if value is a number
144164
*/
145165
numeric: (value: unknown) => {
146-
if (typeof value === "number") return !isNaN(value);
147-
if (typeof value === "string") return !isNaN(parseFloat(value));
166+
if (typeof value === 'number') return !isNaN(value);
167+
if (typeof value === 'string') return !isNaN(parseFloat(value));
148168
return false;
149169
},
150170

151171
/**
152172
* Check if value is a valid URL
153173
*/
154174
url: (value: unknown) => {
155-
if (typeof value !== "string") return false;
175+
if (typeof value !== 'string') return false;
156176
try {
157177
new URL(value);
158178
return true;
@@ -166,6 +186,10 @@ export const builtInValidationFunctions: Record<string, ValidationFunction> = {
166186
*/
167187
matches: (value: unknown, args?: Record<string, unknown>) => {
168188
const other = args?.other;
189+
if (other === undefined) {
190+
console.warn('matches validation requires a value argument');
191+
return false;
192+
}
169193
return value === other;
170194
},
171195
};
@@ -205,7 +229,7 @@ export interface ValidationContext {
205229
*/
206230
export function runValidationCheck(
207231
check: ValidationCheck,
208-
ctx: ValidationContext,
232+
ctx: ValidationContext
209233
): ValidationCheckResult {
210234
const { value, dataModel, customFunctions } = ctx;
211235

@@ -244,7 +268,7 @@ export function runValidationCheck(
244268
*/
245269
export function runValidation(
246270
config: ValidationConfig,
247-
ctx: ValidationContext & { authState?: { isSignedIn: boolean } },
271+
ctx: ValidationContext & { authState?: { isSignedIn: boolean } }
248272
): ValidationResult {
249273
const checks: ValidationCheckResult[] = [];
250274
const errors: string[] = [];
@@ -282,56 +306,56 @@ export function runValidation(
282306
* Helper to create validation checks
283307
*/
284308
export const check = {
285-
required: (message = "This field is required"): ValidationCheck => ({
286-
fn: "required",
309+
required: (message = 'This field is required'): ValidationCheck => ({
310+
fn: 'required',
287311
message,
288312
}),
289313

290-
email: (message = "Invalid email address"): ValidationCheck => ({
291-
fn: "email",
314+
email: (message = 'Invalid email address'): ValidationCheck => ({
315+
fn: 'email',
292316
message,
293317
}),
294318

295319
minLength: (min: number, message?: string): ValidationCheck => ({
296-
fn: "minLength",
320+
fn: 'minLength',
297321
args: { min },
298322
message: message ?? `Must be at least ${min} characters`,
299323
}),
300324

301325
maxLength: (max: number, message?: string): ValidationCheck => ({
302-
fn: "maxLength",
326+
fn: 'maxLength',
303327
args: { max },
304328
message: message ?? `Must be at most ${max} characters`,
305329
}),
306330

307-
pattern: (pattern: string, message = "Invalid format"): ValidationCheck => ({
308-
fn: "pattern",
331+
pattern: (pattern: string, message = 'Invalid format'): ValidationCheck => ({
332+
fn: 'pattern',
309333
args: { pattern },
310334
message,
311335
}),
312336

313337
min: (min: number, message?: string): ValidationCheck => ({
314-
fn: "min",
338+
fn: 'min',
315339
args: { min },
316340
message: message ?? `Must be at least ${min}`,
317341
}),
318342

319343
max: (max: number, message?: string): ValidationCheck => ({
320-
fn: "max",
344+
fn: 'max',
321345
args: { max },
322346
message: message ?? `Must be at most ${max}`,
323347
}),
324348

325-
url: (message = "Invalid URL"): ValidationCheck => ({
326-
fn: "url",
349+
url: (message = 'Invalid URL'): ValidationCheck => ({
350+
fn: 'url',
327351
message,
328352
}),
329353

330354
matches: (
331355
otherPath: string,
332-
message = "Fields must match",
356+
message = 'Fields must match'
333357
): ValidationCheck => ({
334-
fn: "matches",
358+
fn: 'matches',
335359
args: { other: { path: otherPath } },
336360
message,
337361
}),

0 commit comments

Comments
 (0)