@@ -66,18 +66,17 @@ import {
66
66
type InstancePath ,
67
67
} from "~/shared/awareness" ;
68
68
import { updateWebstudioData } from "~/shared/instance-utils" ;
69
- import {
70
- computeExpression ,
71
- rebindTreeVariablesMutable ,
72
- } from "~/shared/data-variables" ;
69
+ import { rebindTreeVariablesMutable } from "~/shared/data-variables" ;
73
70
import { parseCurl , type CurlRequest } from "./curl" ;
74
71
75
72
export const parseResource = ( {
76
73
id,
74
+ control,
77
75
name,
78
76
formData,
79
77
} : {
80
78
id : string ;
79
+ control ?: string ;
81
80
name ?: string ;
82
81
formData : FormData ;
83
82
} ) => {
@@ -87,6 +86,7 @@ export const parseResource = ({
87
86
const headerValues = formData . getAll ( "header-value" ) as string [ ] ;
88
87
return Resource . parse ( {
89
88
id,
89
+ control,
90
90
name : name ?? formData . get ( "name" ) ,
91
91
url : formData . get ( "url" ) ,
92
92
searchParams : searchParamNames
@@ -253,7 +253,7 @@ const SearchParamPair = ({
253
253
} ) => {
254
254
const evaluatedValue = evaluateExpressionWithinScope ( value , scope ) ;
255
255
// expressions with variables or objects cannot be edited from input
256
- const isValueUnbound =
256
+ const isValueUnboundString =
257
257
isLiteralExpression ( value ) && typeof evaluatedValue === "string" ;
258
258
return (
259
259
< Grid
@@ -274,7 +274,7 @@ const SearchParamPair = ({
274
274
< InputField
275
275
placeholder = "Value"
276
276
name = "search-param-value-literal"
277
- disabled = { ! isValueUnbound }
277
+ disabled = { ! isValueUnboundString }
278
278
value = { serializeValue ( evaluatedValue ) }
279
279
// update text value as string literal
280
280
onChange = { ( event ) =>
@@ -284,7 +284,7 @@ const SearchParamPair = ({
284
284
< BindingPopover
285
285
scope = { scope }
286
286
aliases = { aliases }
287
- variant = { isValueUnbound ? "default" : "bound" }
287
+ variant = { isLiteralExpression ( value ) ? "default" : "bound" }
288
288
value = { value }
289
289
onChange = { ( newValue ) => onChange ( name , newValue ) }
290
290
onRemove = { ( evaluatedValue ) =>
@@ -377,7 +377,7 @@ const HeaderPair = ({
377
377
} ) => {
378
378
const evaluatedValue = evaluateExpressionWithinScope ( value , scope ) ;
379
379
// expressions with variables or objects cannot be edited from input
380
- const isValueUnbound =
380
+ const isValueUnboundString =
381
381
isLiteralExpression ( value ) && typeof evaluatedValue === "string" ;
382
382
return (
383
383
< Grid
@@ -398,7 +398,7 @@ const HeaderPair = ({
398
398
< InputField
399
399
placeholder = "Value"
400
400
name = "header-value-validator"
401
- disabled = { ! isValueUnbound }
401
+ disabled = { ! isValueUnboundString }
402
402
value = { serializeValue ( evaluatedValue ) }
403
403
// update text value as string literal
404
404
onChange = { ( event ) =>
@@ -408,7 +408,7 @@ const HeaderPair = ({
408
408
< BindingPopover
409
409
scope = { scope }
410
410
aliases = { aliases }
411
- variant = { isValueUnbound ? "default" : "bound" }
411
+ variant = { isLiteralExpression ( value ) ? "default" : "bound" }
412
412
value = { value }
413
413
onChange = { ( newValue ) => onChange ( name , newValue ) }
414
414
onRemove = { ( evaluatedValue ) =>
@@ -558,7 +558,7 @@ export const getResourceScopeForInstance = ({
558
558
const name = encodeDataVariableId ( dataSourceId ) ;
559
559
scope [ name ] = value ;
560
560
aliases . set ( name , dataSource . name ) ;
561
- variableValues . set ( dataSource . name , value ) ;
561
+ variableValues . set ( dataSourceId , value ) ;
562
562
}
563
563
}
564
564
}
@@ -621,7 +621,7 @@ export const useResourceScope = ({ variable }: { variable?: DataSource }) => {
621
621
const key = encodeDataVariableId ( variable . id ) ;
622
622
delete newScope [ key ] ;
623
623
newAliases . delete ( key ) ;
624
- newVariableValues . delete ( variable . name ) ;
624
+ newVariableValues . delete ( variable . id ) ;
625
625
}
626
626
return {
627
627
scope : newScope ,
@@ -796,7 +796,10 @@ const parseHeaders = (headers: Resource["headers"]) => {
796
796
let maxAge : undefined | string ;
797
797
let bodyType : BodyType ;
798
798
const newHeaders = headers . filter ( ( header ) => {
799
- const value = computeExpression ( header . value , new Map ( ) ) . toLowerCase ( ) ;
799
+ // cast raw expression result to string
800
+ const value = String (
801
+ evaluateExpressionWithinScope ( header . value , { } )
802
+ ) . toLowerCase ( ) ;
800
803
if ( isCacheControl ( header . name ) ) {
801
804
// move simple header like Cache-Control: max-age=10 to dedicated input
802
805
// preserve more complex cache-control
@@ -818,7 +821,7 @@ const parseHeaders = (headers: Resource["headers"]) => {
818
821
return false ;
819
822
}
820
823
}
821
- return false ;
824
+ return true ;
822
825
} ) ;
823
826
return { headers : newHeaders , maxAge, bodyType } ;
824
827
} ;
@@ -980,8 +983,6 @@ export const SystemResourceForm = forwardRef<
980
983
? resources . get ( variable . resourceId )
981
984
: undefined ;
982
985
983
- const method = "get" ;
984
-
985
986
const localResources = [
986
987
{
987
988
label : "Sitemap" ,
@@ -1006,19 +1007,15 @@ export const SystemResourceForm = forwardRef<
1006
1007
if ( scopeInstanceId === undefined ) {
1007
1008
return ;
1008
1009
}
1009
- const name = z . string ( ) . parse ( formData . get ( "name" ) ) ;
1010
- const newResource : Resource = {
1010
+ const newResource : Resource = parseResource ( {
1011
1011
id : resource ?. id ?? nanoid ( ) ,
1012
- name,
1013
1012
control : "system" ,
1014
- url : localResource . value ,
1015
- method,
1016
- headers : [ ] ,
1017
- } ;
1013
+ formData,
1014
+ } ) ;
1018
1015
const newVariable : DataSource = {
1019
1016
id : variable ?. id ?? nanoid ( ) ,
1020
1017
scopeInstanceId,
1021
- name,
1018
+ name : newResource . name ,
1022
1019
type : "resource" ,
1023
1020
resourceId : newResource . id ,
1024
1021
} ;
@@ -1037,6 +1034,8 @@ export const SystemResourceForm = forwardRef<
1037
1034
1038
1035
return (
1039
1036
< >
1037
+ < input type = "hidden" name = "method" value = "get" />
1038
+ < input type = "hidden" name = "url" value = { localResource . value } />
1040
1039
< Flex direction = "column" css = { { gap : theme . spacing [ 3 ] } } >
1041
1040
< Label htmlFor = { resourceId } > Resource</ Label >
1042
1041
< Select
@@ -1116,29 +1115,15 @@ export const GraphqlResourceForm = forwardRef<
1116
1115
if ( scopeInstanceId === undefined ) {
1117
1116
return ;
1118
1117
}
1119
- const name = z . string ( ) . parse ( formData . get ( "name" ) ) ;
1120
- const body = generateObjectExpression (
1121
- new Map ( [
1122
- [ "query" , JSON . stringify ( query ) ] ,
1123
- [ "variables" , variables ] ,
1124
- ] )
1125
- ) ;
1126
- const newResource : Resource = {
1118
+ const newResource = parseResource ( {
1127
1119
id : resource ?. id ?? nanoid ( ) ,
1128
- name,
1129
1120
control : "graphql" ,
1130
- url,
1131
- method : "post" ,
1132
- headers : [
1133
- ...headers ,
1134
- { name : "Content-Type" , value : "application/json" } ,
1135
- ] ,
1136
- body,
1137
- } ;
1121
+ formData,
1122
+ } ) ;
1138
1123
const newVariable : DataSource = {
1139
1124
id : variable ?. id ?? nanoid ( ) ,
1140
1125
scopeInstanceId,
1141
- name,
1126
+ name : newResource . name ,
1142
1127
type : "resource" ,
1143
1128
resourceId : newResource . id ,
1144
1129
} ;
@@ -1155,6 +1140,28 @@ export const GraphqlResourceForm = forwardRef<
1155
1140
1156
1141
return (
1157
1142
< >
1143
+ < input type = "hidden" name = "method" value = "post" />
1144
+ { ! headers . some ( ( { name } ) => isContentType ( name ) ) && (
1145
+ < >
1146
+ < input type = "hidden" name = "header-name" value = "Content-Type" />
1147
+ < input
1148
+ type = "hidden"
1149
+ name = "header-value"
1150
+ value = { `"application/json"` }
1151
+ />
1152
+ </ >
1153
+ ) }
1154
+ < input
1155
+ type = "hidden"
1156
+ name = "body"
1157
+ value = { generateObjectExpression (
1158
+ new Map ( [
1159
+ [ "query" , JSON . stringify ( query ) ] ,
1160
+ [ "variables" , variables ] ,
1161
+ ] )
1162
+ ) }
1163
+ />
1164
+
1158
1165
< UrlField
1159
1166
scope = { scope }
1160
1167
aliases = { aliases }
0 commit comments