mirror of
https://github.com/enso-org/enso.git
synced 2024-12-26 23:22:36 +03:00
Widget support for Data.fetch and Data.post. (#11199)
- Add `pretty` for `Date` and `Time`. - Add constructors for `JS_Object` and `Dictionary` to the component browser. - Add widgets to `Dictionary` methods. ![image](https://github.com/user-attachments/assets/4f6c58d5-9eb5-40e5-96c1-2e06e23051d0) - Add conversion from Vector to Dictionary. - Add `pair` method shorthand for `Pair.Value`. - Created widget for `Header`. - Added widgets for `Data.fetch` and `Data.post`. - Added widgets for `Request_Body` constructors. - Update the Forbidden Operation message to be friendlier. ![image](https://github.com/user-attachments/assets/eaac5def-a91f-450f-b814-d776311962e3) Video before fixing Forbidden Message: https://github.com/user-attachments/assets/f9c4bde4-3f0a-49f1-a3ca-a0aaa3219286
This commit is contained in:
parent
ecfe959c29
commit
28bbc34257
@ -16,7 +16,7 @@ instance =
|
|||||||
## PRIVATE
|
## PRIVATE
|
||||||
create_dry_run_file file copy_original =
|
create_dry_run_file file copy_original =
|
||||||
_ = [file, copy_original]
|
_ = [file, copy_original]
|
||||||
Error.throw (Forbidden_Operation.Error "Currently dry-run is not supported for S3_File, so writing to an S3_File is forbidden if the Output context is disabled.")
|
Error.throw (Forbidden_Operation.Error "As writing is disabled, no action has been performed. Press the Write button ▶ to write the file.")
|
||||||
|
|
||||||
## PRIVATE
|
## PRIVATE
|
||||||
remote_write_with_local_file file existing_file_behavior action =
|
remote_write_with_local_file file existing_file_behavior action =
|
||||||
|
@ -67,7 +67,7 @@ type S3_File
|
|||||||
value. The value is returned from this method.
|
value. The value is returned from this method.
|
||||||
with_output_stream : Vector File_Access -> (Output_Stream -> Any ! File_Error) -> Any ! File_Error
|
with_output_stream : Vector File_Access -> (Output_Stream -> Any ! File_Error) -> Any ! File_Error
|
||||||
with_output_stream self (open_options : Vector) action = if self.is_directory then Error.throw (S3_Error.Error "S3 directory cannot be opened as a stream." self.uri) else
|
with_output_stream self (open_options : Vector) action = if self.is_directory then Error.throw (S3_Error.Error "S3 directory cannot be opened as a stream." self.uri) else
|
||||||
Context.Output.if_enabled disabled_message="Writing to an S3_File is forbidden as the Output context is disabled." panic=False <|
|
Context.Output.if_enabled disabled_message="As writing is disabled, cannot write to S3. Press the Write button ▶ to perform the operation." panic=False <|
|
||||||
open_as_data_link = (open_options.contains Data_Link_Access.No_Follow . not) && (Data_Link.is_data_link self)
|
open_as_data_link = (open_options.contains Data_Link_Access.No_Follow . not) && (Data_Link.is_data_link self)
|
||||||
if open_as_data_link then Data_Link_Helpers.write_data_link_as_stream self open_options action else
|
if open_as_data_link then Data_Link_Helpers.write_data_link_as_stream self open_options action else
|
||||||
if open_options.contains File_Access.Append then Error.throw (S3_Error.Error "S3 does not support appending to a file. Instead you may read it, modify and then write the new contents." self.uri) else
|
if open_options.contains File_Access.Append then Error.throw (S3_Error.Error "S3 does not support appending to a file. Instead you may read it, modify and then write the new contents." self.uri) else
|
||||||
@ -251,7 +251,7 @@ type S3_File
|
|||||||
copy_to : File_Like -> Boolean -> Any ! S3_Error | File_Error
|
copy_to : File_Like -> Boolean -> Any ! S3_Error | File_Error
|
||||||
copy_to self (destination : File_Like) (replace_existing : Boolean = False) = Data_Link_Helpers.disallow_links_in_copy self destination <|
|
copy_to self (destination : File_Like) (replace_existing : Boolean = False) = Data_Link_Helpers.disallow_links_in_copy self destination <|
|
||||||
if self.is_directory then Error.throw (S3_Error.Error "Copying S3 folders is currently not implemented." self.uri) else
|
if self.is_directory then Error.throw (S3_Error.Error "Copying S3 folders is currently not implemented." self.uri) else
|
||||||
Context.Output.if_enabled disabled_message="Copying an S3_File is forbidden as the Output context is disabled." panic=False <|
|
Context.Output.if_enabled disabled_message="As writing is disabled, cannot copy to a file. Press the Write button ▶ to perform the operation." panic=False <|
|
||||||
destination_writable = Writable_File.from destination
|
destination_writable = Writable_File.from destination
|
||||||
case destination_writable.file of
|
case destination_writable.file of
|
||||||
# Special shortcut for more efficient handling of S3 file copying (no need to move the data to our machine)
|
# Special shortcut for more efficient handling of S3 file copying (no need to move the data to our machine)
|
||||||
@ -292,7 +292,7 @@ type S3_File
|
|||||||
move_to self (destination : File_Like) (replace_existing : Boolean = False) =
|
move_to self (destination : File_Like) (replace_existing : Boolean = False) =
|
||||||
if self.is_directory then Error.throw (S3_Error.Error "Moving S3 folders is currently not implemented." self.uri) else
|
if self.is_directory then Error.throw (S3_Error.Error "Moving S3 folders is currently not implemented." self.uri) else
|
||||||
Data_Link_Helpers.disallow_links_in_move self destination <|
|
Data_Link_Helpers.disallow_links_in_move self destination <|
|
||||||
Context.Output.if_enabled disabled_message="File moving is forbidden as the Output context is disabled." panic=False <|
|
Context.Output.if_enabled disabled_message="As writing is disabled, cannot move the file. Press the Write button ▶ to perform the operation." panic=False <|
|
||||||
r = self.copy_to destination replace_existing=replace_existing
|
r = self.copy_to destination replace_existing=replace_existing
|
||||||
r.if_not_error <|
|
r.if_not_error <|
|
||||||
# If source and destination are the same, we do not want to delete the file
|
# If source and destination are the same, we do not want to delete the file
|
||||||
@ -341,7 +341,7 @@ type S3_File
|
|||||||
will occur.
|
will occur.
|
||||||
delete_if_exists : Boolean -> Nothing
|
delete_if_exists : Boolean -> Nothing
|
||||||
delete_if_exists self (recursive : Boolean = False) =
|
delete_if_exists self (recursive : Boolean = False) =
|
||||||
Context.Output.if_enabled disabled_message="Deleting an S3_File is forbidden as the Output context is disabled." panic=False <|
|
Context.Output.if_enabled disabled_message="As writing is disabled, cannot delete the file. Press the Write button ▶ to perform the operation." panic=False <|
|
||||||
case self.is_directory of
|
case self.is_directory of
|
||||||
True ->
|
True ->
|
||||||
# This is a temporary simplified implementation to ensure cleaning up after tests
|
# This is a temporary simplified implementation to ensure cleaning up after tests
|
||||||
|
@ -196,8 +196,9 @@ list (directory:(Text | File)=enso_project.root) (name_filter:Text="") recursive
|
|||||||
Data.fetch URL . body . write file
|
Data.fetch URL . body . write file
|
||||||
@uri Text_Input
|
@uri Text_Input
|
||||||
@format Data_Read_Helpers.format_widget_with_raw_response
|
@format Data_Read_Helpers.format_widget_with_raw_response
|
||||||
|
@headers Header.default_widget
|
||||||
fetch : (URI | Text) -> HTTP_Method -> Vector (Header | Pair Text Text) -> File_Format -> Any ! Request_Error | HTTP_Error
|
fetch : (URI | Text) -> HTTP_Method -> Vector (Header | Pair Text Text) -> File_Format -> Any ! Request_Error | HTTP_Error
|
||||||
fetch (uri:(URI | Text)) (method:HTTP_Method=HTTP_Method.Get) (headers:(Vector (Header | Pair Text Text))=[]) (format = Auto_Detect) =
|
fetch (uri:(URI | Text)) (method:HTTP_Method=..Get) (headers:(Vector (Header | Pair Text Text))=[]) (format = Auto_Detect) =
|
||||||
Data_Read_Helpers.fetch_following_data_links uri method headers (Data_Read_Helpers.handle_legacy_format "fetch" "format" format)
|
Data_Read_Helpers.fetch_following_data_links uri method headers (Data_Read_Helpers.handle_legacy_format "fetch" "format" format)
|
||||||
|
|
||||||
## ALIAS http post, upload
|
## ALIAS http post, upload
|
||||||
@ -321,9 +322,10 @@ fetch (uri:(URI | Text)) (method:HTTP_Method=HTTP_Method.Get) (headers:(Vector (
|
|||||||
form_data = Dictionary.from_vector [["key", "val"], ["a_file", test_file]]
|
form_data = Dictionary.from_vector [["key", "val"], ["a_file", test_file]]
|
||||||
response = Data.post url_post (Request_Body.Form_Data form_data url_encoded=True)
|
response = Data.post url_post (Request_Body.Form_Data form_data url_encoded=True)
|
||||||
@uri Text_Input
|
@uri Text_Input
|
||||||
|
@headers Header.default_widget
|
||||||
@response_format Data_Read_Helpers.format_widget_with_raw_response
|
@response_format Data_Read_Helpers.format_widget_with_raw_response
|
||||||
post : (URI | Text) -> Request_Body -> HTTP_Method -> Vector (Header | Pair Text Text) -> File_Format -> Any ! Request_Error | HTTP_Error
|
post : (URI | Text) -> Request_Body -> HTTP_Method -> Vector (Header | Pair Text Text) -> File_Format -> Any ! Request_Error | HTTP_Error
|
||||||
post (uri:(URI | Text)) (body:Request_Body=Request_Body.Empty) (method:HTTP_Method=HTTP_Method.Post) (headers:(Vector (Header | Pair Text Text))=[]) (response_format = Auto_Detect) =
|
post (uri:(URI | Text)) (body:Request_Body=..Empty) (method:HTTP_Method=..Post) (headers:(Vector (Header | Pair Text Text))=[]) (response_format = Auto_Detect) =
|
||||||
response = HTTP.post uri body method headers
|
response = HTTP.post uri body method headers
|
||||||
Data_Read_Helpers.decode_http_response_following_data_links response (Data_Read_Helpers.handle_legacy_format "post" "response_format" response_format)
|
Data_Read_Helpers.decode_http_response_following_data_links response (Data_Read_Helpers.handle_legacy_format "post" "response_format" response_format)
|
||||||
|
|
||||||
@ -340,9 +342,10 @@ post (uri:(URI | Text)) (body:Request_Body=Request_Body.Empty) (method:HTTP_Meth
|
|||||||
Defaults to `HTTP_Method.Get`.
|
Defaults to `HTTP_Method.Get`.
|
||||||
- headers: The headers to send with the request. Defaults to an empty vector.
|
- headers: The headers to send with the request. Defaults to an empty vector.
|
||||||
@uri Text_Input
|
@uri Text_Input
|
||||||
|
@headers Header.default_widget
|
||||||
download : (URI | Text) -> Writable_File -> HTTP_Method -> Vector (Header | Pair Text Text) -> File ! Request_Error | HTTP_Error
|
download : (URI | Text) -> Writable_File -> HTTP_Method -> Vector (Header | Pair Text Text) -> File ! Request_Error | HTTP_Error
|
||||||
download (uri:(URI | Text)) file:Writable_File (method:HTTP_Method=HTTP_Method.Get) (headers:(Vector (Header | Pair Text Text))=[]) =
|
download (uri:(URI | Text)) file:Writable_File (method:HTTP_Method=..Get) (headers:(Vector (Header | Pair Text Text))=[]) =
|
||||||
Context.Output.if_enabled disabled_message="Downloading to a file is forbidden as the Output context is disabled." panic=False <|
|
Context.Output.if_enabled disabled_message="As writing is disabled, cannot download to a file. Press the Write button ▶ to perform the operation." panic=False <|
|
||||||
response = HTTP.fetch uri method headers
|
response = HTTP.fetch uri method headers
|
||||||
case Data_Link.is_data_link response.body.metadata of
|
case Data_Link.is_data_link response.body.metadata of
|
||||||
True ->
|
True ->
|
||||||
|
@ -4,12 +4,18 @@ import project.Data.Pair.Pair
|
|||||||
import project.Data.Text.Text
|
import project.Data.Text.Text
|
||||||
import project.Data.Vector.Vector
|
import project.Data.Vector.Vector
|
||||||
import project.Error.Error
|
import project.Error.Error
|
||||||
|
import project.Errors.Common.Missing_Argument
|
||||||
import project.Errors.Illegal_Argument.Illegal_Argument
|
import project.Errors.Illegal_Argument.Illegal_Argument
|
||||||
import project.Errors.No_Such_Key.No_Such_Key
|
import project.Errors.No_Such_Key.No_Such_Key
|
||||||
|
import project.Meta
|
||||||
|
import project.Metadata.Widget
|
||||||
import project.Nothing.Nothing
|
import project.Nothing.Nothing
|
||||||
import project.Panic.Panic
|
import project.Panic.Panic
|
||||||
from project.Data.Boolean import Boolean, False, True
|
from project.Data.Boolean import Boolean, False, True
|
||||||
from project.Data.Text.Extensions import all
|
from project.Data.Text.Extensions import all
|
||||||
|
from project.Metadata.Choice import Option
|
||||||
|
from project.Metadata.Widget import Single_Choice, Vector_Editor
|
||||||
|
from project.Widget_Helpers import make_all_selector
|
||||||
|
|
||||||
## A key-value store. It is possible to use any type as keys and values and mix
|
## A key-value store. It is possible to use any type as keys and values and mix
|
||||||
them in one Dictionary. Keys are checked for equality based on their hash
|
them in one Dictionary. Keys are checked for equality based on their hash
|
||||||
@ -32,14 +38,12 @@ from project.Data.Text.Extensions import all
|
|||||||
to pass a foreign map into Enso, where it will be treated as a Dictionary.
|
to pass a foreign map into Enso, where it will be treated as a Dictionary.
|
||||||
@Builtin_Type
|
@Builtin_Type
|
||||||
type Dictionary key value
|
type Dictionary key value
|
||||||
## PRIVATE
|
## ICON array_new2
|
||||||
ADVANCED
|
|
||||||
Returns an empty dictionary.
|
Returns an empty dictionary.
|
||||||
empty : Dictionary
|
empty : Dictionary
|
||||||
empty = @Builtin_Method "Dictionary.empty"
|
empty = @Builtin_Method "Dictionary.empty"
|
||||||
|
|
||||||
## PRIVATE
|
## ICON array_new2
|
||||||
ADVANCED
|
|
||||||
Returns a single-element dictionary with the given key and value.
|
Returns a single-element dictionary with the given key and value.
|
||||||
A Call to `Dictionary.singleton key value` is the same as a call to
|
A Call to `Dictionary.singleton key value` is the same as a call to
|
||||||
`Dictionary.empty.insert key value`.
|
`Dictionary.empty.insert key value`.
|
||||||
@ -53,12 +57,14 @@ type Dictionary key value
|
|||||||
value 2.
|
value 2.
|
||||||
|
|
||||||
example_singleton = Dictionary.singleton "my_key" 2
|
example_singleton = Dictionary.singleton "my_key" 2
|
||||||
|
@key (make_all_selector ..Always)
|
||||||
|
@value (make_all_selector ..Always)
|
||||||
singleton : Any -> Any -> Dictionary
|
singleton : Any -> Any -> Dictionary
|
||||||
singleton key value = Dictionary.empty.insert key value
|
singleton key value = Dictionary.empty.insert key value
|
||||||
|
|
||||||
## ALIAS dictionary, lookup table
|
## ALIAS dictionary, lookup table
|
||||||
GROUP Constants
|
GROUP Constants
|
||||||
ICON convert
|
ICON array_new2
|
||||||
Builds a dictionary from two Vectors. The first vector contains the keys,
|
Builds a dictionary from two Vectors. The first vector contains the keys,
|
||||||
and the second vector contains the values. The two vectors must be of the
|
and the second vector contains the values. The two vectors must be of the
|
||||||
same length.
|
same length.
|
||||||
@ -71,6 +77,8 @@ type Dictionary key value
|
|||||||
meaning that if two entries in the vector share the same key, an
|
meaning that if two entries in the vector share the same key, an
|
||||||
`Illegal_Argument` error is raised. If set to `False`, the last entry
|
`Illegal_Argument` error is raised. If set to `False`, the last entry
|
||||||
with a given key will be kept.
|
with a given key will be kept.
|
||||||
|
@keys (Vector_Editor item_editor=make_all_selector display=..Always item_default="Nothing")
|
||||||
|
@values (Vector_Editor item_editor=make_all_selector display=..Always item_default="Nothing")
|
||||||
from_keys_and_values : Vector Any -> Vector Any -> Boolean -> Dictionary ! Illegal_Argument
|
from_keys_and_values : Vector Any -> Vector Any -> Boolean -> Dictionary ! Illegal_Argument
|
||||||
from_keys_and_values keys:Vector values:Vector error_on_duplicates:Boolean=True =
|
from_keys_and_values keys:Vector values:Vector error_on_duplicates:Boolean=True =
|
||||||
if keys.length != values.length then Error.throw (Illegal_Argument.Error "`Dictionary.from_keys_and_values` encountered two vectors of different lengths.") else
|
if keys.length != values.length then Error.throw (Illegal_Argument.Error "`Dictionary.from_keys_and_values` encountered two vectors of different lengths.") else
|
||||||
@ -80,7 +88,7 @@ type Dictionary key value
|
|||||||
|
|
||||||
## ALIAS dictionary, lookup table
|
## ALIAS dictionary, lookup table
|
||||||
GROUP Constants
|
GROUP Constants
|
||||||
ICON convert
|
ICON array_new2
|
||||||
Builds a dictionary from a vector of key-value pairs, with each key-value
|
Builds a dictionary from a vector of key-value pairs, with each key-value
|
||||||
pair represented as a 2 element vector.
|
pair represented as a 2 element vector.
|
||||||
|
|
||||||
@ -96,8 +104,9 @@ type Dictionary key value
|
|||||||
Building a dictionary containing two key-value pairs.
|
Building a dictionary containing two key-value pairs.
|
||||||
|
|
||||||
example_from_vector = Dictionary.from_vector [["A", 1], ["B", 2]]
|
example_from_vector = Dictionary.from_vector [["A", 1], ["B", 2]]
|
||||||
|
@vec key_value_widget
|
||||||
from_vector : Vector Any -> Boolean -> Dictionary ! Illegal_Argument
|
from_vector : Vector Any -> Boolean -> Dictionary ! Illegal_Argument
|
||||||
from_vector vec error_on_duplicates=True =
|
from_vector vec error_on_duplicates:Boolean=True =
|
||||||
vec.fold Dictionary.empty m-> el-> if el.length != 2 then Error.throw (Illegal_Argument.Error "`Dictionary.from_vector` encountered an invalid value. Each value in the vector has to be a key-value pair - it must have exactly 2 elements.") else
|
vec.fold Dictionary.empty m-> el-> if el.length != 2 then Error.throw (Illegal_Argument.Error "`Dictionary.from_vector` encountered an invalid value. Each value in the vector has to be a key-value pair - it must have exactly 2 elements.") else
|
||||||
key = el.at 0
|
key = el.at 0
|
||||||
value = el.at 1
|
value = el.at 1
|
||||||
@ -152,8 +161,11 @@ type Dictionary key value
|
|||||||
import Standard.Examples
|
import Standard.Examples
|
||||||
|
|
||||||
example_insert = Examples.dictionary.insert 7 "seven"
|
example_insert = Examples.dictionary.insert 7 "seven"
|
||||||
|
@key (make_all_selector ..Always)
|
||||||
|
@value (make_all_selector ..Always)
|
||||||
insert : Any -> Any -> Dictionary
|
insert : Any -> Any -> Dictionary
|
||||||
insert self key value = @Builtin_Method "Dictionary.insert"
|
insert self key=(Missing_Argument.throw "key") value=(Missing_Argument.throw "value") =
|
||||||
|
self.insert_builtin key value
|
||||||
|
|
||||||
## GROUP Selections
|
## GROUP Selections
|
||||||
ICON table_clean
|
ICON table_clean
|
||||||
@ -170,8 +182,9 @@ type Dictionary key value
|
|||||||
import Standard.Examples
|
import Standard.Examples
|
||||||
|
|
||||||
Examples.dictionary.remove "A"
|
Examples.dictionary.remove "A"
|
||||||
|
@key key_widget
|
||||||
remove : Any -> Dictionary ! No_Such_Key
|
remove : Any -> Dictionary ! No_Such_Key
|
||||||
remove self key =
|
remove self key=(Missing_Argument.throw "key") =
|
||||||
Panic.catch Any (self.remove_builtin key) _->
|
Panic.catch Any (self.remove_builtin key) _->
|
||||||
Error.throw (No_Such_Key.Error self key)
|
Error.throw (No_Such_Key.Error self key)
|
||||||
|
|
||||||
@ -191,6 +204,7 @@ type Dictionary key value
|
|||||||
import Standard.Examples
|
import Standard.Examples
|
||||||
|
|
||||||
example_at = Examples.dictionary.at "A"
|
example_at = Examples.dictionary.at "A"
|
||||||
|
@key key_widget
|
||||||
at : Any -> Any ! No_Such_Key
|
at : Any -> Any ! No_Such_Key
|
||||||
at self key = self.get key (Error.throw (No_Such_Key.Error self key))
|
at self key = self.get key (Error.throw (No_Such_Key.Error self key))
|
||||||
|
|
||||||
@ -211,12 +225,14 @@ type Dictionary key value
|
|||||||
import Standard.Examples
|
import Standard.Examples
|
||||||
|
|
||||||
example_get = Examples.dictionary.get 2 "zero"
|
example_get = Examples.dictionary.get 2 "zero"
|
||||||
|
@key key_widget
|
||||||
get : Any -> Any -> Any
|
get : Any -> Any -> Any
|
||||||
get self key ~if_missing=Nothing = self.get_builtin key if_missing
|
get self key ~if_missing=Nothing = self.get_builtin key if_missing
|
||||||
|
|
||||||
## GROUP Logical
|
## GROUP Logical
|
||||||
ICON preparation
|
ICON preparation
|
||||||
Returns True iff the Dictionary contains the given `key`.
|
Returns True iff the Dictionary contains the given `key`.
|
||||||
|
@key (make_all_selector ..Always)
|
||||||
contains_key : Any -> Boolean
|
contains_key : Any -> Boolean
|
||||||
contains_key self key = @Builtin_Method "Dictionary.contains_key"
|
contains_key self key = @Builtin_Method "Dictionary.contains_key"
|
||||||
|
|
||||||
@ -423,3 +439,19 @@ type Dictionary key value
|
|||||||
## PRIVATE
|
## PRIVATE
|
||||||
get_builtin : Any -> Any -> Any
|
get_builtin : Any -> Any -> Any
|
||||||
get_builtin self key ~if_missing = @Builtin_Method "Dictionary.get_builtin"
|
get_builtin self key ~if_missing = @Builtin_Method "Dictionary.get_builtin"
|
||||||
|
|
||||||
|
## PRIVATE
|
||||||
|
key_widget dict:Dictionary -> Widget =
|
||||||
|
values = dict.keys.map k-> Option k.to_text k.pretty
|
||||||
|
Single_Choice display=..Always values=values
|
||||||
|
|
||||||
|
## PRIVATE
|
||||||
|
key_value_widget -> Widget =
|
||||||
|
fqn = Meta.get_qualified_type_name Pair . drop (..Last 5)
|
||||||
|
default = 'pair "key" Nothing'
|
||||||
|
pair = Option "Pair" fqn+".pair" [["first", make_all_selector], ["second", make_all_selector]]
|
||||||
|
item_editor = Single_Choice display=..Always values=[pair]
|
||||||
|
Vector_Editor item_editor=item_editor display=..Always item_default=default
|
||||||
|
|
||||||
|
## PRIVATE
|
||||||
|
Dictionary.from (that:Vector) = Dictionary.from_vector that
|
||||||
|
@ -29,7 +29,8 @@ from project.Data.Ordering import all
|
|||||||
from project.Data.Range.Extensions import all
|
from project.Data.Range.Extensions import all
|
||||||
from project.Data.Text.Extensions import all
|
from project.Data.Text.Extensions import all
|
||||||
from project.Metadata.Choice import Option
|
from project.Metadata.Choice import Option
|
||||||
from project.Metadata.Widget import Single_Choice
|
from project.Metadata.Widget import Single_Choice, Text_Input, Vector_Editor
|
||||||
|
from project.Widget_Helpers import make_all_selector
|
||||||
|
|
||||||
polyglot java import com.fasterxml.jackson.core.JsonLocation
|
polyglot java import com.fasterxml.jackson.core.JsonLocation
|
||||||
polyglot java import com.fasterxml.jackson.core.JsonProcessingException
|
polyglot java import com.fasterxml.jackson.core.JsonProcessingException
|
||||||
@ -161,10 +162,11 @@ type JS_Object
|
|||||||
loop name_iterator builder
|
loop name_iterator builder
|
||||||
JS_Object.Value object_node (make_field_names object_node)
|
JS_Object.Value object_node (make_field_names object_node)
|
||||||
|
|
||||||
## PRIVATE
|
## ICON braces
|
||||||
Creates a Jackson_Object from a list of key-value pairs.
|
Creates a JS_Object from a list of key-value pairs.
|
||||||
Keys must be `Text` values.
|
Keys must be `Text` values.
|
||||||
Values will be recursively converted to JSON serializable as needed.
|
Values will be recursively converted to JSON serializable as needed.
|
||||||
|
@pairs key_value_widget
|
||||||
from_pairs : Vector -> JS_Object
|
from_pairs : Vector -> JS_Object
|
||||||
from_pairs pairs =
|
from_pairs pairs =
|
||||||
mapper = ObjectMapper.new
|
mapper = ObjectMapper.new
|
||||||
@ -348,7 +350,7 @@ type JS_Object
|
|||||||
## PRIVATE
|
## PRIVATE
|
||||||
Make a field name selector
|
Make a field name selector
|
||||||
make_field_name_selector : JS_Object -> Display -> Widget
|
make_field_name_selector : JS_Object -> Display -> Widget
|
||||||
make_field_name_selector js_object display=Display.Always =
|
make_field_name_selector js_object display:Display=..Always =
|
||||||
Single_Choice display=display values=(js_object.field_names.map n->(Option n n.pretty))
|
Single_Choice display=display values=(js_object.field_names.map n->(Option n n.pretty))
|
||||||
|
|
||||||
## PRIVATE
|
## PRIVATE
|
||||||
@ -423,3 +425,12 @@ make_enso object =
|
|||||||
_ -> js_object
|
_ -> js_object
|
||||||
|
|
||||||
if parsed.is_error then js_object else parsed
|
if parsed.is_error then js_object else parsed
|
||||||
|
|
||||||
|
## PRIVATE
|
||||||
|
key_value_widget : Widget
|
||||||
|
key_value_widget =
|
||||||
|
fqn = Meta.get_qualified_type_name Pair . drop (..Last 5)
|
||||||
|
default = 'pair "key" Nothing'
|
||||||
|
pair = Option "Pair" fqn+".pair" [["first", Text_Input], ["second", make_all_selector]]
|
||||||
|
item_editor = Single_Choice display=..Always values=[pair]
|
||||||
|
Vector_Editor item_editor=item_editor display=..Always item_default=default
|
||||||
|
@ -295,3 +295,12 @@ check_start_valid start function max=3 =
|
|||||||
used_start = if start < 0 then start + 2 else start
|
used_start = if start < 0 then start + 2 else start
|
||||||
if used_start < 0 || used_start >= max then Error.throw (Index_Out_Of_Bounds.Error start max) else
|
if used_start < 0 || used_start >= max then Error.throw (Index_Out_Of_Bounds.Error start max) else
|
||||||
function used_start
|
function used_start
|
||||||
|
|
||||||
|
## ICON array_new
|
||||||
|
Create a new Pair from two elements.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
- first: The first element.
|
||||||
|
- second: The second element.
|
||||||
|
pair : Any -> Any -> Pair
|
||||||
|
pair first second -> Pair = Pair.new first second
|
||||||
|
@ -826,6 +826,11 @@ type Date
|
|||||||
format self format:Date_Time_Formatter=Date_Time_Formatter.iso_date =
|
format self format:Date_Time_Formatter=Date_Time_Formatter.iso_date =
|
||||||
format.format_date self
|
format.format_date self
|
||||||
|
|
||||||
|
## PRIVATE
|
||||||
|
Convert to a Enso code representation of this Date.
|
||||||
|
pretty : Text
|
||||||
|
pretty self = "(Date.new " + self.year.to_text + " " + self.month.to_text + " " + self.day.to_text + ")"
|
||||||
|
|
||||||
## PRIVATE
|
## PRIVATE
|
||||||
week_days_between start end =
|
week_days_between start end =
|
||||||
## We split the interval into 3 periods: the first week (containing the
|
## We split the interval into 3 periods: the first week (containing the
|
||||||
|
@ -491,6 +491,18 @@ type Time_Of_Day
|
|||||||
format self format:Date_Time_Formatter =
|
format self format:Date_Time_Formatter =
|
||||||
format.format_time self
|
format.format_time self
|
||||||
|
|
||||||
|
## PRIVATE
|
||||||
|
Convert to a Enso code representation of this Time_Of_Day.
|
||||||
|
pretty : Text
|
||||||
|
pretty self = "(Time_Of_Day.new "
|
||||||
|
+ (if self.hour == 0 then "" else " hour="+self.hour.to_text)
|
||||||
|
+ (if self.minute == 0 then "" else " minute="+self.minute.to_text)
|
||||||
|
+ (if self.second == 0 then "" else " second="+self.second.to_text)
|
||||||
|
+ (if self.millisecond == 0 then "" else " millisecond="+self.millisecond.to_text)
|
||||||
|
+ (if self.microsecond == 0 then "" else " microsecond="+self.microsecond.to_text)
|
||||||
|
+ (if self.nanosecond == 0 then "" else " nanosecond="+self.nanosecond.to_text)
|
||||||
|
+ ")"
|
||||||
|
|
||||||
## PRIVATE
|
## PRIVATE
|
||||||
Time_Of_Day.from (that:JS_Object) =
|
Time_Of_Day.from (that:JS_Object) =
|
||||||
## Must have hour and minute but second and nanosecond are optional
|
## Must have hour and minute but second and nanosecond are optional
|
||||||
|
@ -211,7 +211,7 @@ type Enso_File
|
|||||||
value. The value is returned from this method.
|
value. The value is returned from this method.
|
||||||
with_output_stream : Vector File_Access -> (Output_Stream -> Any ! File_Error) -> Any ! File_Error
|
with_output_stream : Vector File_Access -> (Output_Stream -> Any ! File_Error) -> Any ! File_Error
|
||||||
with_output_stream self (open_options : Vector) action =
|
with_output_stream self (open_options : Vector) action =
|
||||||
Context.Output.if_enabled disabled_message="Writing to an Enso_File is forbidden as the Output context is disabled." panic=False <|
|
Context.Output.if_enabled disabled_message="As writing is disabled, cannot write to a file. Press the Write button ▶ to perform the operation." panic=False <|
|
||||||
is_data_link = Data_Link.is_data_link self
|
is_data_link = Data_Link.is_data_link self
|
||||||
open_as_data_link = (open_options.contains Data_Link_Access.No_Follow . not) && is_data_link
|
open_as_data_link = (open_options.contains Data_Link_Access.No_Follow . not) && is_data_link
|
||||||
if open_as_data_link then Data_Link_Helpers.write_data_link_as_stream self open_options action else
|
if open_as_data_link then Data_Link_Helpers.write_data_link_as_stream self open_options action else
|
||||||
|
@ -13,7 +13,6 @@ import project.Errors.Common.Not_Found
|
|||||||
import project.Errors.Illegal_Argument.Illegal_Argument
|
import project.Errors.Illegal_Argument.Illegal_Argument
|
||||||
import project.Network.HTTP.HTTP
|
import project.Network.HTTP.HTTP
|
||||||
import project.Network.HTTP.HTTP_Method.HTTP_Method
|
import project.Network.HTTP.HTTP_Method.HTTP_Method
|
||||||
import project.Network.HTTP.Request_Body.Request_Body
|
|
||||||
import project.Network.URI.URI
|
import project.Network.URI.URI
|
||||||
import project.Nothing.Nothing
|
import project.Nothing.Nothing
|
||||||
import project.Runtime.Context
|
import project.Runtime.Context
|
||||||
@ -45,7 +44,7 @@ type Enso_Secret
|
|||||||
created in the current working directory.
|
created in the current working directory.
|
||||||
create : Text -> Text -> Enso_File | Nothing -> Enso_Secret
|
create : Text -> Text -> Enso_File | Nothing -> Enso_Secret
|
||||||
create name:Text value:Text parent:(Enso_File | Nothing)=Nothing = if name == "" then Error.throw (Illegal_Argument.Error "Secret name cannot be empty") else
|
create name:Text value:Text parent:(Enso_File | Nothing)=Nothing = if name == "" then Error.throw (Illegal_Argument.Error "Secret name cannot be empty") else
|
||||||
Context.Output.if_enabled disabled_message="Creating a secret is forbidden as the Output context is disabled." panic=False <|
|
Context.Output.if_enabled disabled_message="As writing is disabled, cannot create a secret. Press the Write button ▶ to perform the operation." panic=False <|
|
||||||
if name.starts_with "connection-" then Error.throw (Illegal_Argument.Error "Secret name cannot start with 'connection-'") else
|
if name.starts_with "connection-" then Error.throw (Illegal_Argument.Error "Secret name cannot start with 'connection-'") else
|
||||||
parent_dir = parent.if_nothing Enso_File.current_working_directory
|
parent_dir = parent.if_nothing Enso_File.current_working_directory
|
||||||
path = if name.contains "/" then Error.throw (Illegal_Argument.Error "Secret name cannot contain `/`.") else parent_dir.enso_path.resolve name
|
path = if name.contains "/" then Error.throw (Illegal_Argument.Error "Secret name cannot contain `/`.") else parent_dir.enso_path.resolve name
|
||||||
@ -65,7 +64,7 @@ type Enso_Secret
|
|||||||
Deletes a secret.
|
Deletes a secret.
|
||||||
delete : Enso_Secret
|
delete : Enso_Secret
|
||||||
delete self =
|
delete self =
|
||||||
Context.Output.if_enabled disabled_message="Deleting a secret is forbidden as the Output context is disabled." panic=False <|
|
Context.Output.if_enabled disabled_message="As writing is disabled, cannot delete secret. Press the Write button ▶ to perform the operation." panic=False <|
|
||||||
uri = URI.from (secret_asset_uri self) . add_query_argument "force" "true"
|
uri = URI.from (secret_asset_uri self) . add_query_argument "force" "true"
|
||||||
response = Utils.http_request HTTP_Method.Delete uri
|
response = Utils.http_request HTTP_Method.Delete uri
|
||||||
response.if_not_error self
|
response.if_not_error self
|
||||||
@ -140,7 +139,7 @@ type Enso_Secret
|
|||||||
- new_value: The new value of the secret
|
- new_value: The new value of the secret
|
||||||
update_value : Text -> Enso_Secret
|
update_value : Text -> Enso_Secret
|
||||||
update_value self (new_value : Text) =
|
update_value self (new_value : Text) =
|
||||||
Context.Output.if_enabled disabled_message="Updating a secret is forbidden as the Output context is disabled." panic=False <|
|
Context.Output.if_enabled disabled_message="As writing is disabled, cannot update secret. Press the Write button ▶ to perform the operation." panic=False <|
|
||||||
body = JS_Object.from_pairs [["value", new_value]]
|
body = JS_Object.from_pairs [["value", new_value]]
|
||||||
response = Utils.http_request HTTP_Method.Put (secret_resource_uri self) body
|
response = Utils.http_request HTTP_Method.Put (secret_resource_uri self) body
|
||||||
response.if_not_error <|
|
response.if_not_error <|
|
||||||
|
@ -22,7 +22,7 @@ instance =
|
|||||||
## PRIVATE
|
## PRIVATE
|
||||||
create_dry_run_file file copy_original =
|
create_dry_run_file file copy_original =
|
||||||
_ = [file, copy_original]
|
_ = [file, copy_original]
|
||||||
Error.throw (Forbidden_Operation.Error "Currently dry-run is not supported for Enso_File, so writing to an Enso_File is forbidden if the Output context is disabled.")
|
Error.throw (Forbidden_Operation.Error "As writing is disabled, no action has been performed. Press the Write button ▶ to write the file.")
|
||||||
|
|
||||||
|
|
||||||
## PRIVATE
|
## PRIVATE
|
||||||
|
@ -72,7 +72,7 @@ flush_caches = CloudAPI.flushCloudCaches
|
|||||||
## PRIVATE
|
## PRIVATE
|
||||||
Performs a standard request to the Enso Cloud API,
|
Performs a standard request to the Enso Cloud API,
|
||||||
parsing the result as JSON.
|
parsing the result as JSON.
|
||||||
http_request_as_json (method : HTTP_Method) (url : URI) (body : Request_Body = Request_Body.Empty) (additional_headers : Vector = []) (error_handlers : Dictionary Text (Any -> Any) = Dictionary.empty) (retries : Integer = 3) -> Any ! Enso_Cloud_Error =
|
http_request_as_json (method : HTTP_Method) (url : URI) (body : Request_Body = ..Empty) (additional_headers : Vector = []) (error_handlers : Dictionary Text (Any -> Any) = Dictionary.empty) (retries : Integer = 3) -> Any ! Enso_Cloud_Error =
|
||||||
response = http_request method url body additional_headers error_handlers retries
|
response = http_request method url body additional_headers error_handlers retries
|
||||||
response.decode_as_json.catch Invalid_JSON error->
|
response.decode_as_json.catch Invalid_JSON error->
|
||||||
Error.throw (Enso_Cloud_Error.Invalid_Response_Payload error)
|
Error.throw (Enso_Cloud_Error.Invalid_Response_Payload error)
|
||||||
@ -87,7 +87,7 @@ http_request_as_json (method : HTTP_Method) (url : URI) (body : Request_Body = R
|
|||||||
Custom error handlers can be provided as a mapping from error codes
|
Custom error handlers can be provided as a mapping from error codes
|
||||||
(defined in the cloud project) to functions that take the full JSON payload
|
(defined in the cloud project) to functions that take the full JSON payload
|
||||||
and return a custom error.
|
and return a custom error.
|
||||||
http_request (method : HTTP_Method) (url : URI) (body : Request_Body = Request_Body.Empty) (additional_headers : Vector = []) (error_handlers : Dictionary Text (Any -> Any) = Dictionary.empty) (retries : Integer = 3) -> Response ! Enso_Cloud_Error = method.if_not_error <| url.if_not_error <| body.if_not_error <| additional_headers.if_not_error <|
|
http_request (method : HTTP_Method) (url : URI) (body : Request_Body = ..Empty) (additional_headers : Vector = []) (error_handlers : Dictionary Text (Any -> Any) = Dictionary.empty) (retries : Integer = 3) -> Response ! Enso_Cloud_Error = method.if_not_error <| url.if_not_error <| body.if_not_error <| additional_headers.if_not_error <|
|
||||||
all_headers = [authorization_header] + additional_headers
|
all_headers = [authorization_header] + additional_headers
|
||||||
as_connection_error err = Error.throw (Enso_Cloud_Error.Connection_Error err)
|
as_connection_error err = Error.throw (Enso_Cloud_Error.Connection_Error err)
|
||||||
|
|
||||||
|
@ -431,7 +431,7 @@ type Forbidden_Operation
|
|||||||
## PRIVATE
|
## PRIVATE
|
||||||
Convert the Forbidden_Operation error to a human-readable format.
|
Convert the Forbidden_Operation error to a human-readable format.
|
||||||
to_display_text : Text
|
to_display_text : Text
|
||||||
to_display_text self = "Forbidden operation: "+self.message
|
to_display_text self = self.message
|
||||||
|
|
||||||
type Dry_Run_Operation
|
type Dry_Run_Operation
|
||||||
## PRIVATE
|
## PRIVATE
|
||||||
|
@ -32,6 +32,7 @@ export project.Data.Numeric.Rounding_Mode.Rounding_Mode
|
|||||||
export project.Data.Ordering.Comparable
|
export project.Data.Ordering.Comparable
|
||||||
export project.Data.Ordering.Natural_Order
|
export project.Data.Ordering.Natural_Order
|
||||||
export project.Data.Ordering.Ordering
|
export project.Data.Ordering.Ordering
|
||||||
|
export project.Data.Pair.pair
|
||||||
export project.Data.Pair.Pair
|
export project.Data.Pair.Pair
|
||||||
export project.Data.Range.Extensions.down_to
|
export project.Data.Range.Extensions.down_to
|
||||||
export project.Data.Range.Extensions.up_to
|
export project.Data.Range.Extensions.up_to
|
||||||
|
@ -44,7 +44,7 @@ Text.to_uri self = URI.parse self
|
|||||||
cannot be determined automatically, a raw HTTP `Response` will be returned.
|
cannot be determined automatically, a raw HTTP `Response` will be returned.
|
||||||
@format Data_Read_Helpers.format_widget_with_raw_response
|
@format Data_Read_Helpers.format_widget_with_raw_response
|
||||||
URI.fetch : HTTP_Method -> Vector (Header | Pair Text Text) -> File_Format -> Any
|
URI.fetch : HTTP_Method -> Vector (Header | Pair Text Text) -> File_Format -> Any
|
||||||
URI.fetch self (method:HTTP_Method=HTTP_Method.Get) headers=[] format=Auto_Detect =
|
URI.fetch self (method:HTTP_Method=..Get) headers=[] format=Auto_Detect =
|
||||||
Data.fetch self method headers format
|
Data.fetch self method headers format
|
||||||
|
|
||||||
## ALIAS http post, upload
|
## ALIAS http post, upload
|
||||||
@ -85,7 +85,8 @@ URI.fetch self (method:HTTP_Method=HTTP_Method.Get) headers=[] format=Auto_Detec
|
|||||||
- Text: shorthand for `Request_Body.Text that_text`.
|
- Text: shorthand for `Request_Body.Text that_text`.
|
||||||
- File: shorthand for `Request_Body.Binary that_file`.
|
- File: shorthand for `Request_Body.Binary that_file`.
|
||||||
- Any other Enso object: shorthand for `Request_Body.Json that_object`.
|
- Any other Enso object: shorthand for `Request_Body.Json that_object`.
|
||||||
|
@headers Header.default_widget
|
||||||
@response_format Data_Read_Helpers.format_widget_with_raw_response
|
@response_format Data_Read_Helpers.format_widget_with_raw_response
|
||||||
URI.post : Request_Body -> HTTP_Method -> Vector (Header | Pair Text Text) -> File_Format -> Any
|
URI.post : Request_Body -> HTTP_Method -> Vector (Header | Pair Text Text) -> File_Format -> Any
|
||||||
URI.post self (body:Request_Body=Request_Body.Empty) (method:HTTP_Method=HTTP_Method.Post) (headers:(Vector (Header | Pair Text Text))=[]) (response_format = Auto_Detect) =
|
URI.post self (body:Request_Body=..Empty) (method:HTTP_Method=..Post) (headers:(Vector (Header | Pair Text Text))=[]) (response_format = Auto_Detect) =
|
||||||
Data.post self body method headers response_format
|
Data.post self body method headers response_format
|
||||||
|
@ -11,6 +11,7 @@ import project.Enso_Cloud.Enso_Secret.Enso_Secret
|
|||||||
import project.Error.Error
|
import project.Error.Error
|
||||||
import project.Errors.Common.Forbidden_Operation
|
import project.Errors.Common.Forbidden_Operation
|
||||||
import project.Errors.Illegal_Argument.Illegal_Argument
|
import project.Errors.Illegal_Argument.Illegal_Argument
|
||||||
|
import project.Function.Function
|
||||||
import project.Meta
|
import project.Meta
|
||||||
import project.Network.HTTP.Header.Header
|
import project.Network.HTTP.Header.Header
|
||||||
import project.Network.HTTP.HTTP_Error.HTTP_Error
|
import project.Network.HTTP.HTTP_Error.HTTP_Error
|
||||||
@ -106,7 +107,7 @@ type HTTP
|
|||||||
# Prevent request if the method is a write-like method and output context is disabled.
|
# Prevent request if the method is a write-like method and output context is disabled.
|
||||||
check_output_context ~action =
|
check_output_context ~action =
|
||||||
if fetch_methods.contains req.method || Context.Output.is_enabled then action else
|
if fetch_methods.contains req.method || Context.Output.is_enabled then action else
|
||||||
Error.throw (Forbidden_Operation.Error ("Method " + req.method.to_text + " requests are forbidden as the Output context is disabled."))
|
Error.throw (Forbidden_Operation.Error ("As writing is disabled, " + req.method.to_text + " request not sent. Press the Write button ▶ to send it."))
|
||||||
handle_request_error =
|
handle_request_error =
|
||||||
handler caught_panic =
|
handler caught_panic =
|
||||||
exception = caught_panic.payload
|
exception = caught_panic.payload
|
||||||
@ -137,7 +138,7 @@ type HTTP
|
|||||||
## PRIVATE
|
## PRIVATE
|
||||||
Static helper for get-like methods
|
Static helper for get-like methods
|
||||||
fetch : (URI | Text) -> HTTP_Method -> Vector (Header | Pair Text Text) -> Response ! Request_Error | HTTP_Error
|
fetch : (URI | Text) -> HTTP_Method -> Vector (Header | Pair Text Text) -> Response ! Request_Error | HTTP_Error
|
||||||
fetch (uri:(URI | Text)) (method:HTTP_Method=HTTP_Method.Get) (headers:(Vector (Header | Pair Text Text))=[]) =
|
fetch (uri:(URI | Text)) (method:HTTP_Method=..Get) (headers:(Vector (Header | Pair Text Text))=[]) =
|
||||||
check_method fetch_methods method <|
|
check_method fetch_methods method <|
|
||||||
request = Request.new method uri (parse_headers headers) Request_Body.Empty
|
request = Request.new method uri (parse_headers headers) Request_Body.Empty
|
||||||
HTTP.new.request request
|
HTTP.new.request request
|
||||||
@ -187,6 +188,7 @@ parse_headers headers =
|
|||||||
headers . map on_problems=No_Wrap h-> case h of
|
headers . map on_problems=No_Wrap h-> case h of
|
||||||
_ : Vector -> Header.new (h.at 0) (h.at 1)
|
_ : Vector -> Header.new (h.at 0) (h.at 1)
|
||||||
_ : Pair -> Header.new (h.at 0) (h.at 1)
|
_ : Pair -> Header.new (h.at 0) (h.at 1)
|
||||||
|
_ : Function -> h:Header
|
||||||
_ : Header -> h
|
_ : Header -> h
|
||||||
_ -> Error.throw (Illegal_Argument.Error "Invalid header type - all values must be Vector, Pair or Header (got "+(Meta.get_simple_type_name h)+").")
|
_ -> Error.throw (Illegal_Argument.Error "Invalid header type - all values must be Vector, Pair or Header (got "+(Meta.get_simple_type_name h)+").")
|
||||||
|
|
||||||
|
@ -3,11 +3,18 @@ import project.Data.Text.Encoding.Encoding
|
|||||||
import project.Data.Text.Text
|
import project.Data.Text.Text
|
||||||
import project.Enso_Cloud.Enso_Secret.Derived_Secret_Value
|
import project.Enso_Cloud.Enso_Secret.Derived_Secret_Value
|
||||||
import project.Enso_Cloud.Enso_Secret.Enso_Secret
|
import project.Enso_Cloud.Enso_Secret.Enso_Secret
|
||||||
|
import project.Meta
|
||||||
|
import project.Metadata.Display
|
||||||
|
import project.Metadata.Widget
|
||||||
import project.Nothing.Nothing
|
import project.Nothing.Nothing
|
||||||
from project.Data.Boolean import Boolean, False, True
|
from project.Data.Boolean import Boolean, False, True
|
||||||
from project.Data.Ordering import all
|
from project.Data.Ordering import all
|
||||||
from project.Data.Text.Extensions import all
|
from project.Data.Text.Extensions import all
|
||||||
from project.Enso_Cloud.Enso_Secret import as_hideable_value
|
from project.Enso_Cloud.Enso_Secret import as_hideable_value
|
||||||
|
from project.Metadata import make_single_choice
|
||||||
|
from project.Metadata.Choice import Option
|
||||||
|
from project.Metadata.Widget import Single_Choice, Vector_Editor
|
||||||
|
from project.Widget_Helpers import make_text_secret_selector
|
||||||
|
|
||||||
polyglot java import org.graalvm.collections.Pair as Java_Pair
|
polyglot java import org.graalvm.collections.Pair as Java_Pair
|
||||||
|
|
||||||
@ -213,6 +220,22 @@ type Header
|
|||||||
to_java_pair self =
|
to_java_pair self =
|
||||||
Java_Pair.create self.name (as_hideable_value self.value)
|
Java_Pair.create self.name (as_hideable_value self.value)
|
||||||
|
|
||||||
|
## PRIVATE
|
||||||
|
default_widget (display : Display = ..When_Modified) -> Widget =
|
||||||
|
fqn = "Header"
|
||||||
|
secret_selector = make_text_secret_selector
|
||||||
|
|
||||||
|
custom = [Option "Custom" fqn+".new '' ''"]
|
||||||
|
accept = [Option "Accept" fqn+".accept '*/*'"]
|
||||||
|
authorization = [Option "Authorization" fqn+".authorization ''" [["value", secret_selector]]]
|
||||||
|
basic_auth = [Option "HTTP Basic Auth" fqn+".authorization_basic '' ''" [["user", secret_selector], ["pass", secret_selector]]]
|
||||||
|
bearer_auth = [Option "Bearer Auth" fqn+".authorization_bearer ''" [["token", secret_selector]]]
|
||||||
|
content_type = [Option "Content-Type" fqn+".content_type ''" [["value", content_type_widget], ["encoding", Encoding.default_widget]]]
|
||||||
|
values = custom + accept + authorization + basic_auth + bearer_auth + content_type
|
||||||
|
|
||||||
|
item_editor = Single_Choice values=values display=..Always
|
||||||
|
Vector_Editor item_editor item_default='Header.new "header" "value"' display=display
|
||||||
|
|
||||||
## PRIVATE
|
## PRIVATE
|
||||||
type Header_Comparator
|
type Header_Comparator
|
||||||
## PRIVATE
|
## PRIVATE
|
||||||
@ -229,3 +252,7 @@ type Header_Comparator
|
|||||||
|
|
||||||
## PRIVATE
|
## PRIVATE
|
||||||
Comparable.from (that:Header) = Comparable.new that Header_Comparator
|
Comparable.from (that:Header) = Comparable.new that Header_Comparator
|
||||||
|
|
||||||
|
## PRIVATE
|
||||||
|
content_type_widget -> Widget =
|
||||||
|
make_single_choice [["Custom", "*"], "application/json", "application/octet-stream", "application/x-www-form-urlencoded", "multipart/form-data", "text/csv", "text/html", "text/plain", "text/xml"]
|
||||||
|
@ -34,7 +34,7 @@ type Request
|
|||||||
|
|
||||||
example_new = Request.new Method.Post (URI.parse "http://example.com")
|
example_new = Request.new Method.Post (URI.parse "http://example.com")
|
||||||
new : HTTP_Method -> URI -> Vector Header -> Request_Body -> Request
|
new : HTTP_Method -> URI -> Vector Header -> Request_Body -> Request
|
||||||
new (method:HTTP_Method) (url:URI) (headers:(Vector Header)=[]) (body:Request_Body=Request_Body.Empty) =
|
new (method:HTTP_Method) (url:URI) (headers:(Vector Header)=[]) (body:Request_Body=..Empty) =
|
||||||
Request.Value method url headers body
|
Request.Value method url headers body
|
||||||
|
|
||||||
## ICON find
|
## ICON find
|
||||||
|
@ -1,11 +1,21 @@
|
|||||||
import project.Any.Any
|
import project.Any.Any
|
||||||
import project.Data.Dictionary.Dictionary
|
import project.Data.Dictionary.Dictionary
|
||||||
|
import project.Data.Pair.Pair
|
||||||
import project.Data.Text.Encoding.Encoding
|
import project.Data.Text.Encoding.Encoding
|
||||||
import project.Data.Text.Text
|
import project.Data.Text.Text
|
||||||
|
import project.Errors.Common.Missing_Argument
|
||||||
|
import project.Meta
|
||||||
|
import project.Metadata.Widget
|
||||||
import project.Network.HTTP.Header.Header
|
import project.Network.HTTP.Header.Header
|
||||||
import project.Nothing.Nothing
|
import project.Nothing.Nothing
|
||||||
import project.System.File.File
|
import project.System.File.File
|
||||||
from project.Data.Boolean import Boolean, False, True
|
from project.Data.Boolean import Boolean, False, True
|
||||||
|
from project.Data.Json import key_value_widget
|
||||||
|
from project.Data.Text.Extensions import all
|
||||||
|
from project.Metadata.Choice import Option
|
||||||
|
from project.Metadata.Widget import File_Browse, Single_Choice, Text_Input, Vector_Editor
|
||||||
|
from project.Network.HTTP.Header import content_type_widget
|
||||||
|
from project.Widget_Helpers import make_all_selector
|
||||||
|
|
||||||
## The HTTP POST request body.
|
## The HTTP POST request body.
|
||||||
type Request_Body
|
type Request_Body
|
||||||
@ -16,19 +26,22 @@ type Request_Body
|
|||||||
- text: The plain text in the request body.
|
- text: The plain text in the request body.
|
||||||
- encoding: the text encoding to send as a Content-Encoding header
|
- encoding: the text encoding to send as a Content-Encoding header
|
||||||
- content_type: the content_type to send as a Content-Type header
|
- content_type: the content_type to send as a Content-Type header
|
||||||
Text (text:Text) (encoding:(Encoding|Nothing)=Nothing) (content_type:(Text|Nothing)=Nothing)
|
@encoding Encoding.default_widget
|
||||||
|
@content_type content_type_widget
|
||||||
|
Text (text:Text="") (encoding:(Encoding|Nothing)=Nothing) (content_type:(Text|Nothing)=Nothing)
|
||||||
|
|
||||||
## Request body with an object to be sent as JSON.
|
## Request body with an object to be sent as JSON.
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
- x: The object to convert to JSON using `.to_json`.
|
- x: The object to convert to JSON using `.to_json`.
|
||||||
Json (x:Any)
|
@x make_all_with_json
|
||||||
|
Json (x:Any=(Missing_Argument.throw "x"))
|
||||||
|
|
||||||
## Request body with an object to be sent as a binary file.
|
## Request body with an object to be sent as a binary file.
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
- file: The file to send.
|
- file: The file to send.
|
||||||
Binary (file:File)
|
Binary (file:File=(Missing_Argument.throw "file"))
|
||||||
|
|
||||||
## Request body with form data.
|
## Request body with form data.
|
||||||
|
|
||||||
@ -36,7 +49,8 @@ type Request_Body
|
|||||||
- form_data: the form fields (text or file) to be sent
|
- form_data: the form fields (text or file) to be sent
|
||||||
- url_encoded: if true, use a URL-encoded form; otherwise, use a
|
- url_encoded: if true, use a URL-encoded form; otherwise, use a
|
||||||
multi-part encoding.
|
multi-part encoding.
|
||||||
Form_Data (form_data:(Dictionary Text (Text | File))) (url_encoded:Boolean=False)
|
@form_data dictionary_widget
|
||||||
|
Form_Data (form_data:Dictionary=(Missing_Argument.throw "form_data")) (url_encoded:Boolean=False)
|
||||||
|
|
||||||
## Empty request body; used for GET
|
## Empty request body; used for GET
|
||||||
Empty
|
Empty
|
||||||
@ -61,3 +75,18 @@ Request_Body.from (that:File) = Request_Body.Binary that
|
|||||||
|
|
||||||
## PRIVATE
|
## PRIVATE
|
||||||
Request_Body.from (that:Any) = Request_Body.Json that
|
Request_Body.from (that:Any) = Request_Body.Json that
|
||||||
|
|
||||||
|
## PRIVATE
|
||||||
|
make_all_with_json =
|
||||||
|
base_selector = make_all_selector Request_Body
|
||||||
|
values = [Option "JSON Object" key_value_widget] + base_selector.values
|
||||||
|
Single_Choice display=..Always values=values
|
||||||
|
|
||||||
|
## PRIVATE
|
||||||
|
dictionary_widget -> Widget =
|
||||||
|
fqn = Meta.get_qualified_type_name Pair . drop (..Last 5)
|
||||||
|
default = 'pair "key" ""'
|
||||||
|
value_editor = Single_Choice display=..Always values=[Option "Text" '""', Option "File" "File.new ''"]
|
||||||
|
pair = Option "Pair" fqn+".pair" [["first", Text_Input], ["second", value_editor]]
|
||||||
|
item_editor = Single_Choice display=..Always values=[pair]
|
||||||
|
Vector_Editor item_editor=item_editor display=..Always item_default=default
|
||||||
|
@ -195,7 +195,7 @@ type File
|
|||||||
_ -> stream
|
_ -> stream
|
||||||
Output_Stream.new wrapped (File_Error.handle_java_exceptions self)
|
Output_Stream.new wrapped (File_Error.handle_java_exceptions self)
|
||||||
|
|
||||||
Context.Output.if_enabled disabled_message="File writing is forbidden as the Output context is disabled." panic=False <|
|
Context.Output.if_enabled disabled_message="As writing is disabled, cannot write to a file. Press the Write button ▶ to perform the operation." panic=False <|
|
||||||
open_as_data_link = (open_options.contains Data_Link_Access.No_Follow . not) && (Data_Link.is_data_link self)
|
open_as_data_link = (open_options.contains Data_Link_Access.No_Follow . not) && (Data_Link.is_data_link self)
|
||||||
if open_as_data_link then Data_Link_Helpers.write_data_link_as_stream self open_options action else
|
if open_as_data_link then Data_Link_Helpers.write_data_link_as_stream self open_options action else
|
||||||
# We ignore the Data_Link_Access options at this stage:
|
# We ignore the Data_Link_Access options at this stage:
|
||||||
@ -515,7 +515,7 @@ type File
|
|||||||
(Examples.data_dir / "my_directory") . create_directory
|
(Examples.data_dir / "my_directory") . create_directory
|
||||||
create_directory : File ! File_Error
|
create_directory : File ! File_Error
|
||||||
create_directory self =
|
create_directory self =
|
||||||
Context.Output.if_enabled disabled_message="Directory creation is forbidden as the Output context is disabled." panic=False <|
|
Context.Output.if_enabled disabled_message="As writing is disabled, cannot create directory. Press the Write button ▶ to perform the operation." panic=False <|
|
||||||
File_Error.handle_java_exceptions self self.create_directory_builtin . if_not_error self
|
File_Error.handle_java_exceptions self self.create_directory_builtin . if_not_error self
|
||||||
|
|
||||||
## PRIVATE
|
## PRIVATE
|
||||||
@ -665,7 +665,7 @@ type File
|
|||||||
file.delete
|
file.delete
|
||||||
delete : Boolean -> Nothing ! File_Error
|
delete : Boolean -> Nothing ! File_Error
|
||||||
delete self (recursive : Boolean = False) -> Nothing ! File_Error =
|
delete self (recursive : Boolean = False) -> Nothing ! File_Error =
|
||||||
Context.Output.if_enabled disabled_message="File deleting is forbidden as the Output context is disabled." panic=False <|
|
Context.Output.if_enabled disabled_message="As writing is disabled, cannot delete file. Press the Write button ▶ to perform the operation." panic=False <|
|
||||||
File_Error.handle_java_exceptions self (self.delete_builtin recursive)
|
File_Error.handle_java_exceptions self (self.delete_builtin recursive)
|
||||||
|
|
||||||
## ICON data_output
|
## ICON data_output
|
||||||
@ -677,7 +677,7 @@ type File
|
|||||||
destination file already exists. Defaults to `False`.
|
destination file already exists. Defaults to `False`.
|
||||||
copy_to : File_Like -> Boolean -> Any ! File_Error
|
copy_to : File_Like -> Boolean -> Any ! File_Error
|
||||||
copy_to self (destination : File_Like) (replace_existing : Boolean = False) = Data_Link_Helpers.disallow_links_in_copy self destination <|
|
copy_to self (destination : File_Like) (replace_existing : Boolean = False) = Data_Link_Helpers.disallow_links_in_copy self destination <|
|
||||||
Context.Output.if_enabled disabled_message="File copying is forbidden as the Output context is disabled." panic=False <|
|
Context.Output.if_enabled disabled_message="As writing is disabled, cannot copy file. Press the Write button ▶ to perform the operation." panic=False <|
|
||||||
## We defer the `Writable_File` conversion after the 'disallow links' check,
|
## We defer the `Writable_File` conversion after the 'disallow links' check,
|
||||||
because the conversion would already start resolving the data link too soon.
|
because the conversion would already start resolving the data link too soon.
|
||||||
destination_writable = Writable_File.from destination
|
destination_writable = Writable_File.from destination
|
||||||
@ -695,7 +695,7 @@ type File
|
|||||||
destination file already exists. Defaults to `False`.
|
destination file already exists. Defaults to `False`.
|
||||||
move_to : File_Like -> Boolean -> Any ! File_Error
|
move_to : File_Like -> Boolean -> Any ! File_Error
|
||||||
move_to self (destination : File_Like) (replace_existing : Boolean = False) = Data_Link_Helpers.disallow_links_in_move self destination <|
|
move_to self (destination : File_Like) (replace_existing : Boolean = False) = Data_Link_Helpers.disallow_links_in_move self destination <|
|
||||||
Context.Output.if_enabled disabled_message="File moving is forbidden as the Output context is disabled." panic=False <|
|
Context.Output.if_enabled disabled_message="As writing is disabled, cannot move file. Press the Write button ▶ to perform the operation." panic=False <|
|
||||||
## We defer the `Writable_File` conversion after the 'disallow links' check,
|
## We defer the `Writable_File` conversion after the 'disallow links' check,
|
||||||
because the conversion would already start resolving the data link too soon.
|
because the conversion would already start resolving the data link too soon.
|
||||||
destination_writable = Writable_File.from destination
|
destination_writable = Writable_File.from destination
|
||||||
|
@ -131,6 +131,12 @@ make_data_cleanse_vector_selector display:Display=Display.Always =
|
|||||||
options = patterns.map f-> Option f (".." + f)
|
options = patterns.map f-> Option f (".." + f)
|
||||||
Widget.Multiple_Choice values=options display=display
|
Widget.Multiple_Choice values=options display=display
|
||||||
|
|
||||||
|
## PRIVATE
|
||||||
|
Creates a Single_Choice Widget for Any selectors with all types enabled.
|
||||||
|
make_all_selector : Display -> Widget
|
||||||
|
make_all_selector display:Display=..Always -> Widget =
|
||||||
|
make_any_selector display add_text=True add_number=True add_boolean=True add_date=True add_time=True add_date_time=True add_nothing=True
|
||||||
|
|
||||||
## PRIVATE
|
## PRIVATE
|
||||||
Creates a Single_Choice Widget for Any selectors.
|
Creates a Single_Choice Widget for Any selectors.
|
||||||
make_any_selector : Display -> Boolean -> Boolean -> Boolean -> Boolean -> Boolean -> Boolean -> Boolean -> Boolean -> Boolean -> Widget
|
make_any_selector : Display -> Boolean -> Boolean -> Boolean -> Boolean -> Boolean -> Boolean -> Boolean -> Boolean -> Boolean -> Widget
|
||||||
|
@ -360,7 +360,7 @@ type Connection
|
|||||||
representing the query to execute.
|
representing the query to execute.
|
||||||
execute_update : Text | SQL_Statement -> Integer
|
execute_update : Text | SQL_Statement -> Integer
|
||||||
execute_update self query =
|
execute_update self query =
|
||||||
Execution_Context.Output.if_enabled disabled_message="Executing update queries is forbidden as the Output context is disabled." panic=False <|
|
Execution_Context.Output.if_enabled disabled_message="As writing is disabled, cannot execute an update query. Press the Write button ▶ to perform the operation." panic=False <|
|
||||||
statement_setter = self.dialect.get_statement_setter
|
statement_setter = self.dialect.get_statement_setter
|
||||||
self.jdbc_connection.with_prepared_statement query statement_setter stmt->
|
self.jdbc_connection.with_prepared_statement query statement_setter stmt->
|
||||||
check_statement_is_allowed self stmt
|
check_statement_is_allowed self stmt
|
||||||
@ -384,7 +384,7 @@ type Connection
|
|||||||
representing the query to execute.
|
representing the query to execute.
|
||||||
execute : Text | SQL_Statement -> Integer
|
execute : Text | SQL_Statement -> Integer
|
||||||
execute self query =
|
execute self query =
|
||||||
Execution_Context.Output.if_enabled disabled_message="Executing update queries is forbidden as the Output context is disabled." panic=False <|
|
Execution_Context.Output.if_enabled disabled_message="As writing is disabled, cannot execute an update query. Press the Write button ▶ to perform the operation." panic=False <|
|
||||||
result = self.jdbc_connection.execute query
|
result = self.jdbc_connection.execute query
|
||||||
stmt = result.second
|
stmt = result.second
|
||||||
check_statement_is_allowed self stmt
|
check_statement_is_allowed self stmt
|
||||||
|
@ -21,7 +21,7 @@ type Postgres_Data_Link_Setup
|
|||||||
|
|
||||||
## PRIVATE
|
## PRIVATE
|
||||||
save_as_data_link self destination on_existing_file:Existing_File_Behavior = case self of
|
save_as_data_link self destination on_existing_file:Existing_File_Behavior = case self of
|
||||||
Postgres_Data_Link_Setup.Available details -> Context.Output.if_enabled disabled_message="Saving a connection to data link requires the Output context." panic=False <|
|
Postgres_Data_Link_Setup.Available details -> Context.Output.if_enabled disabled_message="As writing is disabled, cannot save to a Data Link. Press the Write button ▶ to perform the operation." panic=False <|
|
||||||
case destination of
|
case destination of
|
||||||
_ : Enso_File ->
|
_ : Enso_File ->
|
||||||
replace_existing = case on_existing_file of
|
replace_existing = case on_existing_file of
|
||||||
|
@ -101,7 +101,7 @@ type Image
|
|||||||
@path (Widget.Text_Input display=Display.Always)
|
@path (Widget.Text_Input display=Display.Always)
|
||||||
write : Writable_File -> (Write_Flag | Vector) -> Nothing ! File_Error
|
write : Writable_File -> (Write_Flag | Vector) -> Nothing ! File_Error
|
||||||
write self path:Writable_File flags=[] =
|
write self path:Writable_File flags=[] =
|
||||||
Context.Output.if_enabled disabled_message="Writing the image to a file is forbidden as the Output context is disabled." panic=False <|
|
Context.Output.if_enabled disabled_message="As writing is disabled, cannot write to a file. Press the Write button ▶ to perform the operation." panic=False <|
|
||||||
write_flags = case flags of
|
write_flags = case flags of
|
||||||
_ : Vector -> flags
|
_ : Vector -> flags
|
||||||
_ -> [flags]
|
_ -> [flags]
|
||||||
|
@ -188,7 +188,7 @@ class RuntimeExecutionEnvironmentTest
|
|||||||
IF_ENABLED_METH_CALL,
|
IF_ENABLED_METH_CALL,
|
||||||
Api.ExpressionUpdate.Payload
|
Api.ExpressionUpdate.Payload
|
||||||
.Panic(
|
.Panic(
|
||||||
"Forbidden operation: The Output context is disabled.",
|
"The Output context is disabled.",
|
||||||
Seq(idRes)
|
Seq(idRes)
|
||||||
),
|
),
|
||||||
false
|
false
|
||||||
@ -292,7 +292,7 @@ class RuntimeExecutionEnvironmentTest
|
|||||||
IF_ENABLED_METH_CALL,
|
IF_ENABLED_METH_CALL,
|
||||||
Api.ExpressionUpdate.Payload
|
Api.ExpressionUpdate.Payload
|
||||||
.Panic(
|
.Panic(
|
||||||
"Forbidden operation: The Input context is disabled.",
|
"The Input context is disabled.",
|
||||||
Seq(idRes)
|
Seq(idRes)
|
||||||
),
|
),
|
||||||
false
|
false
|
||||||
|
@ -20,12 +20,11 @@ import org.enso.interpreter.runtime.error.PanicException;
|
|||||||
|
|
||||||
@BuiltinMethod(
|
@BuiltinMethod(
|
||||||
type = "Dictionary",
|
type = "Dictionary",
|
||||||
name = "insert",
|
name = "insert_builtin",
|
||||||
description =
|
description =
|
||||||
"""
|
"""
|
||||||
Returns newly created hash map with the given key value mapping.
|
Returns newly created hash map with the given key value mapping.
|
||||||
""",
|
""")
|
||||||
autoRegister = false)
|
|
||||||
@GenerateUncached
|
@GenerateUncached
|
||||||
public abstract class HashMapInsertNode extends Node {
|
public abstract class HashMapInsertNode extends Node {
|
||||||
|
|
||||||
|
@ -84,7 +84,7 @@ type Arity_Error
|
|||||||
type Forbidden_Operation
|
type Forbidden_Operation
|
||||||
Error message
|
Error message
|
||||||
|
|
||||||
to_display_text self = "Forbidden operation: "+self.message
|
to_display_text self = self.message
|
||||||
|
|
||||||
## PRIVATE
|
## PRIVATE
|
||||||
A helper that replaces complicated `Text.replace` from main distribution, used for simple error message formatting.
|
A helper that replaces complicated `Text.replace` from main distribution, used for simple error message formatting.
|
||||||
|
Loading…
Reference in New Issue
Block a user