@plowtech/rescript-fetch 0.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/Fetch.resi ADDED
@@ -0,0 +1,337 @@
1
+ type body
2
+ type bodyInit
3
+ type headers
4
+ type headersInit
5
+ type response
6
+ type request
7
+ type requestInit
8
+
9
+ // external
10
+ type arrayBuffer /* TypedArray */
11
+ type blob /* FileAPI */
12
+ type bufferSource /* Web IDL, either an arrayBuffer or arrayBufferView */
13
+ type formData /* XMLHttpRequest */
14
+ type readableStream /* Streams */
15
+ type urlSearchParams /* URL */
16
+ type abortController
17
+ type signal
18
+
19
+ type requestMethod =
20
+ | Get
21
+ | Head
22
+ | Post
23
+ | Put
24
+ | Delete
25
+ | Connect
26
+ | Options
27
+ | Trace
28
+ | Patch
29
+ | Other(string)
30
+
31
+ module AbortController: {
32
+ /* Experimental API */
33
+ type t = abortController
34
+
35
+ /* Experimental API */
36
+ @get
37
+ external signal: t => signal = "signal"
38
+
39
+ /* Experimental API */
40
+ @send
41
+ external abort: t => unit = "abort"
42
+
43
+ /* Experimental API */
44
+ @new
45
+ external make: unit => t = "AbortController"
46
+ }
47
+
48
+ type referrerPolicy =
49
+ | None
50
+ | NoReferrer
51
+ | NoReferrerWhenDowngrade
52
+ | SameOrigin
53
+ | Origin
54
+ | StrictOrigin
55
+ | OriginWhenCrossOrigin
56
+ | StrictOriginWhenCrossOrigin
57
+ | UnsafeUrl
58
+
59
+ type requestType =
60
+ | None /* default? unknown? just empty string in spec */
61
+ | Audio
62
+ | Font
63
+ | Image
64
+ | Script
65
+ | Style
66
+ | Track
67
+ | Video
68
+
69
+ type requestDestination =
70
+ | None /* default? unknown? just empty string in spec */
71
+ | Document
72
+ | Embed
73
+ | Font
74
+ | Image
75
+ | Manifest
76
+ | Media
77
+ | Object
78
+ | Report
79
+ | Script
80
+ | ServiceWorker
81
+ | SharedWorker
82
+ | Style
83
+ | Worker
84
+ | Xslt
85
+
86
+ type requestMode =
87
+ | Navigate
88
+ | SameOrigin
89
+ | NoCORS
90
+ | CORS
91
+
92
+ type requestCredentials =
93
+ | Omit
94
+ | SameOrigin
95
+ | Include
96
+
97
+ type requestCache =
98
+ | Default
99
+ | NoStore
100
+ | Reload
101
+ | NoCache
102
+ | ForceCache
103
+ | OnlyIfCached
104
+
105
+ type requestRedirect =
106
+ | Follow
107
+ | Error
108
+ | Manual
109
+
110
+ module HeadersInit: {
111
+ type t = headersInit
112
+
113
+ external make: Js.t<{..}> => t = "%identity"
114
+ external makeWithDict: Js.Dict.t<string> => t = "%identity"
115
+ external makeWithArray: array<(string, string)> => t = "%identity"
116
+ }
117
+
118
+ module Headers: {
119
+ type t = headers
120
+
121
+ @new
122
+ external make: t = "Headers"
123
+
124
+ @new
125
+ external makeWithInit: headersInit => t = "Headers"
126
+
127
+ @send
128
+ external append: (t, string, string) => unit = "append"
129
+
130
+ @send
131
+ external delete: (t, string) => unit = "delete"
132
+
133
+ @send @return(nullable)
134
+ external get: (t, string) => option<string> = "get"
135
+
136
+ @send
137
+ external has: (t, string) => bool = "has"
138
+
139
+ @send
140
+ external set: (t, string, string) => unit = "set"
141
+ }
142
+
143
+ module BodyInit: {
144
+ type t = bodyInit
145
+
146
+ external make: string => t = "%identity"
147
+ external makeWithBlob: blob => t = "%identity"
148
+ external makeWithBufferSource: bufferSource => t = "%identity"
149
+ external makeWithFormData: formData => t = "%identity"
150
+ external makeWithUrlSearchParams: urlSearchParams => t = "%identity"
151
+ }
152
+
153
+ module Body: {
154
+ type t = body
155
+
156
+ @get
157
+ external body: t => readableStream = "body"
158
+
159
+ @get
160
+ external bodyUsed: t => bool = "bodyUsed"
161
+
162
+ @send
163
+ external arrayBuffer: t => Js.Promise.t<arrayBuffer> = "arrayBuffer"
164
+
165
+ @send
166
+ external blob: t => Js.Promise.t<blob> = "blob"
167
+
168
+ @send
169
+ external formData: t => Js.Promise.t<formData> = "formData"
170
+
171
+ @send
172
+ external json: t => Js.Promise.t<Js.Json.t> = "json"
173
+
174
+ @send
175
+ external text: t => Js.Promise.t<string> = "text"
176
+ }
177
+
178
+ module RequestInit: {
179
+ type t = requestInit
180
+
181
+ let make: (
182
+ ~method_: requestMethod=?,
183
+ ~headers: headersInit=?,
184
+ ~body: bodyInit=?,
185
+ ~referrer: string=?,
186
+ ~referrerPolicy: referrerPolicy=?,
187
+ ~mode: requestMode=?,
188
+ ~credentials: requestCredentials=?,
189
+ ~cache: requestCache=?,
190
+ ~redirect: requestRedirect=?,
191
+ ~integrity: string=?,
192
+ ~keepalive: bool=?,
193
+ ~signal: signal=?,
194
+ unit,
195
+ ) => t
196
+ }
197
+
198
+ module Request: {
199
+ type t = request
200
+
201
+ @new
202
+ external make: string => t = "Request"
203
+ @new
204
+ external makeWithInit: (string, requestInit) => t = "Request"
205
+ @new
206
+ external makeWithRequest: t => t = "Request"
207
+ @new
208
+ external makeWithRequestInit: (t, requestInit) => t = "Request"
209
+
210
+ let method_: t => requestMethod
211
+
212
+ @get
213
+ external url: t => string = "url"
214
+
215
+ @get
216
+ external headers: t => headers = "headers"
217
+
218
+ let type_: t => requestType
219
+
220
+ let destination: t => requestDestination
221
+
222
+ @get
223
+ external referrer: t => string = "referrer"
224
+
225
+ let referrerPolicy: t => referrerPolicy
226
+
227
+ let mode: t => requestMode
228
+
229
+ let credentials: t => requestCredentials
230
+
231
+ let cache: t => requestCache
232
+
233
+ let redirect: t => requestRedirect
234
+
235
+ @get
236
+ external integrity: t => string = "integrity"
237
+
238
+ @get
239
+ external keepalive: t => bool = "keepalive"
240
+
241
+ @get
242
+ external signal: t => signal = "signal"
243
+
244
+ /* Body Impl */
245
+ @get
246
+ external body: t => readableStream = "body"
247
+
248
+ @get
249
+ external bodyUsed: t => bool = "bodyUsed"
250
+
251
+ @send
252
+ external arrayBuffer: t => Js.Promise.t<arrayBuffer> = "arrayBuffer"
253
+
254
+ @send
255
+ external blob: t => Js.Promise.t<blob> = "blob"
256
+
257
+ @send
258
+ external formData: t => Js.Promise.t<formData> = "formData"
259
+
260
+ @send
261
+ external json: t => Js.Promise.t<Js.Json.t> = "json"
262
+
263
+ @send
264
+ external text: t => Js.Promise.t<string> = "text"
265
+ }
266
+
267
+ module Response: {
268
+ type t = response
269
+
270
+ @val
271
+ external error: unit => t = "error"
272
+
273
+ @val
274
+ external redirect: string => t = "redirect"
275
+
276
+ @val
277
+ external redirectWithStatus: (string, int) => t = "redirect"
278
+
279
+ @get
280
+ external headers: t => headers = "headers"
281
+
282
+ @get
283
+ external ok: t => bool = "ok"
284
+
285
+ @get
286
+ external redirected: t => bool = "redirected"
287
+
288
+ @get
289
+ external status: t => int = "status"
290
+
291
+ @get
292
+ external statusText: t => string = "statusText"
293
+
294
+ @get
295
+ external _type: t => string = "_type"
296
+
297
+ @get
298
+ external url: t => string = "url"
299
+
300
+ @send
301
+ external clone: t => t = "clone"
302
+
303
+ /* Body.Impl */
304
+
305
+ @get
306
+ external body: t => readableStream = "body"
307
+
308
+ @get
309
+ external bodyUsed: t => bool = "bodyUsed"
310
+
311
+ @send
312
+ external arrayBuffer: t => Js.Promise.t<arrayBuffer> = "arrayBuffer"
313
+
314
+ @send
315
+ external blob: t => Js.Promise.t<blob> = "blob"
316
+
317
+ @send
318
+ external formData: t => Js.Promise.t<formData> = "formData"
319
+
320
+ @send
321
+ external json: t => Js.Promise.t<Js.Json.t> = "json"
322
+
323
+ @send
324
+ external text: t => Js.Promise.t<string> = "text"
325
+ }
326
+
327
+ @val
328
+ external fetch: string => Js.Promise.t<response> = "fetch"
329
+
330
+ @val
331
+ external fetchWithInit: (string, requestInit) => Js.Promise.t<response> = "fetch"
332
+
333
+ @val
334
+ external fetchWithRequest: request => Js.Promise.t<response> = "fetch"
335
+
336
+ @val
337
+ external fetchWithRequestInit: (request, requestInit) => Js.Promise.t<response> = "fetch"
@@ -0,0 +1,155 @@
1
+ open ReactTest
2
+
3
+ let placeholderText = `{"userId":1,"id":1,"title":"delectus aut autem","completed":false}`
4
+ let postPlaceholderText = `{"title":"foo","body":"bar","userId":1,"id":101}`
5
+
6
+ module Hooks = {
7
+ let useFetch = () => {
8
+ let (state, setState) = React.useState(() => None)
9
+
10
+ React.useEffect0(() => {
11
+ let promise = async () => {
12
+ let response = await Fetch.fetch("https://jsonplaceholder.typicode.com/todos/1")
13
+ let body = await response->Fetch.Response.json
14
+
15
+ setState(_ => Some(body))
16
+ }
17
+
18
+ promise()->Promise.thenResolve(_ => ())->ignore
19
+
20
+ None
21
+ })
22
+
23
+ state
24
+ }
25
+
26
+ let useFetchWithInit = () => {
27
+ let (state, setState) = React.useState(() => None)
28
+
29
+ React.useEffect0(() => {
30
+ let promise = async () => {
31
+ let response = await Fetch.fetchWithInit(
32
+ "https://jsonplaceholder.typicode.com/todos/1",
33
+ Fetch.RequestInit.make(~method_=Get, ()),
34
+ )
35
+ let body = await response->Fetch.Response.json
36
+
37
+ setState(_ => Some(body))
38
+ }
39
+
40
+ promise()->Promise.thenResolve(_ => ())->ignore
41
+
42
+ None
43
+ })
44
+
45
+ state
46
+ }
47
+
48
+ let usePostFetchWithInit = () => {
49
+ let postBody = {
50
+ "title": "foo",
51
+ "body": "bar",
52
+ "userId": 1,
53
+ }
54
+ let (state, setState) = React.useState(() => None)
55
+
56
+ React.useEffect0(() => {
57
+ let promise = async () => {
58
+ let body = Fetch.BodyInit.make(JSON.stringifyAny(postBody)->Option.getOr(""))
59
+ let headers = Fetch.HeadersInit.makeWithArray([
60
+ ("Accept", "application/json"),
61
+ ("Content-Type", "application/json"),
62
+ ])
63
+ let response = await Fetch.fetchWithInit(
64
+ "https://jsonplaceholder.typicode.com/posts",
65
+ Fetch.RequestInit.make(~method_=Post, ~headers, ~body, ()),
66
+ )
67
+ let body = await response->Fetch.Response.json
68
+
69
+ setState(_ => Some(body))
70
+ }
71
+
72
+ promise()->Promise.thenResolve(_ => ())->ignore
73
+
74
+ None
75
+ })
76
+
77
+ state
78
+ }
79
+ }
80
+
81
+ module Home = {
82
+ @react.component
83
+ let make = (~fetchHok: unit => option<JSON.t>) => {
84
+ let jsonPlaceholder = fetchHok()
85
+
86
+ <div id="placeholder">
87
+ {React.string(jsonPlaceholder->Option.mapOr("Loading...", JSON.stringify(_)))}
88
+ </div>
89
+ }
90
+ }
91
+
92
+ @get external textContent: Dom.element => string = "textContent"
93
+
94
+ testAsyncWithReact("fetch", (root, done) => {
95
+ let promise = async () => {
96
+ let _ = await act(async () => {
97
+ root->ReactDOM.Client.Root.render(<Home fetchHok=Hooks.useFetch />)
98
+ })
99
+
100
+ let _ = await screen->findByText(placeholderText)
101
+ }
102
+
103
+ promise()
104
+ ->Promise.thenResolve(_ => {
105
+ Assert.elementContains(
106
+ ~message="has result",
107
+ ReactDOM.querySelector("#placeholder"),
108
+ placeholderText,
109
+ )
110
+ done()
111
+ })
112
+ ->ignore
113
+ })
114
+
115
+ testAsyncWithReact("fetchWithInit", (root, done) => {
116
+ let promise = async () => {
117
+ let _ = await act(async () => {
118
+ root->ReactDOM.Client.Root.render(<Home fetchHok=Hooks.useFetchWithInit />)
119
+ })
120
+
121
+ let _ = await screen->findByText(placeholderText)
122
+ }
123
+
124
+ promise()
125
+ ->Promise.thenResolve(_ => {
126
+ Assert.elementContains(
127
+ ~message="has result",
128
+ ReactDOM.querySelector("#placeholder"),
129
+ placeholderText,
130
+ )
131
+ done()
132
+ })
133
+ ->ignore
134
+ })
135
+
136
+ testAsyncWithReact("postFetchWithInit", (root, done) => {
137
+ let promise = async () => {
138
+ let _ = await act(async () => {
139
+ root->ReactDOM.Client.Root.render(<Home fetchHok=Hooks.usePostFetchWithInit />)
140
+ })
141
+
142
+ let _ = await screen->findByText(postPlaceholderText)
143
+ }
144
+
145
+ promise()
146
+ ->Promise.thenResolve(_ => {
147
+ Assert.elementContains(
148
+ ~message="has result",
149
+ ReactDOM.querySelector("#placeholder"),
150
+ postPlaceholderText,
151
+ )
152
+ done()
153
+ })
154
+ ->ignore
155
+ })
@@ -0,0 +1,162 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+ 'use strict';
3
+
4
+ var Fetch = require("../src/Fetch.res.js");
5
+ var React = require("react");
6
+ var Assert = require("./utils/Assert.res.js");
7
+ var ReactTest = require("./utils/ReactTest.res.js");
8
+ var Caml_option = require("rescript/lib/js/caml_option.js");
9
+ var Core__Option = require("@rescript/core/src/Core__Option.res.js");
10
+ var JsxRuntime = require("react/jsx-runtime");
11
+ var React$1 = require("@testing-library/react");
12
+
13
+ var placeholderText = "{\"userId\":1,\"id\":1,\"title\":\"delectus aut autem\",\"completed\":false}";
14
+
15
+ var postPlaceholderText = "{\"title\":\"foo\",\"body\":\"bar\",\"userId\":1,\"id\":101}";
16
+
17
+ function useFetch() {
18
+ var match = React.useState(function () {
19
+
20
+ });
21
+ var setState = match[1];
22
+ React.useEffect((function () {
23
+ var promise = async function () {
24
+ var response = await fetch("https://jsonplaceholder.typicode.com/todos/1");
25
+ var body = await response.json();
26
+ return setState(function (param) {
27
+ return body;
28
+ });
29
+ };
30
+ promise().then(function () {
31
+
32
+ });
33
+ }), []);
34
+ return match[0];
35
+ }
36
+
37
+ function useFetchWithInit() {
38
+ var match = React.useState(function () {
39
+
40
+ });
41
+ var setState = match[1];
42
+ React.useEffect((function () {
43
+ var promise = async function () {
44
+ var response = await fetch("https://jsonplaceholder.typicode.com/todos/1", Fetch.RequestInit.make("Get", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined));
45
+ var body = await response.json();
46
+ return setState(function (param) {
47
+ return body;
48
+ });
49
+ };
50
+ promise().then(function () {
51
+
52
+ });
53
+ }), []);
54
+ return match[0];
55
+ }
56
+
57
+ function usePostFetchWithInit() {
58
+ var postBody = {
59
+ title: "foo",
60
+ body: "bar",
61
+ userId: 1
62
+ };
63
+ var match = React.useState(function () {
64
+
65
+ });
66
+ var setState = match[1];
67
+ React.useEffect((function () {
68
+ var promise = async function () {
69
+ var body = Core__Option.getOr(JSON.stringify(postBody), "");
70
+ var headers = [
71
+ [
72
+ "Accept",
73
+ "application/json"
74
+ ],
75
+ [
76
+ "Content-Type",
77
+ "application/json"
78
+ ]
79
+ ];
80
+ var response = await fetch("https://jsonplaceholder.typicode.com/posts", Fetch.RequestInit.make("Post", Caml_option.some(headers), Caml_option.some(body), undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined));
81
+ var body$1 = await response.json();
82
+ return setState(function (param) {
83
+ return body$1;
84
+ });
85
+ };
86
+ promise().then(function () {
87
+
88
+ });
89
+ }), []);
90
+ return match[0];
91
+ }
92
+
93
+ var Hooks = {
94
+ useFetch: useFetch,
95
+ useFetchWithInit: useFetchWithInit,
96
+ usePostFetchWithInit: usePostFetchWithInit
97
+ };
98
+
99
+ function FetchTest$Home(props) {
100
+ var jsonPlaceholder = props.fetchHok();
101
+ return JsxRuntime.jsx("div", {
102
+ children: Core__Option.mapOr(jsonPlaceholder, "Loading...", (function (__x) {
103
+ return JSON.stringify(__x);
104
+ })),
105
+ id: "placeholder"
106
+ });
107
+ }
108
+
109
+ var Home = {
110
+ make: FetchTest$Home
111
+ };
112
+
113
+ ReactTest.testAsyncWithReact("fetch", undefined, (function (root, done) {
114
+ var promise = async function () {
115
+ await React$1.act(async function () {
116
+ root.render(JsxRuntime.jsx(FetchTest$Home, {
117
+ fetchHok: useFetch
118
+ }));
119
+ });
120
+ await React$1.screen.findByText(placeholderText);
121
+ };
122
+ promise().then(function () {
123
+ Assert.elementContains("has result", Caml_option.nullable_to_opt(document.querySelector("#placeholder")), placeholderText);
124
+ done(undefined, undefined);
125
+ });
126
+ }));
127
+
128
+ ReactTest.testAsyncWithReact("fetchWithInit", undefined, (function (root, done) {
129
+ var promise = async function () {
130
+ await React$1.act(async function () {
131
+ root.render(JsxRuntime.jsx(FetchTest$Home, {
132
+ fetchHok: useFetchWithInit
133
+ }));
134
+ });
135
+ await React$1.screen.findByText(placeholderText);
136
+ };
137
+ promise().then(function () {
138
+ Assert.elementContains("has result", Caml_option.nullable_to_opt(document.querySelector("#placeholder")), placeholderText);
139
+ done(undefined, undefined);
140
+ });
141
+ }));
142
+
143
+ ReactTest.testAsyncWithReact("postFetchWithInit", undefined, (function (root, done) {
144
+ var promise = async function () {
145
+ await React$1.act(async function () {
146
+ root.render(JsxRuntime.jsx(FetchTest$Home, {
147
+ fetchHok: usePostFetchWithInit
148
+ }));
149
+ });
150
+ await React$1.screen.findByText(postPlaceholderText);
151
+ };
152
+ promise().then(function () {
153
+ Assert.elementContains("has result", Caml_option.nullable_to_opt(document.querySelector("#placeholder")), postPlaceholderText);
154
+ done(undefined, undefined);
155
+ });
156
+ }));
157
+
158
+ exports.placeholderText = placeholderText;
159
+ exports.postPlaceholderText = postPlaceholderText;
160
+ exports.Hooks = Hooks;
161
+ exports.Home = Home;
162
+ /* Not a pure module */
@@ -0,0 +1,20 @@
1
+ open Test
2
+
3
+ @get external textContent: Dom.element => string = "textContent"
4
+
5
+ let isSome = (~message: string, value: option<'a>) =>
6
+ switch value {
7
+ | Some(_) => pass(~message, ())
8
+ | None => fail(~message="Expected Some, got None", ())
9
+ }
10
+
11
+ let elementContains = (~message=?, element: option<Dom.element>, substring: string) =>
12
+ assertion(
13
+ ~message?,
14
+ ~operator="elementContains",
15
+ (textContent, substring) => {
16
+ textContent->String.includes(substring)
17
+ },
18
+ element->Option.mapOr("Not Found", element => element->textContent),
19
+ substring,
20
+ )
@@ -0,0 +1,25 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+ 'use strict';
3
+
4
+ var Test = require("rescript-test/src/Test.res.js");
5
+ var Core__Option = require("@rescript/core/src/Core__Option.res.js");
6
+
7
+ function isSome(message, value) {
8
+ if (value !== undefined) {
9
+ return Test.pass(message, undefined);
10
+ } else {
11
+ return Test.fail("Expected Some, got None", undefined);
12
+ }
13
+ }
14
+
15
+ function elementContains(message, element, substring) {
16
+ Test.assertion(message, "elementContains", (function (textContent, substring) {
17
+ return textContent.includes(substring);
18
+ }), Core__Option.mapOr(element, "Not Found", (function (element) {
19
+ return element.textContent;
20
+ })), substring);
21
+ }
22
+
23
+ exports.isSome = isSome;
24
+ exports.elementContains = elementContains;
25
+ /* Test Not a pure module */