1- /** @import { RemoteFormInput, RemoteForm } from '@sveltejs/kit' */
1+ /** @import { RemoteFormInput, RemoteForm, InvalidField } from '@sveltejs/kit' */
22/** @import { InternalRemoteFormIssue, MaybePromise, RemoteInfo } from 'types' */
33/** @import { StandardSchemaV1 } from '@standard-schema/spec' */
44import { get_request_store } from '@sveltejs/kit/internal/server' ;
@@ -12,6 +12,7 @@ import {
1212 flatten_issues
1313} from '../../../form-utils.js' ;
1414import { get_cache , run_remote_function } from './shared.js' ;
15+ import { ValidationError } from '@sveltejs/kit/internal' ;
1516
1617/**
1718 * Creates a form object that can be spread onto a `<form>` element.
@@ -20,7 +21,7 @@ import { get_cache, run_remote_function } from './shared.js';
2021 *
2122 * @template Output
2223 * @overload
23- * @param {(invalid: import('@sveltejs/kit').Invalid<void> ) => MaybePromise<Output> } fn
24+ * @param {() => MaybePromise<Output> } fn
2425 * @returns {RemoteForm<void, Output> }
2526 * @since 2.27
2627 */
@@ -33,7 +34,7 @@ import { get_cache, run_remote_function } from './shared.js';
3334 * @template Output
3435 * @overload
3536 * @param {'unchecked' } validate
36- * @param {(data: Input, invalid: import('@sveltejs/kit').Invalid <Input>) => MaybePromise<Output> } fn
37+ * @param {(data: Input, issue: InvalidField <Input>) => MaybePromise<Output> } fn
3738 * @returns {RemoteForm<Input, Output> }
3839 * @since 2.27
3940 */
@@ -46,15 +47,15 @@ import { get_cache, run_remote_function } from './shared.js';
4647 * @template Output
4748 * @overload
4849 * @param {Schema } validate
49- * @param {(data: StandardSchemaV1.InferOutput<Schema>, invalid: import('@sveltejs/kit').Invalid <StandardSchemaV1.InferInput<Schema>>) => MaybePromise<Output> } fn
50+ * @param {(data: StandardSchemaV1.InferOutput<Schema>, issue: InvalidField <StandardSchemaV1.InferInput<Schema>>) => MaybePromise<Output> } fn
5051 * @returns {RemoteForm<StandardSchemaV1.InferInput<Schema>, Output> }
5152 * @since 2.27
5253 */
5354/**
5455 * @template {RemoteFormInput} Input
5556 * @template Output
5657 * @param {any } validate_or_fn
57- * @param {(data_or_invalid : any, invalid ?: any) => MaybePromise<Output> } [maybe_fn]
58+ * @param {(data_or_issue : any, issue ?: any) => MaybePromise<Output> } [maybe_fn]
5859 * @returns {RemoteForm<Input, Output> }
5960 * @since 2.27
6061 */
@@ -152,7 +153,7 @@ export function form(validate_or_fn, maybe_fn) {
152153
153154 state . refreshes ??= { } ;
154155
155- const invalid = create_invalid ( ) ;
156+ const issue = create_issues ( ) ;
156157
157158 try {
158159 output . result = await run_remote_function (
@@ -161,7 +162,7 @@ export function form(validate_or_fn, maybe_fn) {
161162 true ,
162163 data ,
163164 ( d ) => d ,
164- ( data ) => ( ! maybe_fn ? fn ( invalid ) : fn ( data , invalid ) )
165+ ( data ) => ( ! maybe_fn ? fn ( ) : fn ( data , issue ) )
165166 ) ;
166167 } catch ( e ) {
167168 if ( e instanceof ValidationError ) {
@@ -314,89 +315,72 @@ function handle_issues(output, issues, form_data) {
314315
315316/**
316317 * Creates an invalid function that can be used to imperatively mark form fields as invalid
317- * @returns {import('@sveltejs/kit').Invalid }
318+ * @returns {InvalidField<any> }
318319 */
319- function create_invalid ( ) {
320- /**
321- * @param {...(string | StandardSchemaV1.Issue) } issues
322- * @returns {never }
323- */
324- function invalid ( ...issues ) {
325- throw new ValidationError (
326- issues . map ( ( issue ) => {
327- if ( typeof issue === 'string' ) {
328- return {
329- path : [ ] ,
330- message : issue
331- } ;
320+ function create_issues ( ) {
321+ return /** @type {InvalidField<any> } */ (
322+ new Proxy (
323+ /** @param {string } message */
324+ ( message ) => {
325+ // TODO 3.0 remove
326+ if ( typeof message !== 'string' ) {
327+ throw new Error (
328+ '`invalid` should now be imported from `@sveltejs/kit` to throw validation issues. ' +
329+ "The second parameter provided to the form function (renamed to `issue`) is still used to construct issues, e.g. `invalid(issue.field('message'))`. " +
330+ 'For more info see https://github.com/sveltejs/kit/pulls/14768'
331+ ) ;
332332 }
333333
334- return issue ;
335- } )
336- ) ;
337- }
338-
339- return /** @type {import('@sveltejs/kit').Invalid } */ (
340- new Proxy ( invalid , {
341- get ( target , prop ) {
342- if ( typeof prop === 'symbol' ) return /** @type {any } */ ( target ) [ prop ] ;
334+ return create_issue ( message ) ;
335+ } ,
336+ {
337+ get ( target , prop ) {
338+ if ( typeof prop === 'symbol' ) return /** @type {any } */ ( target ) [ prop ] ;
343339
344- /**
345- * @param {string } message
346- * @param {(string | number)[] } path
347- * @returns {StandardSchemaV1.Issue }
348- */
349- const create_issue = ( message , path = [ ] ) => ( {
350- message,
351- path
352- } ) ;
353-
354- return create_issue_proxy ( prop , create_issue , [ ] ) ;
340+ return create_issue_proxy ( prop , [ ] ) ;
341+ }
355342 }
356- } )
343+ )
357344 ) ;
358- }
359345
360- /**
361- * Error thrown when form validation fails imperatively
362- */
363- class ValidationError extends Error {
364346 /**
365- * @param {StandardSchemaV1.Issue[] } issues
347+ * @param {string } message
348+ * @param {(string | number)[] } path
349+ * @returns {StandardSchemaV1.Issue }
366350 */
367- constructor ( issues ) {
368- super ( 'Validation failed' ) ;
369- this . name = 'ValidationError' ;
370- this . issues = issues ;
351+ function create_issue ( message , path = [ ] ) {
352+ return {
353+ message,
354+ path
355+ } ;
371356 }
372- }
373-
374- /**
375- * Creates a proxy that builds up a path and returns a function to create an issue
376- * @param {string | number } key
377- * @param {(message: string, path: (string | number)[]) => StandardSchemaV1.Issue } create_issue
378- * @param {(string | number)[] } path
379- */
380- function create_issue_proxy ( key , create_issue , path ) {
381- const new_path = [ ...path , key ] ;
382357
383358 /**
384- * @param {string } message
385- * @returns {StandardSchemaV1.Issue }
359+ * Creates a proxy that builds up a path and returns a function to create an issue
360+ * @param {string | number } key
361+ * @param {(string | number)[] } path
386362 */
387- const issue_func = ( message ) => create_issue ( message , new_path ) ;
363+ function create_issue_proxy ( key , path ) {
364+ const new_path = [ ...path , key ] ;
388365
389- return new Proxy ( issue_func , {
390- get ( target , prop ) {
391- if ( typeof prop === 'symbol' ) return /** @type {any } */ ( target ) [ prop ] ;
366+ /**
367+ * @param {string } message
368+ * @returns {StandardSchemaV1.Issue }
369+ */
370+ const issue_func = ( message ) => create_issue ( message , new_path ) ;
392371
393- // Handle array access like invalid.items[0]
394- if ( / ^ \d + $ / . test ( prop ) ) {
395- return create_issue_proxy ( parseInt ( prop , 10 ) , create_issue , new_path ) ;
396- }
372+ return new Proxy ( issue_func , {
373+ get ( target , prop ) {
374+ if ( typeof prop === 'symbol' ) return /** @type {any } */ ( target ) [ prop ] ;
397375
398- // Handle property access like invalid.field.nested
399- return create_issue_proxy ( prop , create_issue , new_path ) ;
400- }
401- } ) ;
376+ // Handle array access like invalid.items[0]
377+ if ( / ^ \d + $ / . test ( prop ) ) {
378+ return create_issue_proxy ( parseInt ( prop , 10 ) , new_path ) ;
379+ }
380+
381+ // Handle property access like invalid.field.nested
382+ return create_issue_proxy ( prop , new_path ) ;
383+ }
384+ } ) ;
385+ }
402386}
0 commit comments