1
1
import { computed , reactive , type Ref , ref , toRaw } from 'vue'
2
2
import { cloneDeep , debounce , isEqual } from 'lodash'
3
+ import { objectToFormData } from 'object-form-encoder'
3
4
import type {
4
5
Payload ,
5
6
PayloadData ,
@@ -12,14 +13,21 @@ import type {
12
13
} from '../types'
13
14
import { usePrecognitionConfig } from '../composables/usePrecognitionConfig'
14
15
import {
15
- CONTENT_TYPE_HEADER ,
16
16
PRECOGNITION_HEADER ,
17
17
PRECOGNITION_ONLY_HEADER ,
18
18
PRECOGNITION_SUCCESS_HEADER ,
19
+ STATUS_NO_CONTENT ,
20
+ STATUS_VALIDATION_ERROR ,
19
21
} from '../utils/constants'
20
22
import { clearFiles , hasFiles } from '../utils/files'
21
23
import { useSanctumClient } from '#imports'
22
24
25
+ type FormProcessParams < T extends Payload > = {
26
+ precognitive : boolean
27
+ fields : PayloadKey < T > [ ]
28
+ options ?: ValidationOptions
29
+ }
30
+
23
31
// TODO: implement a Nuxt UI compatible version of this composable (via decorator?)
24
32
export const usePrecognitionForm = < T extends Payload > (
25
33
method : RequestMethod ,
@@ -39,23 +47,24 @@ export const usePrecognitionForm = <T extends Payload>(
39
47
const _client = useSanctumClient ( )
40
48
41
49
// TODO: refactor and decompose this function (separate current state and arguments)
42
- async function process ( params : { precognitive : boolean , fields : PayloadKey < T > [ ] , options ?: ValidationOptions } = { precognitive : false , fields : [ ] , options : { } } ) : Promise < ResponseType > {
43
- // TODO: use object-form-encoder (and test with files attached)
44
- let payload = form . data ( )
50
+ async function process ( params : FormProcessParams < T > = {
51
+ precognitive : false ,
52
+ fields : [ ] ,
53
+ options : { } ,
54
+ } ) : Promise < ResponseType > {
55
+ let payload = form . data ( ) as object
45
56
46
57
const headers = new Headers ( )
47
58
const includeFiles = params . options ?. validateFiles ?? _config . validateFiles
48
59
49
60
if ( hasFiles ( payload ) ) {
50
- if ( includeFiles ) {
51
- headers . set ( CONTENT_TYPE_HEADER , 'multipart/form-data' )
61
+ if ( params . precognitive && ! includeFiles ) {
62
+ console . warn ( 'Files were detected in the payload but will not be sent. '
63
+ + 'To include files, set `validateFiles` to `true` in the validation options or module config.' )
64
+ payload = clearFiles ( payload )
52
65
}
53
66
else {
54
- if ( params . precognitive ) {
55
- console . warn ( 'Files were detected in the payload but will not be sent. '
56
- + 'To include files, set `validateFiles` to `true` in the validation options or module config.' )
57
- payload = clearFiles ( payload )
58
- }
67
+ payload = objectToFormData ( payload )
59
68
}
60
69
}
61
70
@@ -83,7 +92,10 @@ export const usePrecognitionForm = <T extends Payload>(
83
92
console . warn ( 'Did not receive a Precognition response. Ensure you have the Precognition middleware in place for the route.' )
84
93
}
85
94
86
- if ( response . status === 204 && response . headers . get ( PRECOGNITION_SUCCESS_HEADER ) === 'true' ) {
95
+ if (
96
+ response . status === STATUS_NO_CONTENT
97
+ && response . headers . get ( PRECOGNITION_SUCCESS_HEADER ) === 'true'
98
+ ) {
87
99
if ( params . fields . length > 0 ) {
88
100
const validatedNew = new Set ( _validated . value )
89
101
@@ -105,7 +117,7 @@ export const usePrecognitionForm = <T extends Payload>(
105
117
return Promise . resolve ( response )
106
118
}
107
119
108
- if ( response . status === 422 ) {
120
+ if ( response . status === STATUS_VALIDATION_ERROR ) {
109
121
form . setErrors ( response . _data . errors as PayloadErrors < T > )
110
122
}
111
123
@@ -226,7 +238,7 @@ export const usePrecognitionForm = <T extends Payload>(
226
238
options . onSuccess ( response )
227
239
} )
228
240
. catch ( ( response : ResponseType ) => {
229
- if ( response . status === 422 ) {
241
+ if ( response . status === STATUS_VALIDATION_ERROR ) {
230
242
if ( ! options ?. onValidationError ) {
231
243
return
232
244
}
0 commit comments