From 263f0edb3186ca29f4d12d437b57b87a35eeff93 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Sun, 27 Oct 2019 00:21:07 -0300 Subject: [PATCH 01/99] Add module jsfetch for fetch support for JavaScript target https://developer.mozilla.org/docs/Web/API/Fetch_API --- changelog.md | 1 + lib/js/jsfetch.nim | 48 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 lib/js/jsfetch.nim diff --git a/changelog.md b/changelog.md index 8b1aaeadc772..9c7f468f44c8 100644 --- a/changelog.md +++ b/changelog.md @@ -20,6 +20,7 @@ - `macros.newLit` now works for ref object types. - `system.writeFile` has been overloaded to also support `openarray[byte]`. +- `jsfetch` [Fetch](https://developer.mozilla.org/docs/Web/API/Fetch_API) wrapper for JavaScript target. ## Library changes diff --git a/lib/js/jsfetch.nim b/lib/js/jsfetch.nim new file mode 100644 index 000000000000..ee2bd8ac683f --- /dev/null +++ b/lib/js/jsfetch.nim @@ -0,0 +1,48 @@ +## Fetch +## ===== +## +## - Fetch wrapper for JavaScript target: https://developer.mozilla.org/docs/Web/API/Fetch_API +from asyncjs import PromiseJs +from httpcore import HttpMethod + +when not defined(js) and not defined(nimdoc): + {.fatal: "Module jsfetch is designed to be used with the JavaScript backend.".} + +type + fetchModes* = enum ## JavaScript Fetch API mode options. + fmCors, fmNoCors, fmSameOrigin + fetchCredentials* = enum ## JavaScript Fetch API Credential options. + fcInclude, fcSameOrigin, fcOmit + fetchCaches* = enum ## https://developer.mozilla.org/docs/Web/API/Request/cache + fchDefault, fchNoStore, fchReload, fchNoCache, fchForceCache + fetchRedirects* = enum ## JavaScript Fetch API Redirects options. + frFollow, frError, frManual + fetchReferrerPolicies* = enum ## JavaScript Fetch API Referrer Policy options. + frpNoReferrer, frpNoReferrerWhenDowngrade, frpOrigin, frpOriginWhenCrossOrigin, frpUnsafeUrl + + +proc fetch*(url: cstring, httpMethod = HttpGET, body = "".cstring, + integrity = "".cstring, referrer = "client".cstring, mode = fmNoCors, + credentials = fcInclude, cache = fchDefault, redirect = frFollow, + referrerPolicy = frpOrigin, keepalive = false): PromiseJs {.importcpp: """( + fetch(#, { + method: ["HEAD", "GET", "POST", "PUT", "DELETE", "GET", "GET", "GET", "PATCH"][#], + body: (# || undefined), + integrity: (# || undefined), + referrer: (# || undefined), + mode: ["cors", "no-cors", "same-origin"][#], + credentials: ["include", "same-origin", "omit"][#], + cache: ["default", "no-store", "reload", "no-cache", "force-cache"][#], + redirect: ["follow", "error", "manual"][#], + referrerPolicy: ["no-referrer", "no-referrer-when-downgrade", "origin", "origin-when-cross-origin", "unsafe-url"][#], + keepalive: # + }))""".} + ## https://developer.mozilla.org/docs/Web/API/Fetch_API + ## Default arguments of the API are also default arguments on this proc. + ## By default ``fetch`` is defined on the web browser, but not on NodeJS. + ## + ## .. code-block:: nim + ## + ## assert fetch("http://nim-lang.org".cstring) is PromiseJs, "asyncjs.PromiseJs" + ## let myPromise = fetch("http://example.io".cstring, HttpPost, body = "some data".cstring) + ## var anotherPromise = fetch("http://example.io/debts".cstring, HttpDelete) From 46b398f271684161cdaee9ad6df3e9b39c75df9c Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Sun, 5 Apr 2020 23:37:32 -0300 Subject: [PATCH 02/99] ReSync --- lib/js/jsfetch.nim | 106 +++++++++++++++++++++++++++++---------------- 1 file changed, 68 insertions(+), 38 deletions(-) diff --git a/lib/js/jsfetch.nim b/lib/js/jsfetch.nim index ee2bd8ac683f..79861ccefe69 100644 --- a/lib/js/jsfetch.nim +++ b/lib/js/jsfetch.nim @@ -1,48 +1,78 @@ -## Fetch -## ===== -## -## - Fetch wrapper for JavaScript target: https://developer.mozilla.org/docs/Web/API/Fetch_API +## - Fetch for the JavaScript target: https://developer.mozilla.org/docs/Web/API/Fetch_API from asyncjs import PromiseJs from httpcore import HttpMethod +export PromiseJs, HttpMethod when not defined(js) and not defined(nimdoc): {.fatal: "Module jsfetch is designed to be used with the JavaScript backend.".} +when defined(nodejs): + {.warning: "By design 'fetch()' is defined on the web browser, but may not be on NodeJS.".} -type - fetchModes* = enum ## JavaScript Fetch API mode options. - fmCors, fmNoCors, fmSameOrigin - fetchCredentials* = enum ## JavaScript Fetch API Credential options. - fcInclude, fcSameOrigin, fcOmit - fetchCaches* = enum ## https://developer.mozilla.org/docs/Web/API/Request/cache - fchDefault, fchNoStore, fchReload, fchNoCache, fchForceCache - fetchRedirects* = enum ## JavaScript Fetch API Redirects options. - frFollow, frError, frManual - fetchReferrerPolicies* = enum ## JavaScript Fetch API Referrer Policy options. - frpNoReferrer, frpNoReferrerWhenDowngrade, frpOrigin, frpOriginWhenCrossOrigin, frpUnsafeUrl +template method2cstring(metod: HttpMethod): cstring = + ## Template that takes an `HttpMethod` and returns an *Uppercase* `cstring`, + ## but *only* for the HTTP Methods that are supported by the fetch API. + ## High performance and minimal code compared to just `$(HttpMethod)`. + assert metod notin {HttpTrace, HttpOptions, HttpConnect}, "HTTP Method not supported by fetch API" + case metod + of HttpHead: "HEAD".cstring + of HttpGet: "GET".cstring + of HttpPost: "POST".cstring + of HttpPut: "PUT".cstring + of HttpDelete: "DELETE".cstring + of HttpPatch: "PATCH".cstring + else: "GET".cstring - -proc fetch*(url: cstring, httpMethod = HttpGET, body = "".cstring, - integrity = "".cstring, referrer = "client".cstring, mode = fmNoCors, - credentials = fcInclude, cache = fchDefault, redirect = frFollow, - referrerPolicy = frpOrigin, keepalive = false): PromiseJs {.importcpp: """( - fetch(#, { - method: ["HEAD", "GET", "POST", "PUT", "DELETE", "GET", "GET", "GET", "PATCH"][#], - body: (# || undefined), - integrity: (# || undefined), - referrer: (# || undefined), - mode: ["cors", "no-cors", "same-origin"][#], - credentials: ["include", "same-origin", "omit"][#], - cache: ["default", "no-store", "reload", "no-cache", "force-cache"][#], - redirect: ["follow", "error", "manual"][#], - referrerPolicy: ["no-referrer", "no-referrer-when-downgrade", "origin", "origin-when-cross-origin", "unsafe-url"][#], - keepalive: # - }))""".} - ## https://developer.mozilla.org/docs/Web/API/Fetch_API - ## Default arguments of the API are also default arguments on this proc. - ## By default ``fetch`` is defined on the web browser, but not on NodeJS. +func fetch*(url: cstring): PromiseJs {.importcpp: "fetch(#)".} + ## `fetch()` API, Simple GET only (generates `fetch(url)`). ## ## .. code-block:: nim + ## doAssert fetch("https://nim-lang.org") is PromiseJs + +func fetch*(url: cstring, httpMethod: static[HttpMethod], body: cstring): PromiseJs {.asmNoStackFrame.} = + ## `fetch()` API, for any HTTP Method (static overload for optimization). ## - ## assert fetch("http://nim-lang.org".cstring) is PromiseJs, "asyncjs.PromiseJs" - ## let myPromise = fetch("http://example.io".cstring, HttpPost, body = "some data".cstring) - ## var anotherPromise = fetch("http://example.io/debts".cstring, HttpDelete) + ## .. code-block:: nim + ## doAssert fetch("https://my.api.org", HttpPost, "body") is PromiseJs + # See the generated code if you dont understand why this overload exists. + assert url.len > 0, "url must not be empty string" + const x: cstring = method2cstring(httpMethod) + {.emit: """return fetch(`url`, {method: "`x`", body: `body`});""".} + +func fetch*(url: cstring, httpMethod: HttpMethod, body: cstring): PromiseJs {.asmNoStackFrame.} = + ## .. code-block:: nim + ## let mthd = HttpPost + ## doAssert fetch("https://my.api.org", mthd, "body") is PromiseJs + # See the generated code if you dont understand why this overload exists. + assert url.len > 0, "url must not be empty string" + let x: cstring = method2cstring(httpMethod) + {.emit: """return fetch(`url`, {method: `x`, body: `body`});""".} + +func fetch*(url: cstring, httpMethod: HttpMethod, body, mode, cache, redirect, + credentials, referrerPolicy: cstring, keepalive = false, integrity = "".cstring, + referrer = "client".cstring): PromiseJs {.asmNoStackFrame.} = + ## `fetch()` API, for any HTTP Method, overload with all arguments supported by fetch API. + # For Code Reviewers: Why dont use "Enum" for argument flags instead?. + # Because this is *Low-Level* API,a jshttpclient may stand on top,with Enums,Types,etc + # See the generated code if you dont understand why this overload exists. + assert url.len > 0, "url must not be empty string" + assert referrer.len > 0, "referrer must not be empty string" + assert redirect in ["follow".cstring, "error".cstring, "manual".cstring] + assert mode in ["cors".cstring, "no-cors".cstring, "same-origin".cstring] + assert credentials in ["include".cstring, "same-origin".cstring, "omit".cstring] + assert cache in ["no-store".cstring, "reload".cstring, "default".cstring, "no-cache".cstring, "force-cache".cstring] + assert referrerPolicy in ["no-referrer".cstring, "no-referrer-when-downgrade".cstring, + "origin".cstring, "origin-when-cross-origin".cstring, "unsafe-url".cstring] + let x: cstring = method2cstring(httpMethod) + {.emit: """return fetch(`url`, { + method: `x`, + body: `body`, + integrity: (`integrity` || undefined), + referrer: `referrer`, + mode: `mode`, + credentials: `credentials`, + cache: `cache`, + redirect: `redirect`, + referrerPolicy: `referrerPolicy`, + keepalive: `keepalive` + }); + """.} From 975932e159a655f1a17963424f81405410732c8a Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Fri, 10 Apr 2020 20:30:27 -0300 Subject: [PATCH 03/99] FetchOptions object to just pass 2 arguments to fetch() --- lib/js/jsfetch.nim | 116 +++++++++++++++++++++++++-------------------- 1 file changed, 64 insertions(+), 52 deletions(-) diff --git a/lib/js/jsfetch.nim b/lib/js/jsfetch.nim index 79861ccefe69..7ea61df86c96 100644 --- a/lib/js/jsfetch.nim +++ b/lib/js/jsfetch.nim @@ -8,7 +8,22 @@ when not defined(js) and not defined(nimdoc): when defined(nodejs): {.warning: "By design 'fetch()' is defined on the web browser, but may not be on NodeJS.".} -template method2cstring(metod: HttpMethod): cstring = +type + FetchOptions* = ref object + `method`, body, integrity, referrer, mode, credentials, cache, redirect, referrerPolicy: cstring + keepalive: bool + FetchModes* = enum ## JavaScript Fetch API mode options. + fmCors, fmNoCors, fmSameOrigin + FetchCredentials* = enum ## JavaScript Fetch API Credential options. + fcInclude, fcSameOrigin, fcOmit + FetchCaches* = enum ## https://developer.mozilla.org/docs/Web/API/Request/cache + fchDefault, fchNoStore, fchReload, fchNoCache, fchForceCache + FetchRedirects* = enum ## JavaScript Fetch API Redirects options. + frFollow, frError, frManual + FetchReferrerPolicies* = enum ## JavaScript Fetch API Referrer Policy options. + frpNoReferrer, frpNoReferrerWhenDowngrade, frpOrigin, frpOriginWhenCrossOrigin, frpUnsafeUrl + +template fetchMethodToCstring(metod: HttpMethod): cstring = ## Template that takes an `HttpMethod` and returns an *Uppercase* `cstring`, ## but *only* for the HTTP Methods that are supported by the fetch API. ## High performance and minimal code compared to just `$(HttpMethod)`. @@ -22,57 +37,54 @@ template method2cstring(metod: HttpMethod): cstring = of HttpPatch: "PATCH".cstring else: "GET".cstring -func fetch*(url: cstring): PromiseJs {.importcpp: "fetch(#)".} - ## `fetch()` API, Simple GET only (generates `fetch(url)`). - ## - ## .. code-block:: nim - ## doAssert fetch("https://nim-lang.org") is PromiseJs +template `$`(x: FetchCredentials): cstring = + case x + of fcInclude: "include".cstring + of fcSameOrigin: "same-origin".cstring + of fcOmit: "omit".cstring + +template `$`(x: FetchModes): cstring = + case x + of fmCors: "cors".cstring + of fmNoCors: "no-cors".cstring + of fmSameOrigin: "same-origin".cstring + +template `$`(x: FetchCaches): cstring = + case x + of fchDefault: "default".cstring + of fchNoStore: "no-store".cstring + of fchReload: "reload".cstring + of fchNoCache: "no-cache".cstring + of fchForceCache: "force-cache".cstring -func fetch*(url: cstring, httpMethod: static[HttpMethod], body: cstring): PromiseJs {.asmNoStackFrame.} = - ## `fetch()` API, for any HTTP Method (static overload for optimization). - ## - ## .. code-block:: nim - ## doAssert fetch("https://my.api.org", HttpPost, "body") is PromiseJs - # See the generated code if you dont understand why this overload exists. - assert url.len > 0, "url must not be empty string" - const x: cstring = method2cstring(httpMethod) - {.emit: """return fetch(`url`, {method: "`x`", body: `body`});""".} +template `$`(x: FetchRedirects): cstring = + case x + of frFollow: "follow".cstring + of frError: "error".cstring + of frManual: "manual".cstring -func fetch*(url: cstring, httpMethod: HttpMethod, body: cstring): PromiseJs {.asmNoStackFrame.} = - ## .. code-block:: nim - ## let mthd = HttpPost - ## doAssert fetch("https://my.api.org", mthd, "body") is PromiseJs - # See the generated code if you dont understand why this overload exists. - assert url.len > 0, "url must not be empty string" - let x: cstring = method2cstring(httpMethod) - {.emit: """return fetch(`url`, {method: `x`, body: `body`});""".} +template `$`(x: FetchReferrerPolicies): cstring = + case x + of frpNoReferrer: "no-referrer".cstring + of frpNoReferrerWhenDowngrade: "no-referrer-when-downgrade".cstring + of frpOrigin: "origin".cstring + of frpOriginWhenCrossOrigin: "origin-when-cross-origin".cstring + of frpUnsafeUrl: "unsafe-url".cstring + +func unsafeNewFetchOptions*(`method`, body, mode, credentials, cache, referrerPolicy: cstring, + keepalive: bool, redirect = "follow".cstring, referrer = "client".cstring, integrity = "".cstring): FetchOptions {.importcpp: + "{method: #, body: #, mode: #, credentials: #, cache: #, referrerPolicy: #, keepalive: #, redirect: #, referrer: #, integrity: #}".} + ## **Unsafe** `newfetchOptions`. Low-level proc, usage is discouraged, only for optimization purposes. + +func newfetchOptions*(metod: HttpMethod, body: cstring, + mode: FetchModes, credentials: FetchCredentials, cache: FetchCaches, referrerPolicy: FetchReferrerPolicies, + keepalive: bool, redirect = frFollow, referrer = "client".cstring, integrity = "".cstring): FetchOptions = + result = FetchOptions(`method`: fetchMethodTocstring(metod), body: body, mode: $mode, + credentials: $credentials, cache: $cache, referrerPolicy: $referrerPolicy, + keepalive: keepalive, redirect: $redirect , referrer: referrer, integrity: integrity) + +func fetch*(url: cstring): PromiseJs {.importcpp: "fetch(#)".} + ## `fetch()` API, Simple GET only (generates `fetch(url)`). -func fetch*(url: cstring, httpMethod: HttpMethod, body, mode, cache, redirect, - credentials, referrerPolicy: cstring, keepalive = false, integrity = "".cstring, - referrer = "client".cstring): PromiseJs {.asmNoStackFrame.} = - ## `fetch()` API, for any HTTP Method, overload with all arguments supported by fetch API. - # For Code Reviewers: Why dont use "Enum" for argument flags instead?. - # Because this is *Low-Level* API,a jshttpclient may stand on top,with Enums,Types,etc - # See the generated code if you dont understand why this overload exists. - assert url.len > 0, "url must not be empty string" - assert referrer.len > 0, "referrer must not be empty string" - assert redirect in ["follow".cstring, "error".cstring, "manual".cstring] - assert mode in ["cors".cstring, "no-cors".cstring, "same-origin".cstring] - assert credentials in ["include".cstring, "same-origin".cstring, "omit".cstring] - assert cache in ["no-store".cstring, "reload".cstring, "default".cstring, "no-cache".cstring, "force-cache".cstring] - assert referrerPolicy in ["no-referrer".cstring, "no-referrer-when-downgrade".cstring, - "origin".cstring, "origin-when-cross-origin".cstring, "unsafe-url".cstring] - let x: cstring = method2cstring(httpMethod) - {.emit: """return fetch(`url`, { - method: `x`, - body: `body`, - integrity: (`integrity` || undefined), - referrer: `referrer`, - mode: `mode`, - credentials: `credentials`, - cache: `cache`, - redirect: `redirect`, - referrerPolicy: `referrerPolicy`, - keepalive: `keepalive` - }); - """.} +func fetch*(url: cstring, options: FetchOptions): PromiseJs {.importcpp: "fetch(#, #)".} + ## `fetch()` API, Simple GET only (generates `fetch(url, options)`). From b497c1f959b138f435e7b792262b5cb520c0ae94 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Fri, 10 Apr 2020 22:54:18 -0300 Subject: [PATCH 04/99] https://github.com/nim-lang/Nim/pull/12531#discussion_r406985988 --- lib/js/jsfetch.nim | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/lib/js/jsfetch.nim b/lib/js/jsfetch.nim index 7ea61df86c96..aa06b40f3479 100644 --- a/lib/js/jsfetch.nim +++ b/lib/js/jsfetch.nim @@ -13,15 +13,17 @@ type `method`, body, integrity, referrer, mode, credentials, cache, redirect, referrerPolicy: cstring keepalive: bool FetchModes* = enum ## JavaScript Fetch API mode options. - fmCors, fmNoCors, fmSameOrigin + fmCors = "cors".cstring, fmNoCors = "no-cors".cstring, fmSameOrigin = "same-origin".cstring FetchCredentials* = enum ## JavaScript Fetch API Credential options. - fcInclude, fcSameOrigin, fcOmit + fcInclude = "include".cstring, fcSameOrigin = "same-origin".cstring, fcOmit = "omit".cstring FetchCaches* = enum ## https://developer.mozilla.org/docs/Web/API/Request/cache - fchDefault, fchNoStore, fchReload, fchNoCache, fchForceCache + fchDefault = "default".cstring, fchNoStore = "no-store".cstring, + fchReload = "reload".cstring, fchNoCache = "no-cache".cstring, fchForceCache = "force-cache".cstring FetchRedirects* = enum ## JavaScript Fetch API Redirects options. - frFollow, frError, frManual + frFollow = "follow".cstring, frError = "error".cstring, frManual = "manual".cstring FetchReferrerPolicies* = enum ## JavaScript Fetch API Referrer Policy options. - frpNoReferrer, frpNoReferrerWhenDowngrade, frpOrigin, frpOriginWhenCrossOrigin, frpUnsafeUrl + frpNoReferrer = "no-referrer".cstring, frpNoReferrerWhenDowngrade = "no-referrer-when-downgrade".cstring, + frpOrigin = "origin".cstring, frpOriginWhenCrossOrigin = "origin-when-cross-origin".cstring, frpUnsafeUrl = "unsafe-url".cstring template fetchMethodToCstring(metod: HttpMethod): cstring = ## Template that takes an `HttpMethod` and returns an *Uppercase* `cstring`, From 3e513a638a633dc0e8bf81332a44c058c31265d1 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Fri, 10 Apr 2020 22:58:03 -0300 Subject: [PATCH 05/99] https://github.com/nim-lang/Nim/pull/12531#discussion_r406987058 --- lib/js/jsfetch.nim | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/js/jsfetch.nim b/lib/js/jsfetch.nim index aa06b40f3479..52fec847382c 100644 --- a/lib/js/jsfetch.nim +++ b/lib/js/jsfetch.nim @@ -10,7 +10,9 @@ when defined(nodejs): type FetchOptions* = ref object - `method`, body, integrity, referrer, mode, credentials, cache, redirect, referrerPolicy: cstring + metod {.importc: "method".}: cstring + body, integrity, referrer, mode, credentials: cstring + cache, redirect, referrerPolicy: cstring keepalive: bool FetchModes* = enum ## JavaScript Fetch API mode options. fmCors = "cors".cstring, fmNoCors = "no-cors".cstring, fmSameOrigin = "same-origin".cstring @@ -73,7 +75,7 @@ template `$`(x: FetchReferrerPolicies): cstring = of frpOriginWhenCrossOrigin: "origin-when-cross-origin".cstring of frpUnsafeUrl: "unsafe-url".cstring -func unsafeNewFetchOptions*(`method`, body, mode, credentials, cache, referrerPolicy: cstring, +func unsafeNewFetchOptions*(metod, body, mode, credentials, cache, referrerPolicy: cstring, keepalive: bool, redirect = "follow".cstring, referrer = "client".cstring, integrity = "".cstring): FetchOptions {.importcpp: "{method: #, body: #, mode: #, credentials: #, cache: #, referrerPolicy: #, keepalive: #, redirect: #, referrer: #, integrity: #}".} ## **Unsafe** `newfetchOptions`. Low-level proc, usage is discouraged, only for optimization purposes. @@ -81,7 +83,7 @@ func unsafeNewFetchOptions*(`method`, body, mode, credentials, cache, referrerPo func newfetchOptions*(metod: HttpMethod, body: cstring, mode: FetchModes, credentials: FetchCredentials, cache: FetchCaches, referrerPolicy: FetchReferrerPolicies, keepalive: bool, redirect = frFollow, referrer = "client".cstring, integrity = "".cstring): FetchOptions = - result = FetchOptions(`method`: fetchMethodTocstring(metod), body: body, mode: $mode, + result = FetchOptions(metod: fetchMethodTocstring(metod), body: body, mode: $mode, credentials: $credentials, cache: $cache, referrerPolicy: $referrerPolicy, keepalive: keepalive, redirect: $redirect , referrer: referrer, integrity: integrity) From cf31e28dc022c47c4f5d0aec9a3e816b291a2c73 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Fri, 10 Apr 2020 23:06:27 -0300 Subject: [PATCH 06/99] https://github.com/nim-lang/Nim/pull/12531#discussion_r406987058 --- lib/js/jsfetch.nim | 42 +++++++++++++++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/lib/js/jsfetch.nim b/lib/js/jsfetch.nim index 52fec847382c..367f98bc93fa 100644 --- a/lib/js/jsfetch.nim +++ b/lib/js/jsfetch.nim @@ -11,21 +11,45 @@ when defined(nodejs): type FetchOptions* = ref object metod {.importc: "method".}: cstring - body, integrity, referrer, mode, credentials: cstring - cache, redirect, referrerPolicy: cstring + body: cstring + integrity: cstring + referrer: cstring + mode: cstring + credentials: cstring + cache: cstring + redirect: cstring + referrerPolicy: cstring keepalive: bool + FetchModes* = enum ## JavaScript Fetch API mode options. - fmCors = "cors".cstring, fmNoCors = "no-cors".cstring, fmSameOrigin = "same-origin".cstring + fmCors = "cors".cstring + fmNoCors = "no-cors".cstring + fmSameOrigin = "same-origin".cstring + FetchCredentials* = enum ## JavaScript Fetch API Credential options. - fcInclude = "include".cstring, fcSameOrigin = "same-origin".cstring, fcOmit = "omit".cstring + fcInclude = "include".cstring + fcSameOrigin = "same-origin".cstring + fcOmit = "omit".cstring + FetchCaches* = enum ## https://developer.mozilla.org/docs/Web/API/Request/cache - fchDefault = "default".cstring, fchNoStore = "no-store".cstring, - fchReload = "reload".cstring, fchNoCache = "no-cache".cstring, fchForceCache = "force-cache".cstring + fchDefault = "default".cstring + fchNoStore = "no-store".cstring + fchReload = "reload".cstring + fchNoCache = "no-cache".cstring + fchForceCache = "force-cache".cstring + FetchRedirects* = enum ## JavaScript Fetch API Redirects options. - frFollow = "follow".cstring, frError = "error".cstring, frManual = "manual".cstring + frFollow = "follow".cstring + frError = "error".cstring + frManual = "manual".cstring + FetchReferrerPolicies* = enum ## JavaScript Fetch API Referrer Policy options. - frpNoReferrer = "no-referrer".cstring, frpNoReferrerWhenDowngrade = "no-referrer-when-downgrade".cstring, - frpOrigin = "origin".cstring, frpOriginWhenCrossOrigin = "origin-when-cross-origin".cstring, frpUnsafeUrl = "unsafe-url".cstring + frpNoReferrer = "no-referrer".cstring + frpNoReferrerWhenDowngrade = "no-referrer-when-downgrade".cstring + frpOrigin = "origin".cstring + frpOriginWhenCrossOrigin = "origin-when-cross-origin".cstring + frpUnsafeUrl = "unsafe-url".cstring + template fetchMethodToCstring(metod: HttpMethod): cstring = ## Template that takes an `HttpMethod` and returns an *Uppercase* `cstring`, From 391d299dc7a300f6358992c1f7e9e9b0d729715a Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Fri, 10 Apr 2020 23:08:29 -0300 Subject: [PATCH 07/99] https://github.com/nim-lang/Nim/pull/12531#discussion_r406987058 --- lib/js/jsfetch.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/js/jsfetch.nim b/lib/js/jsfetch.nim index 367f98bc93fa..35aa98d3bb34 100644 --- a/lib/js/jsfetch.nim +++ b/lib/js/jsfetch.nim @@ -9,7 +9,7 @@ when defined(nodejs): {.warning: "By design 'fetch()' is defined on the web browser, but may not be on NodeJS.".} type - FetchOptions* = ref object + FetchOptions* = ref object ## Options for `fetch()` metod {.importc: "method".}: cstring body: cstring integrity: cstring From fd1b4e6dbe88e3055b9c8bfa19fc683a61c8b7ee Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Sun, 12 Apr 2020 01:15:09 -0300 Subject: [PATCH 08/99] Resync and clean out --- lib/js/jsfetch.nim | 34 ---------------------------------- 1 file changed, 34 deletions(-) diff --git a/lib/js/jsfetch.nim b/lib/js/jsfetch.nim index 35aa98d3bb34..a5198c846bdf 100644 --- a/lib/js/jsfetch.nim +++ b/lib/js/jsfetch.nim @@ -65,40 +65,6 @@ template fetchMethodToCstring(metod: HttpMethod): cstring = of HttpPatch: "PATCH".cstring else: "GET".cstring -template `$`(x: FetchCredentials): cstring = - case x - of fcInclude: "include".cstring - of fcSameOrigin: "same-origin".cstring - of fcOmit: "omit".cstring - -template `$`(x: FetchModes): cstring = - case x - of fmCors: "cors".cstring - of fmNoCors: "no-cors".cstring - of fmSameOrigin: "same-origin".cstring - -template `$`(x: FetchCaches): cstring = - case x - of fchDefault: "default".cstring - of fchNoStore: "no-store".cstring - of fchReload: "reload".cstring - of fchNoCache: "no-cache".cstring - of fchForceCache: "force-cache".cstring - -template `$`(x: FetchRedirects): cstring = - case x - of frFollow: "follow".cstring - of frError: "error".cstring - of frManual: "manual".cstring - -template `$`(x: FetchReferrerPolicies): cstring = - case x - of frpNoReferrer: "no-referrer".cstring - of frpNoReferrerWhenDowngrade: "no-referrer-when-downgrade".cstring - of frpOrigin: "origin".cstring - of frpOriginWhenCrossOrigin: "origin-when-cross-origin".cstring - of frpUnsafeUrl: "unsafe-url".cstring - func unsafeNewFetchOptions*(metod, body, mode, credentials, cache, referrerPolicy: cstring, keepalive: bool, redirect = "follow".cstring, referrer = "client".cstring, integrity = "".cstring): FetchOptions {.importcpp: "{method: #, body: #, mode: #, credentials: #, cache: #, referrerPolicy: #, keepalive: #, redirect: #, referrer: #, integrity: #}".} From 7c2157580115b45d7a6fb86cca3dd69d5f077594 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Sun, 12 Apr 2020 01:23:05 -0300 Subject: [PATCH 09/99] Doc Comment --- lib/js/jsfetch.nim | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/js/jsfetch.nim b/lib/js/jsfetch.nim index a5198c846bdf..f655b39dd62d 100644 --- a/lib/js/jsfetch.nim +++ b/lib/js/jsfetch.nim @@ -73,6 +73,7 @@ func unsafeNewFetchOptions*(metod, body, mode, credentials, cache, referrerPolic func newfetchOptions*(metod: HttpMethod, body: cstring, mode: FetchModes, credentials: FetchCredentials, cache: FetchCaches, referrerPolicy: FetchReferrerPolicies, keepalive: bool, redirect = frFollow, referrer = "client".cstring, integrity = "".cstring): FetchOptions = + ## Constructor for `FetchOptions`. result = FetchOptions(metod: fetchMethodTocstring(metod), body: body, mode: $mode, credentials: $credentials, cache: $cache, referrerPolicy: $referrerPolicy, keepalive: keepalive, redirect: $redirect , referrer: referrer, integrity: integrity) @@ -81,4 +82,4 @@ func fetch*(url: cstring): PromiseJs {.importcpp: "fetch(#)".} ## `fetch()` API, Simple GET only (generates `fetch(url)`). func fetch*(url: cstring, options: FetchOptions): PromiseJs {.importcpp: "fetch(#, #)".} - ## `fetch()` API, Simple GET only (generates `fetch(url, options)`). + ## `fetch()` API that takes a `FetchOptions` (generates `fetch(url, options)`). From 41ecadd9212e1d94c1768ef76a6d84c391de2a8e Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Sun, 12 Apr 2020 01:56:25 -0300 Subject: [PATCH 10/99] Doc Comment --- lib/js/jsfetch.nim | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/js/jsfetch.nim b/lib/js/jsfetch.nim index f655b39dd62d..846286dd7678 100644 --- a/lib/js/jsfetch.nim +++ b/lib/js/jsfetch.nim @@ -1,7 +1,7 @@ ## - Fetch for the JavaScript target: https://developer.mozilla.org/docs/Web/API/Fetch_API -from asyncjs import PromiseJs +import asyncjs from httpcore import HttpMethod -export PromiseJs, HttpMethod +export asyncjs, HttpMethod when not defined(js) and not defined(nimdoc): {.fatal: "Module jsfetch is designed to be used with the JavaScript backend.".} @@ -78,8 +78,8 @@ func newfetchOptions*(metod: HttpMethod, body: cstring, credentials: $credentials, cache: $cache, referrerPolicy: $referrerPolicy, keepalive: keepalive, redirect: $redirect , referrer: referrer, integrity: integrity) -func fetch*(url: cstring): PromiseJs {.importcpp: "fetch(#)".} +func fetch*(url: cstring): Future[PromiseJs] {.importcpp: "fetch(#)".} ## `fetch()` API, Simple GET only (generates `fetch(url)`). -func fetch*(url: cstring, options: FetchOptions): PromiseJs {.importcpp: "fetch(#, #)".} +func fetch*(url: cstring, options: FetchOptions): Future[PromiseJs] {.importcpp: "fetch(#, #)".} ## `fetch()` API that takes a `FetchOptions` (generates `fetch(url, options)`). From 60fb0e1604e0e69122985723e5ca40e5e11d2c71 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Fri, 11 Dec 2020 20:43:07 -0300 Subject: [PATCH 11/99] Fix conflict on changelog --- changelog.md | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/changelog.md b/changelog.md index 191b4fd664ec..21f3aa0edc43 100644 --- a/changelog.md +++ b/changelog.md @@ -4,13 +4,6 @@ ## Standard library additions and changes -- `uri` adds Data URI Base64, implements RFC-2397. -- Add [DOM Parser](https://developer.mozilla.org/en-US/docs/Web/API/DOMParser) - to the `dom` module for the JavaScript target. -- `jsfetch` [Fetch](https://developer.mozilla.org/docs/Web/API/Fetch_API) wrapper for JavaScript target. -- The default hash for `Ordinal` has changed to something more bit-scrambling. - `import hashes; proc hash(x: myInt): Hash = hashIdentity(x)` recovers the old - one in an instantiation context while `-d:nimIntHash1` recovers it globally. - Make `{.requiresInit.}` pragma to work for `distinct` types. - Added a macros `enumLen` for returning the number of items in an enum to the @@ -67,6 +60,9 @@ - Added `math.isNaN`. +- `jsfetch` [Fetch](https://developer.mozilla.org/docs/Web/API/Fetch_API) wrapper for JavaScript target. + + ## Language changes - `nimscript` now handles `except Exception as e`. From 8ddb073d0c9f43097306bb11af6e48a82d698dd1 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Fri, 11 Dec 2020 20:44:34 -0300 Subject: [PATCH 12/99] Fix conflict on changelog --- changelog.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/changelog.md b/changelog.md index 5237e4a76e1e..21f3aa0edc43 100644 --- a/changelog.md +++ b/changelog.md @@ -63,8 +63,6 @@ - `jsfetch` [Fetch](https://developer.mozilla.org/docs/Web/API/Fetch_API) wrapper for JavaScript target. -- `jsfetch` [Fetch](https://developer.mozilla.org/docs/Web/API/Fetch_API) wrapper for JavaScript target. - ## Language changes - `nimscript` now handles `except Exception as e`. @@ -90,3 +88,8 @@ ## Tool changes +- The rst parser now supports markdown table syntax. + Known limitations: + - cell alignment is not supported, i.e. alignment annotations in a delimiter + row (`:---`, `:--:`, `---:`) are ignored, + - every table row must start with `|`, e.g. `| cell 1 | cell 2 |`. From ea89ef318d6a2a9b0edf51481e5cbeabba141b5a Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Sat, 12 Dec 2020 02:29:13 -0300 Subject: [PATCH 13/99] Working --- lib/js/jsfetch.nim | 75 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 52 insertions(+), 23 deletions(-) diff --git a/lib/js/jsfetch.nim b/lib/js/jsfetch.nim index 2610d3a70350..db086fdfdca1 100644 --- a/lib/js/jsfetch.nim +++ b/lib/js/jsfetch.nim @@ -1,25 +1,18 @@ ## - Fetch for the JavaScript target: https://developer.mozilla.org/docs/Web/API/Fetch_API -import asyncjs from httpcore import HttpMethod -export asyncjs, HttpMethod +export HttpMethod when not defined(js) and not defined(nimdoc): {.fatal: "Module jsfetch is designed to be used with the JavaScript backend.".} when defined(nodejs): - {.warning: "By design 'fetch()' is defined on the web browser, but may not be on NodeJS.".} + {.warning: "By design Fetch is defined on the web browser, but may not be on NodeJS.".} + type - FetchOptions* = ref object ## Options for `fetch()` - metod {.importc: "method".}: cstring - body: cstring - integrity: cstring - referrer: cstring - mode: cstring - credentials: cstring - cache: cstring - redirect: cstring - referrerPolicy: cstring + FetchOptions* = ref object ## Options for Fetch API. keepalive: bool + metod {.importc: "method".}: cstring + body, integrity, referrer, mode, credentials, cache, redirect, referrerPolicy: cstring FetchModes* = enum ## JavaScript Fetch API mode options. fmCors = "cors".cstring @@ -50,12 +43,48 @@ type frpOriginWhenCrossOrigin = "origin-when-cross-origin".cstring frpUnsafeUrl = "unsafe-url".cstring + Headers* = ref object ## https://developer.mozilla.org/en-US/docs/Web/API/Headers + + Response* = ref object ## Response for Fetch API. + myBodyUsed, ok, redirected: bool + tipe {.importc: "type".}: cstring + url, statusText: cstring + status: cushort + headers: Headers + + +func newHeaders*(): Headers {.importcpp: "(new Headers())".} + ## https://developer.mozilla.org/en-US/docs/Web/API/Headers + +func append*(this: Headers; name: cstring; value: cstring) {.importcpp: "#.append(#, #)".} + ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/append + +func delete*(this: Headers; name: cstring) {.importcpp: "#.delete(#)".} + ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/delete + +func get*(this: Headers; name: cstring): cstring {.importcpp: "#.get(#)".} + ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/get + +func has*(this: Headers; name: cstring): bool {.importcpp: "#.has(#)".} + ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/has + +func set*(this: Headers; name: cstring; value: cstring) {.importcpp: "#.set(#, #)".} + ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/set + +func keys*(this: Headers): seq[cstring] {.importcpp: "Array.from(#.keys())".} + ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/keys + +func values*(this: Headers): seq[cstring] {.importcpp: "Array.from(#.values())".} + ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/values + +func entries*(this: Headers): seq[array[2, cstring]] {.importcpp: "Array.from(#.entries())".} + ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/entries template fetchMethodToCstring(metod: HttpMethod): cstring = ## Template that takes an `HttpMethod` and returns an *Uppercase* `cstring`, ## but *only* for the HTTP Methods that are supported by the fetch API. ## High performance and minimal code compared to just `$(HttpMethod)`. - assert metod notin {HttpTrace, HttpOptions, HttpConnect}, "HTTP Method not supported by fetch API" + assert metod notin {HttpTrace, HttpOptions, HttpConnect}, "HTTP Method not supported by Fetch API" case metod of HttpHead: "HEAD".cstring of HttpGet: "GET".cstring @@ -68,7 +97,7 @@ template fetchMethodToCstring(metod: HttpMethod): cstring = func unsafeNewFetchOptions*(metod, body, mode, credentials, cache, referrerPolicy: cstring, keepalive: bool, redirect = "follow".cstring, referrer = "client".cstring, integrity = "".cstring): FetchOptions {.importcpp: "{method: #, body: #, mode: #, credentials: #, cache: #, referrerPolicy: #, keepalive: #, redirect: #, referrer: #, integrity: #}".} - ## **Unsafe** `newfetchOptions`. Low-level proc, usage is discouraged, only for optimization purposes. + ## **Unsafe** `newfetchOptions`. Low-level proc for optimization. func newfetchOptions*(metod: HttpMethod, body: cstring, mode: FetchModes, credentials: FetchCredentials, cache: FetchCaches, referrerPolicy: FetchReferrerPolicies, @@ -78,14 +107,14 @@ func newfetchOptions*(metod: HttpMethod, body: cstring, credentials: $credentials, cache: $cache, referrerPolicy: $referrerPolicy, keepalive: keepalive, redirect: $redirect , referrer: referrer, integrity: integrity) -func fetch*(url: cstring): Future[PromiseJs] {.importcpp: "fetch(#)".} - ## `fetch()` API, Simple GET only (generates `fetch(url)`). - -func fetch*(url: cstring, options: FetchOptions): Future[PromiseJs] {.importcpp: "fetch(#, #)".} - ## `fetch()` API that takes a `FetchOptions` (generates `fetch(url, options)`). - -func fetchToCstring*(url: cstring): Future[cstring] {.importcpp: "fetch(#).then(function(result){result.text()})".} +func fetchToCstring*(url: cstring): cstring {.importcpp: "await fetch(#).then(response => response.text()).then(text => text)".} ## Convenience proc for `fetch()` API that returns a `cstring` directly. -func fetchToCstring*(url: cstring, options: FetchOptions): Future[cstring] {.importcpp: "fetch(#, #).then(function(result){result.text()})".} +func fetchToCstring*(url: cstring, options: FetchOptions): cstring {.importcpp: "await fetch(#, #).then(response => response.text()).then(text => text)".} ## Convenience proc for `fetch()` API that returns a `cstring` directly. + +func fetch*(url: cstring): Response {.importcpp: "await fetch(#).then(response => response)".} + ## `fetch()` API, simple `GET` only, returns a `Response`. + +func fetch*(url: cstring, options: FetchOptions): Response {.importcpp: "await fetch(#, #).then(response => response)".} + ## `fetch()` API that takes a `FetchOptions`, returns a `Response`. From 0298a03f28c4ec1c55cce7ee58b26e360dd46abc Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Sat, 12 Dec 2020 02:32:15 -0300 Subject: [PATCH 14/99] Working --- lib/js/jsfetch.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/js/jsfetch.nim b/lib/js/jsfetch.nim index db086fdfdca1..b5b1e12546b4 100644 --- a/lib/js/jsfetch.nim +++ b/lib/js/jsfetch.nim @@ -53,7 +53,7 @@ type headers: Headers -func newHeaders*(): Headers {.importcpp: "(new Headers())".} +func newHeaders*(): Headers {.importcpp: "new Headers()".} ## https://developer.mozilla.org/en-US/docs/Web/API/Headers func append*(this: Headers; name: cstring; value: cstring) {.importcpp: "#.append(#, #)".} From fa9ca348d90f810502cdd9bfc46b540aaa3c6bc2 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Sat, 12 Dec 2020 02:40:27 -0300 Subject: [PATCH 15/99] Working --- lib/js/jsfetch.nim | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/lib/js/jsfetch.nim b/lib/js/jsfetch.nim index b5b1e12546b4..70341193e95c 100644 --- a/lib/js/jsfetch.nim +++ b/lib/js/jsfetch.nim @@ -9,34 +9,34 @@ when defined(nodejs): type - FetchOptions* = ref object ## Options for Fetch API. + FetchOptions* = ref object ## Options for Fetch API. keepalive: bool metod {.importc: "method".}: cstring body, integrity, referrer, mode, credentials, cache, redirect, referrerPolicy: cstring - FetchModes* = enum ## JavaScript Fetch API mode options. + FetchModes* = enum ## JavaScript Fetch API mode options. fmCors = "cors".cstring fmNoCors = "no-cors".cstring fmSameOrigin = "same-origin".cstring - FetchCredentials* = enum ## JavaScript Fetch API Credential options. + FetchCredentials* = enum ## JavaScript Fetch API Credential options. fcInclude = "include".cstring fcSameOrigin = "same-origin".cstring fcOmit = "omit".cstring - FetchCaches* = enum ## https://developer.mozilla.org/docs/Web/API/Request/cache + FetchCaches* = enum ## https://developer.mozilla.org/docs/Web/API/Request/cache fchDefault = "default".cstring fchNoStore = "no-store".cstring fchReload = "reload".cstring fchNoCache = "no-cache".cstring fchForceCache = "force-cache".cstring - FetchRedirects* = enum ## JavaScript Fetch API Redirects options. + FetchRedirects* = enum ## JavaScript Fetch API Redirects options. frFollow = "follow".cstring frError = "error".cstring frManual = "manual".cstring - FetchReferrerPolicies* = enum ## JavaScript Fetch API Referrer Policy options. + FetchReferrerPolicies* = enum ## JavaScript Fetch API Referrer Policy options. frpNoReferrer = "no-referrer".cstring frpNoReferrerWhenDowngrade = "no-referrer-when-downgrade".cstring frpOrigin = "origin".cstring @@ -45,7 +45,7 @@ type Headers* = ref object ## https://developer.mozilla.org/en-US/docs/Web/API/Headers - Response* = ref object ## Response for Fetch API. + Response* = ref object ## https://developer.mozilla.org/en-US/docs/Web/API/Response myBodyUsed, ok, redirected: bool tipe {.importc: "type".}: cstring url, statusText: cstring @@ -97,7 +97,7 @@ template fetchMethodToCstring(metod: HttpMethod): cstring = func unsafeNewFetchOptions*(metod, body, mode, credentials, cache, referrerPolicy: cstring, keepalive: bool, redirect = "follow".cstring, referrer = "client".cstring, integrity = "".cstring): FetchOptions {.importcpp: "{method: #, body: #, mode: #, credentials: #, cache: #, referrerPolicy: #, keepalive: #, redirect: #, referrer: #, integrity: #}".} - ## **Unsafe** `newfetchOptions`. Low-level proc for optimization. + ## **Unsafe** `newfetchOptions`. Low-level func for optimization. func newfetchOptions*(metod: HttpMethod, body: cstring, mode: FetchModes, credentials: FetchCredentials, cache: FetchCaches, referrerPolicy: FetchReferrerPolicies, @@ -108,10 +108,10 @@ func newfetchOptions*(metod: HttpMethod, body: cstring, keepalive: keepalive, redirect: $redirect , referrer: referrer, integrity: integrity) func fetchToCstring*(url: cstring): cstring {.importcpp: "await fetch(#).then(response => response.text()).then(text => text)".} - ## Convenience proc for `fetch()` API that returns a `cstring` directly. + ## Convenience func for `fetch()` API that returns a `cstring` directly. func fetchToCstring*(url: cstring, options: FetchOptions): cstring {.importcpp: "await fetch(#, #).then(response => response.text()).then(text => text)".} - ## Convenience proc for `fetch()` API that returns a `cstring` directly. + ## Convenience func for `fetch()` API that returns a `cstring` directly. func fetch*(url: cstring): Response {.importcpp: "await fetch(#).then(response => response)".} ## `fetch()` API, simple `GET` only, returns a `Response`. From 5f73f4377703c28fa78740b7056d702f1295e36c Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Sat, 12 Dec 2020 03:17:08 -0300 Subject: [PATCH 16/99] Convenience func is convenient --- lib/js/jsfetch.nim | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/js/jsfetch.nim b/lib/js/jsfetch.nim index 70341193e95c..a82e6e1147b1 100644 --- a/lib/js/jsfetch.nim +++ b/lib/js/jsfetch.nim @@ -4,9 +4,6 @@ export HttpMethod when not defined(js) and not defined(nimdoc): {.fatal: "Module jsfetch is designed to be used with the JavaScript backend.".} -when defined(nodejs): - {.warning: "By design Fetch is defined on the web browser, but may not be on NodeJS.".} - type FetchOptions* = ref object ## Options for Fetch API. @@ -94,6 +91,9 @@ template fetchMethodToCstring(metod: HttpMethod): cstring = of HttpPatch: "PATCH".cstring else: "GET".cstring +func hasFetch*(): bool {.importcpp: "(() => { return !!window.fetch })()".} + ## Convenience func to detect Fetch API support, returns `true` if Fetch is supported. + func unsafeNewFetchOptions*(metod, body, mode, credentials, cache, referrerPolicy: cstring, keepalive: bool, redirect = "follow".cstring, referrer = "client".cstring, integrity = "".cstring): FetchOptions {.importcpp: "{method: #, body: #, mode: #, credentials: #, cache: #, referrerPolicy: #, keepalive: #, redirect: #, referrer: #, integrity: #}".} From 970444a1e7afd0334f01e7f2fd899807f08622d6 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Sat, 12 Dec 2020 03:23:55 -0300 Subject: [PATCH 17/99] importcpp to importjs --- lib/js/jsfetch.nim | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/lib/js/jsfetch.nim b/lib/js/jsfetch.nim index a82e6e1147b1..954404c20985 100644 --- a/lib/js/jsfetch.nim +++ b/lib/js/jsfetch.nim @@ -8,7 +8,7 @@ when not defined(js) and not defined(nimdoc): type FetchOptions* = ref object ## Options for Fetch API. keepalive: bool - metod {.importc: "method".}: cstring + metod {.importjs: "method".}: cstring body, integrity, referrer, mode, credentials, cache, redirect, referrerPolicy: cstring FetchModes* = enum ## JavaScript Fetch API mode options. @@ -44,37 +44,37 @@ type Response* = ref object ## https://developer.mozilla.org/en-US/docs/Web/API/Response myBodyUsed, ok, redirected: bool - tipe {.importc: "type".}: cstring + tipe {.importjs: "type".}: cstring url, statusText: cstring status: cushort headers: Headers -func newHeaders*(): Headers {.importcpp: "new Headers()".} +func newHeaders*(): Headers {.importjs: "new Headers()".} ## https://developer.mozilla.org/en-US/docs/Web/API/Headers -func append*(this: Headers; name: cstring; value: cstring) {.importcpp: "#.append(#, #)".} +func append*(this: Headers; name: cstring; value: cstring) {.importjs: "#.append(#, #)".} ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/append -func delete*(this: Headers; name: cstring) {.importcpp: "#.delete(#)".} +func delete*(this: Headers; name: cstring) {.importjs: "#.delete(#)".} ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/delete -func get*(this: Headers; name: cstring): cstring {.importcpp: "#.get(#)".} +func get*(this: Headers; name: cstring): cstring {.importjs: "#.get(#)".} ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/get -func has*(this: Headers; name: cstring): bool {.importcpp: "#.has(#)".} +func has*(this: Headers; name: cstring): bool {.importjs: "#.has(#)".} ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/has -func set*(this: Headers; name: cstring; value: cstring) {.importcpp: "#.set(#, #)".} +func set*(this: Headers; name: cstring; value: cstring) {.importjs: "#.set(#, #)".} ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/set -func keys*(this: Headers): seq[cstring] {.importcpp: "Array.from(#.keys())".} +func keys*(this: Headers): seq[cstring] {.importjs: "Array.from(#.keys())".} ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/keys -func values*(this: Headers): seq[cstring] {.importcpp: "Array.from(#.values())".} +func values*(this: Headers): seq[cstring] {.importjs: "Array.from(#.values())".} ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/values -func entries*(this: Headers): seq[array[2, cstring]] {.importcpp: "Array.from(#.entries())".} +func entries*(this: Headers): seq[array[2, cstring]] {.importjs: "Array.from(#.entries())".} ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/entries template fetchMethodToCstring(metod: HttpMethod): cstring = @@ -91,11 +91,11 @@ template fetchMethodToCstring(metod: HttpMethod): cstring = of HttpPatch: "PATCH".cstring else: "GET".cstring -func hasFetch*(): bool {.importcpp: "(() => { return !!window.fetch })()".} +func hasFetch*(): bool {.importjs: "(() => { return !!window.fetch })()".} ## Convenience func to detect Fetch API support, returns `true` if Fetch is supported. func unsafeNewFetchOptions*(metod, body, mode, credentials, cache, referrerPolicy: cstring, - keepalive: bool, redirect = "follow".cstring, referrer = "client".cstring, integrity = "".cstring): FetchOptions {.importcpp: + keepalive: bool, redirect = "follow".cstring, referrer = "client".cstring, integrity = "".cstring): FetchOptions {.importjs: "{method: #, body: #, mode: #, credentials: #, cache: #, referrerPolicy: #, keepalive: #, redirect: #, referrer: #, integrity: #}".} ## **Unsafe** `newfetchOptions`. Low-level func for optimization. @@ -107,14 +107,14 @@ func newfetchOptions*(metod: HttpMethod, body: cstring, credentials: $credentials, cache: $cache, referrerPolicy: $referrerPolicy, keepalive: keepalive, redirect: $redirect , referrer: referrer, integrity: integrity) -func fetchToCstring*(url: cstring): cstring {.importcpp: "await fetch(#).then(response => response.text()).then(text => text)".} +func fetchToCstring*(url: cstring): cstring {.importjs: "await fetch(#).then(response => response.text()).then(text => text)".} ## Convenience func for `fetch()` API that returns a `cstring` directly. -func fetchToCstring*(url: cstring, options: FetchOptions): cstring {.importcpp: "await fetch(#, #).then(response => response.text()).then(text => text)".} +func fetchToCstring*(url: cstring, options: FetchOptions): cstring {.importjs: "await fetch(#, #).then(response => response.text()).then(text => text)".} ## Convenience func for `fetch()` API that returns a `cstring` directly. -func fetch*(url: cstring): Response {.importcpp: "await fetch(#).then(response => response)".} +func fetch*(url: cstring): Response {.importjs: "await fetch(#).then(response => response)".} ## `fetch()` API, simple `GET` only, returns a `Response`. -func fetch*(url: cstring, options: FetchOptions): Response {.importcpp: "await fetch(#, #).then(response => response)".} +func fetch*(url: cstring, options: FetchOptions): Response {.importjs: "await fetch(#, #).then(response => response)".} ## `fetch()` API that takes a `FetchOptions`, returns a `Response`. From bfa45008683e1b33e43e705d2cd4e42ab3b45bb5 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Sat, 12 Dec 2020 03:37:15 -0300 Subject: [PATCH 18/99] runnableExamples only work on web browser console, but they work --- lib/js/jsfetch.nim | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/lib/js/jsfetch.nim b/lib/js/jsfetch.nim index 954404c20985..2f821c3b60dc 100644 --- a/lib/js/jsfetch.nim +++ b/lib/js/jsfetch.nim @@ -118,3 +118,36 @@ func fetch*(url: cstring): Response {.importjs: "await fetch(#).then(response => func fetch*(url: cstring, options: FetchOptions): Response {.importjs: "await fetch(#, #).then(response => response)".} ## `fetch()` API that takes a `FetchOptions`, returns a `Response`. + + +runnableExamples: + when defined(nimJsFetchTests): + + block: + doAssert hasFetch() + var header = newHeaders() + header.append(r"key", r"value") + doAssert header.has(r"key") + doAssert header.keys() == @["key".cstring] + doAssert header.values() == @["value".cstring] + doAssert header.get(r"key") == "value".cstring + header.set(r"other", r"another") + doAssert header.get(r"other") == "another".cstring + doAssert header.entries() == @[["key".cstring, "value"], ["other".cstring, "another"]] + header.delete(r"other") + + block: + let options = unsafeNewFetchOption( + metod = "POST".cstring, + body = """{"key": "value"}""".cstring, + mode = "no-cors".cstring, + credentials = "omit".cstring, + cache = "no-cache".cstring, + referrerPolicy = "no-referrer".cstring, + keepalive = false, + redirect = "follow".cstring, + referrer = "client".cstring, + integrity = "".cstring + ) + doAssert options is FetchOptions + echo fetchToCstring(r"http://httpbin.org/post", options) From d253ca540e7d9cff8366963496b221dd9598e085 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Sat, 12 Dec 2020 04:00:59 -0300 Subject: [PATCH 19/99] naming --- lib/js/jsfetch.nim | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/js/jsfetch.nim b/lib/js/jsfetch.nim index 2f821c3b60dc..fe965e3f41b1 100644 --- a/lib/js/jsfetch.nim +++ b/lib/js/jsfetch.nim @@ -53,19 +53,19 @@ type func newHeaders*(): Headers {.importjs: "new Headers()".} ## https://developer.mozilla.org/en-US/docs/Web/API/Headers -func append*(this: Headers; name: cstring; value: cstring) {.importjs: "#.append(#, #)".} +func append*(this: Headers; key: cstring; value: cstring) {.importjs: "#.append(#, #)".} ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/append -func delete*(this: Headers; name: cstring) {.importjs: "#.delete(#)".} +func delete*(this: Headers; key: cstring) {.importjs: "#.delete(#)".} ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/delete -func get*(this: Headers; name: cstring): cstring {.importjs: "#.get(#)".} +func get*(this: Headers; key: cstring): cstring {.importjs: "#.get(#)".} ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/get -func has*(this: Headers; name: cstring): bool {.importjs: "#.has(#)".} +func has*(this: Headers; key: cstring): bool {.importjs: "#.has(#)".} ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/has -func set*(this: Headers; name: cstring; value: cstring) {.importjs: "#.set(#, #)".} +func set*(this: Headers; key: cstring; value: cstring) {.importjs: "#.set(#, #)".} ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/set func keys*(this: Headers): seq[cstring] {.importjs: "Array.from(#.keys())".} From f009084e6fe33f2903fd665e9e1609046182af95 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Sat, 12 Dec 2020 04:03:31 -0300 Subject: [PATCH 20/99] trypo --- lib/js/jsfetch.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/js/jsfetch.nim b/lib/js/jsfetch.nim index fe965e3f41b1..b438e2aaf7ec 100644 --- a/lib/js/jsfetch.nim +++ b/lib/js/jsfetch.nim @@ -137,7 +137,7 @@ runnableExamples: header.delete(r"other") block: - let options = unsafeNewFetchOption( + let options = unsafeNewFetchOptions( metod = "POST".cstring, body = """{"key": "value"}""".cstring, mode = "no-cors".cstring, From 67e4a1e6ddf17d1d1b3425334465d7b2954f1a01 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Sat, 12 Dec 2020 04:04:29 -0300 Subject: [PATCH 21/99] tipo --- lib/js/jsfetch.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/js/jsfetch.nim b/lib/js/jsfetch.nim index b438e2aaf7ec..c8aeedd4e8e0 100644 --- a/lib/js/jsfetch.nim +++ b/lib/js/jsfetch.nim @@ -121,7 +121,7 @@ func fetch*(url: cstring, options: FetchOptions): Response {.importjs: "await fe runnableExamples: - when defined(nimJsFetchTests): + if defined(nimJsFetchTests): block: doAssert hasFetch() From 5278aa1dc64cf3486020576d1a0f104666189cc7 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Sat, 12 Dec 2020 20:53:58 -0300 Subject: [PATCH 22/99] Headers really is a thing for itself --- changelog.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/changelog.md b/changelog.md index 21f3aa0edc43..036e9d31ea7f 100644 --- a/changelog.md +++ b/changelog.md @@ -60,7 +60,8 @@ - Added `math.isNaN`. -- `jsfetch` [Fetch](https://developer.mozilla.org/docs/Web/API/Fetch_API) wrapper for JavaScript target. +- Added `jsfetch` module [Fetch](https://developer.mozilla.org/docs/Web/API/Fetch_API) wrapper for JavaScript target. +- Added `jsheaders` module [Headers](https://developer.mozilla.org/en-US/docs/Web/API/Headers) wrapper for JavaScript target. ## Language changes From c7760d87b5c87abbb596b106c571166051ab38e7 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Sat, 12 Dec 2020 20:54:13 -0300 Subject: [PATCH 23/99] Headers really is a thing for itself --- lib/js/jsheaders.nim | 48 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 lib/js/jsheaders.nim diff --git a/lib/js/jsheaders.nim b/lib/js/jsheaders.nim new file mode 100644 index 000000000000..1da9b791ae49 --- /dev/null +++ b/lib/js/jsheaders.nim @@ -0,0 +1,48 @@ +## - HTTP Headers for the JavaScript target: https://developer.mozilla.org/en-US/docs/Web/API/Headers +when not defined(js) and not defined(nimdoc): + {.fatal: "Module jsheaders is designed to be used with the JavaScript backend.".} + +type Headers* = ref object ## HTTP Headers + +func newHeaders*(): Headers {.importjs: "new Headers()".} + ## https://developer.mozilla.org/en-US/docs/Web/API/Headers + +func append*(this: Headers; key: cstring; value: cstring) {.importjs: "#.append(#, #)".} + ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/append + +func delete*(this: Headers; key: cstring) {.importjs: "#.delete(#)".} + ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/delete + +func get*(this: Headers; key: cstring): cstring {.importjs: "#.get(#)".} + ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/get + +func has*(this: Headers; key: cstring): bool {.importjs: "#.has(#)".} + ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/has + +func set*(this: Headers; key: cstring; value: cstring) {.importjs: "#.set(#, #)".} + ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/set + +func keys*(this: Headers): seq[cstring] {.importjs: "Array.from(#.keys())".} + ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/keys + +func values*(this: Headers): seq[cstring] {.importjs: "Array.from(#.values())".} + ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/values + +func entries*(this: Headers): seq[array[2, cstring]] {.importjs: "Array.from(#.entries())".} + ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/entries + + +runnableExamples: + if defined(nimJsHeadersTests): + + block: + var header = newHeaders() + header.append(r"key", r"value") + doAssert header.has(r"key") + doAssert header.keys() == @["key".cstring] + doAssert header.values() == @["value".cstring] + doAssert header.get(r"key") == "value".cstring + header.set(r"other", r"another") + doAssert header.get(r"other") == "another".cstring + doAssert header.entries() == @[["key".cstring, "value"], ["other".cstring, "another"]] + header.delete(r"other") From 5e2f92659567c010e8bd2c87d7b64afca57032da Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Sat, 12 Dec 2020 20:55:03 -0300 Subject: [PATCH 24/99] Headers really is a thing for itself --- lib/js/jsfetch.nim | 47 +++------------------------------------------- 1 file changed, 3 insertions(+), 44 deletions(-) diff --git a/lib/js/jsfetch.nim b/lib/js/jsfetch.nim index c8aeedd4e8e0..aa85e96b5586 100644 --- a/lib/js/jsfetch.nim +++ b/lib/js/jsfetch.nim @@ -1,4 +1,5 @@ ## - Fetch for the JavaScript target: https://developer.mozilla.org/docs/Web/API/Fetch_API +import jsheaders from httpcore import HttpMethod export HttpMethod @@ -40,8 +41,6 @@ type frpOriginWhenCrossOrigin = "origin-when-cross-origin".cstring frpUnsafeUrl = "unsafe-url".cstring - Headers* = ref object ## https://developer.mozilla.org/en-US/docs/Web/API/Headers - Response* = ref object ## https://developer.mozilla.org/en-US/docs/Web/API/Response myBodyUsed, ok, redirected: bool tipe {.importjs: "type".}: cstring @@ -50,33 +49,6 @@ type headers: Headers -func newHeaders*(): Headers {.importjs: "new Headers()".} - ## https://developer.mozilla.org/en-US/docs/Web/API/Headers - -func append*(this: Headers; key: cstring; value: cstring) {.importjs: "#.append(#, #)".} - ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/append - -func delete*(this: Headers; key: cstring) {.importjs: "#.delete(#)".} - ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/delete - -func get*(this: Headers; key: cstring): cstring {.importjs: "#.get(#)".} - ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/get - -func has*(this: Headers; key: cstring): bool {.importjs: "#.has(#)".} - ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/has - -func set*(this: Headers; key: cstring; value: cstring) {.importjs: "#.set(#, #)".} - ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/set - -func keys*(this: Headers): seq[cstring] {.importjs: "Array.from(#.keys())".} - ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/keys - -func values*(this: Headers): seq[cstring] {.importjs: "Array.from(#.values())".} - ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/values - -func entries*(this: Headers): seq[array[2, cstring]] {.importjs: "Array.from(#.entries())".} - ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/entries - template fetchMethodToCstring(metod: HttpMethod): cstring = ## Template that takes an `HttpMethod` and returns an *Uppercase* `cstring`, ## but *only* for the HTTP Methods that are supported by the fetch API. @@ -120,22 +92,9 @@ func fetch*(url: cstring, options: FetchOptions): Response {.importjs: "await fe ## `fetch()` API that takes a `FetchOptions`, returns a `Response`. -runnableExamples: - if defined(nimJsFetchTests): - - block: - doAssert hasFetch() - var header = newHeaders() - header.append(r"key", r"value") - doAssert header.has(r"key") - doAssert header.keys() == @["key".cstring] - doAssert header.values() == @["value".cstring] - doAssert header.get(r"key") == "value".cstring - header.set(r"other", r"another") - doAssert header.get(r"other") == "another".cstring - doAssert header.entries() == @[["key".cstring, "value"], ["other".cstring, "another"]] - header.delete(r"other") +runnableExamples: + when defined(nimJsFetchTests): block: let options = unsafeNewFetchOptions( metod = "POST".cstring, From b12a6c2c8802f1ee674752c3fae723eccb251b6d Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Sat, 12 Dec 2020 21:14:17 -0300 Subject: [PATCH 25/99] Headers really is a thing for itself --- lib/js/jsheaders.nim | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/js/jsheaders.nim b/lib/js/jsheaders.nim index 1da9b791ae49..4b5cfbe30c60 100644 --- a/lib/js/jsheaders.nim +++ b/lib/js/jsheaders.nim @@ -7,6 +7,14 @@ type Headers* = ref object ## HTTP Headers func newHeaders*(): Headers {.importjs: "new Headers()".} ## https://developer.mozilla.org/en-US/docs/Web/API/Headers +func newHeaders*(keyValuePairs: openArray[array[2, cstring]]): Headers {.importjs: """ +(() => { + const header = new Headers(); + #.forEach((item) => header.append(item[0], item[1])); + return header; +})();""".} + ## Same as `newHeaders` but initializes `Headers` with `keyValuePairs`. + func append*(this: Headers; key: cstring; value: cstring) {.importjs: "#.append(#, #)".} ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/append From 2d7e9461520b3311500b416d32b6ed7eaac203b3 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Sat, 12 Dec 2020 21:57:36 -0300 Subject: [PATCH 26/99] Headers really is a thing for itself --- lib/js/jsheaders.nim | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/js/jsheaders.nim b/lib/js/jsheaders.nim index 4b5cfbe30c60..dec6e75c6d6e 100644 --- a/lib/js/jsheaders.nim +++ b/lib/js/jsheaders.nim @@ -12,7 +12,7 @@ func newHeaders*(keyValuePairs: openArray[array[2, cstring]]): Headers {.importj const header = new Headers(); #.forEach((item) => header.append(item[0], item[1])); return header; -})();""".} +})()""".} ## Same as `newHeaders` but initializes `Headers` with `keyValuePairs`. func append*(this: Headers; key: cstring; value: cstring) {.importjs: "#.append(#, #)".} @@ -39,6 +39,9 @@ func values*(this: Headers): seq[cstring] {.importjs: "Array.from(#.values())".} func entries*(this: Headers): seq[array[2, cstring]] {.importjs: "Array.from(#.entries())".} ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/entries +func clear*(this: Headers) {.importjs: """Array.from(#.keys()).forEach((key) => #.delete(key))""".} + ## Convenience func to delete all items from `Headers`. + runnableExamples: if defined(nimJsHeadersTests): From 030a9400f2e15f376efeefcd4a10205cbb097250 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Mon, 18 Jan 2021 10:39:19 -0300 Subject: [PATCH 27/99] This is not dead yet --- lib/js/jsfetch.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/js/jsfetch.nim b/lib/js/jsfetch.nim index aa85e96b5586..2cf1ca7d5751 100644 --- a/lib/js/jsfetch.nim +++ b/lib/js/jsfetch.nim @@ -3,7 +3,7 @@ import jsheaders from httpcore import HttpMethod export HttpMethod -when not defined(js) and not defined(nimdoc): +when not defined(js): {.fatal: "Module jsfetch is designed to be used with the JavaScript backend.".} type From 20e61d0eec5fa8eeae6670467ae86e7becbbeb13 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Mon, 18 Jan 2021 10:55:38 -0300 Subject: [PATCH 28/99] Fix --- lib/js/jsfetch.nim | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/lib/js/jsfetch.nim b/lib/js/jsfetch.nim index 2cf1ca7d5751..ab0ba33b8611 100644 --- a/lib/js/jsfetch.nim +++ b/lib/js/jsfetch.nim @@ -94,19 +94,18 @@ func fetch*(url: cstring, options: FetchOptions): Response {.importjs: "await fe runnableExamples: - when defined(nimJsFetchTests): - block: - let options = unsafeNewFetchOptions( - metod = "POST".cstring, - body = """{"key": "value"}""".cstring, - mode = "no-cors".cstring, - credentials = "omit".cstring, - cache = "no-cache".cstring, - referrerPolicy = "no-referrer".cstring, - keepalive = false, - redirect = "follow".cstring, - referrer = "client".cstring, - integrity = "".cstring - ) - doAssert options is FetchOptions - echo fetchToCstring(r"http://httpbin.org/post", options) + if defined(nimJsFetchTests): + let options = unsafeNewFetchOptions( + metod = "POST".cstring, + body = """{"key": "value"}""".cstring, + mode = "no-cors".cstring, + credentials = "omit".cstring, + cache = "no-cache".cstring, + referrerPolicy = "no-referrer".cstring, + keepalive = false, + redirect = "follow".cstring, + referrer = "client".cstring, + integrity = "".cstring + ) + doAssert options is FetchOptions + echo fetchToCstring(r"http://httpbin.org/post", options) From 027db75f3f7645f2a5201afb6c136262c68db06b Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Mon, 18 Jan 2021 10:57:41 -0300 Subject: [PATCH 29/99] Fix --- lib/js/jsfetch.nim | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/lib/js/jsfetch.nim b/lib/js/jsfetch.nim index ab0ba33b8611..a3ef976c2deb 100644 --- a/lib/js/jsfetch.nim +++ b/lib/js/jsfetch.nim @@ -95,17 +95,20 @@ func fetch*(url: cstring, options: FetchOptions): Response {.importjs: "await fe runnableExamples: if defined(nimJsFetchTests): - let options = unsafeNewFetchOptions( - metod = "POST".cstring, - body = """{"key": "value"}""".cstring, - mode = "no-cors".cstring, - credentials = "omit".cstring, - cache = "no-cache".cstring, - referrerPolicy = "no-referrer".cstring, - keepalive = false, - redirect = "follow".cstring, - referrer = "client".cstring, - integrity = "".cstring - ) - doAssert options is FetchOptions - echo fetchToCstring(r"http://httpbin.org/post", options) + proc example() = + let options = unsafeNewFetchOptions( + metod = "POST".cstring, + body = """{"key": "value"}""".cstring, + mode = "no-cors".cstring, + credentials = "omit".cstring, + cache = "no-cache".cstring, + referrerPolicy = "no-referrer".cstring, + keepalive = false, + redirect = "follow".cstring, + referrer = "client".cstring, + integrity = "".cstring + ) + doAssert options is FetchOptions + echo fetchToCstring(r"http://httpbin.org/post", options) + + example() From fab7190761bb01f99ee49ba0928d2201c3c1eb3c Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Mon, 18 Jan 2021 11:00:05 -0300 Subject: [PATCH 30/99] Fix --- lib/js/jsfetch.nim | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/js/jsfetch.nim b/lib/js/jsfetch.nim index a3ef976c2deb..d409e90eab3c 100644 --- a/lib/js/jsfetch.nim +++ b/lib/js/jsfetch.nim @@ -92,7 +92,6 @@ func fetch*(url: cstring, options: FetchOptions): Response {.importjs: "await fe ## `fetch()` API that takes a `FetchOptions`, returns a `Response`. - runnableExamples: if defined(nimJsFetchTests): proc example() = @@ -109,6 +108,6 @@ runnableExamples: integrity = "".cstring ) doAssert options is FetchOptions - echo fetchToCstring(r"http://httpbin.org/post", options) + echo fetchToCstring("http://httpbin.org/post".cstring, options) example() From fd104ffab9ea5041523542e4cee46fdfc414bfb6 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Mon, 18 Jan 2021 12:04:10 -0300 Subject: [PATCH 31/99] Fix --- lib/js/jsfetch.nim | 65 +++++++++++++++++++++++++++++++++------------- 1 file changed, 47 insertions(+), 18 deletions(-) diff --git a/lib/js/jsfetch.nim b/lib/js/jsfetch.nim index d409e90eab3c..34c0ac8e3c9a 100644 --- a/lib/js/jsfetch.nim +++ b/lib/js/jsfetch.nim @@ -1,16 +1,15 @@ ## - Fetch for the JavaScript target: https://developer.mozilla.org/docs/Web/API/Fetch_API -import jsheaders -from httpcore import HttpMethod -export HttpMethod - when not defined(js): {.fatal: "Module jsfetch is designed to be used with the JavaScript backend.".} +import jsheaders +from httpcore import HttpMethod + type FetchOptions* = ref object ## Options for Fetch API. - keepalive: bool - metod {.importjs: "method".}: cstring - body, integrity, referrer, mode, credentials, cache, redirect, referrerPolicy: cstring + keepalive*: bool + metod* {.importjs: "method".}: cstring + body*, integrity*, referrer*, mode*, credentials*, cache*, redirect*, referrerPolicy*: cstring FetchModes* = enum ## JavaScript Fetch API mode options. fmCors = "cors".cstring @@ -79,24 +78,25 @@ func newfetchOptions*(metod: HttpMethod, body: cstring, credentials: $credentials, cache: $cache, referrerPolicy: $referrerPolicy, keepalive: keepalive, redirect: $redirect , referrer: referrer, integrity: integrity) -func fetchToCstring*(url: cstring): cstring {.importjs: "await fetch(#).then(response => response.text()).then(text => text)".} +func fetchToCstring*(url: cstring): cstring {.importjs: "(await fetch(#).then(response => response.text()).then(text => text))".} ## Convenience func for `fetch()` API that returns a `cstring` directly. -func fetchToCstring*(url: cstring, options: FetchOptions): cstring {.importjs: "await fetch(#, #).then(response => response.text()).then(text => text)".} +func fetchToCstring*(url: cstring, options: FetchOptions): cstring {.importjs: "(await fetch(#, #).then(response => response.text()).then(text => text))".} ## Convenience func for `fetch()` API that returns a `cstring` directly. -func fetch*(url: cstring): Response {.importjs: "await fetch(#).then(response => response)".} +func fetch*(url: cstring): Response {.importjs: "(await fetch(#).then(response => response))".} ## `fetch()` API, simple `GET` only, returns a `Response`. -func fetch*(url: cstring, options: FetchOptions): Response {.importjs: "await fetch(#, #).then(response => response)".} +func fetch*(url: cstring, options: FetchOptions): Response {.importjs: "(await fetch(#, #).then(response => response))".} ## `fetch()` API that takes a `FetchOptions`, returns a `Response`. runnableExamples: + import httpcore if defined(nimJsFetchTests): - proc example() = - let options = unsafeNewFetchOptions( - metod = "POST".cstring, + block: + let options0: FetchOptions = unsafeNewFetchOptions( + metod = "POST".cstring, body = """{"key": "value"}""".cstring, mode = "no-cors".cstring, credentials = "omit".cstring, @@ -107,7 +107,36 @@ runnableExamples: referrer = "client".cstring, integrity = "".cstring ) - doAssert options is FetchOptions - echo fetchToCstring("http://httpbin.org/post".cstring, options) - - example() + doAssert options0.keepalive == false + doAssert options0.metod == "POST".cstring + doAssert options0.body == """{"key": "value"}""".cstring + doAssert options0.mode == "no-cors".cstring + doAssert options0.credentials == "omit".cstring + doAssert options0.cache == "no-cache".cstring + doAssert options0.referrerPolicy == "no-referrer".cstring + doAssert options0.redirect == "follow".cstring + doAssert options0.referrer == "client".cstring + doAssert options0.integrity == "".cstring + block: + let options1: FetchOptions = newFetchOptions( + metod = HttpPost, + body = """{"key": "value"}""".cstring, + mode = fmNoCors, + credentials = fcOmit, + cache = fchNoCache, + referrerPolicy = frpNoReferrer, + keepalive = false, + redirect = frFollow, + referrer = "client".cstring, + integrity = "".cstring + ) + doAssert options1.keepalive == false + doAssert options1.metod == $HttpPost + doAssert options1.body == """{"key": "value"}""".cstring + doAssert options1.mode == $fmNoCors + doAssert options1.credentials == $fcOmit + doAssert options1.cache == $fchNoCache + doAssert options1.referrerPolicy == $frpNoReferrer + doAssert options1.redirect == $frFollow + doAssert options1.referrer == "client".cstring + doAssert options1.integrity == "".cstring From 6777e2202482fbcfc66978f1eda67555d511ec3a Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Mon, 18 Jan 2021 13:33:38 -0300 Subject: [PATCH 32/99] Fix --- lib/js/jsfetch.nim | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/lib/js/jsfetch.nim b/lib/js/jsfetch.nim index 34c0ac8e3c9a..d4aa13a833b7 100644 --- a/lib/js/jsfetch.nim +++ b/lib/js/jsfetch.nim @@ -3,6 +3,7 @@ when not defined(js): {.fatal: "Module jsfetch is designed to be used with the JavaScript backend.".} import jsheaders +import asyncjs from httpcore import HttpMethod type @@ -74,20 +75,20 @@ func newfetchOptions*(metod: HttpMethod, body: cstring, mode: FetchModes, credentials: FetchCredentials, cache: FetchCaches, referrerPolicy: FetchReferrerPolicies, keepalive: bool, redirect = frFollow, referrer = "client".cstring, integrity = "".cstring): FetchOptions = ## Constructor for `FetchOptions`. - result = FetchOptions(metod: fetchMethodTocstring(metod), body: body, mode: $mode, + result = FetchOptions(metod: fetchMethodToCstring(metod), body: body, mode: $mode, credentials: $credentials, cache: $cache, referrerPolicy: $referrerPolicy, keepalive: keepalive, redirect: $redirect , referrer: referrer, integrity: integrity) -func fetchToCstring*(url: cstring): cstring {.importjs: "(await fetch(#).then(response => response.text()).then(text => text))".} +func fetchToCstring*(url: cstring): Future[cstring] {.importjs: "fetch(#).then(response => response.text()).then(text => text)".} ## Convenience func for `fetch()` API that returns a `cstring` directly. -func fetchToCstring*(url: cstring, options: FetchOptions): cstring {.importjs: "(await fetch(#, #).then(response => response.text()).then(text => text))".} +func fetchToCstring*(url: cstring, options: FetchOptions): Future[cstring] {.importjs: "fetch(#, #).then(response => response.text()).then(text => text)".} ## Convenience func for `fetch()` API that returns a `cstring` directly. -func fetch*(url: cstring): Response {.importjs: "(await fetch(#).then(response => response))".} +func fetch*(url: cstring): Future[Response] {.importjs: "fetch(#).then(response => response)".} ## `fetch()` API, simple `GET` only, returns a `Response`. -func fetch*(url: cstring, options: FetchOptions): Response {.importjs: "(await fetch(#, #).then(response => response))".} +func fetch*(url: cstring, options: FetchOptions): Future[Response] {.importjs: "(await fetch(#, #).then(response => response))".} ## `fetch()` API that takes a `FetchOptions`, returns a `Response`. From 8aad4f2c576a90bd7c5bfe39743a828ab4f957af Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Tue, 19 Jan 2021 21:20:36 -0300 Subject: [PATCH 33/99] Clean out --- lib/js/jsfetch.nim | 3 --- 1 file changed, 3 deletions(-) diff --git a/lib/js/jsfetch.nim b/lib/js/jsfetch.nim index d4aa13a833b7..9d1be6c1b2c0 100644 --- a/lib/js/jsfetch.nim +++ b/lib/js/jsfetch.nim @@ -63,9 +63,6 @@ template fetchMethodToCstring(metod: HttpMethod): cstring = of HttpPatch: "PATCH".cstring else: "GET".cstring -func hasFetch*(): bool {.importjs: "(() => { return !!window.fetch })()".} - ## Convenience func to detect Fetch API support, returns `true` if Fetch is supported. - func unsafeNewFetchOptions*(metod, body, mode, credentials, cache, referrerPolicy: cstring, keepalive: bool, redirect = "follow".cstring, referrer = "client".cstring, integrity = "".cstring): FetchOptions {.importjs: "{method: #, body: #, mode: #, credentials: #, cache: #, referrerPolicy: #, keepalive: #, redirect: #, referrer: #, integrity: #}".} From c3d30abf79f97a5430e14d445caca7a7a8469579 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Tue, 19 Jan 2021 21:43:09 -0300 Subject: [PATCH 34/99] Clean out --- lib/js/jsfetch.nim | 3 +-- lib/js/jsheaders.nim | 62 +++++++++++++++++++------------------------- 2 files changed, 28 insertions(+), 37 deletions(-) diff --git a/lib/js/jsfetch.nim b/lib/js/jsfetch.nim index 9d1be6c1b2c0..0bbf7833b603 100644 --- a/lib/js/jsfetch.nim +++ b/lib/js/jsfetch.nim @@ -2,8 +2,7 @@ when not defined(js): {.fatal: "Module jsfetch is designed to be used with the JavaScript backend.".} -import jsheaders -import asyncjs +import asyncjs, jsheaders from httpcore import HttpMethod type diff --git a/lib/js/jsheaders.nim b/lib/js/jsheaders.nim index dec6e75c6d6e..97045bab4009 100644 --- a/lib/js/jsheaders.nim +++ b/lib/js/jsheaders.nim @@ -1,59 +1,51 @@ ## - HTTP Headers for the JavaScript target: https://developer.mozilla.org/en-US/docs/Web/API/Headers -when not defined(js) and not defined(nimdoc): +when not defined(js): {.fatal: "Module jsheaders is designed to be used with the JavaScript backend.".} -type Headers* = ref object ## HTTP Headers +type Headers* = ref object of JsRoot ## HTTP Headers for the JavaScript target. func newHeaders*(): Headers {.importjs: "new Headers()".} ## https://developer.mozilla.org/en-US/docs/Web/API/Headers -func newHeaders*(keyValuePairs: openArray[array[2, cstring]]): Headers {.importjs: """ -(() => { - const header = new Headers(); - #.forEach((item) => header.append(item[0], item[1])); - return header; -})()""".} - ## Same as `newHeaders` but initializes `Headers` with `keyValuePairs`. - -func append*(this: Headers; key: cstring; value: cstring) {.importjs: "#.append(#, #)".} +func add*(this: Headers; key: cstring; value: cstring) {.importjs: "#.append(#, #)".} ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/append -func delete*(this: Headers; key: cstring) {.importjs: "#.delete(#)".} +func delete*(this: Headers; key: cstring) {.importjs: "#.$1(#)".} ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/delete -func get*(this: Headers; key: cstring): cstring {.importjs: "#.get(#)".} - ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/get - -func has*(this: Headers; key: cstring): bool {.importjs: "#.has(#)".} +func hasKey*(this: Headers; key: cstring): bool {.importjs: "#.has(#)".} ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/has -func set*(this: Headers; key: cstring; value: cstring) {.importjs: "#.set(#, #)".} - ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/set - -func keys*(this: Headers): seq[cstring] {.importjs: "Array.from(#.keys())".} +func keys*(this: Headers): seq[cstring] {.importjs: "Array.from(#.$1())".} ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/keys -func values*(this: Headers): seq[cstring] {.importjs: "Array.from(#.values())".} +func values*(this: Headers): seq[cstring] {.importjs: "Array.from(#.$1())".} ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/values -func entries*(this: Headers): seq[array[2, cstring]] {.importjs: "Array.from(#.entries())".} +func entries*(this: Headers): seq[array[2, cstring]] {.importjs: "Array.from(#.$1())".} ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/entries -func clear*(this: Headers) {.importjs: """Array.from(#.keys()).forEach((key) => #.delete(key))""".} +func `[]`*(this: Headers; key: cstring): cstring {.importjs: "#.get(#)".} + ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/get + +func `[]=`*(this: Headers; key: cstring; value: cstring) {.importjs: "#.set(#, #)".} + ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/set + +func clear*(this: Headers) {.importjs: + "(() => { const header = #; Array.from(header.keys()).forEach((key) => header.delete(key)) })()".} ## Convenience func to delete all items from `Headers`. runnableExamples: if defined(nimJsHeadersTests): - - block: - var header = newHeaders() - header.append(r"key", r"value") - doAssert header.has(r"key") - doAssert header.keys() == @["key".cstring] - doAssert header.values() == @["value".cstring] - doAssert header.get(r"key") == "value".cstring - header.set(r"other", r"another") - doAssert header.get(r"other") == "another".cstring - doAssert header.entries() == @[["key".cstring, "value"], ["other".cstring, "another"]] - header.delete(r"other") + let header = newHeaders() + header.add("key", "value") + doAssert header.hasKey("key") + doAssert header.keys() == @["key".cstring] + doAssert header.values() == @["value".cstring] + doAssert header["key"] == "value".cstring + header["other"] = "another".cstring + doAssert header["other"] == "another".cstring + doAssert header.entries() == @[["key".cstring, "value"], ["other".cstring, "another"]] + header.delete("other") + doAssert header.entries() == @[] From 833f0c1e1f3825b2ac07ab63bf0b1b2eff0913d4 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Tue, 19 Jan 2021 23:31:13 -0300 Subject: [PATCH 35/99] move it --- lib/{js => std}/jsfetch.nim | 0 lib/{js => std}/jsheaders.nim | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename lib/{js => std}/jsfetch.nim (100%) rename lib/{js => std}/jsheaders.nim (100%) diff --git a/lib/js/jsfetch.nim b/lib/std/jsfetch.nim similarity index 100% rename from lib/js/jsfetch.nim rename to lib/std/jsfetch.nim diff --git a/lib/js/jsheaders.nim b/lib/std/jsheaders.nim similarity index 100% rename from lib/js/jsheaders.nim rename to lib/std/jsheaders.nim From d6bda3b74c84a0c630c5e25b2d20e128df28a6ba Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Tue, 19 Jan 2021 23:40:33 -0300 Subject: [PATCH 36/99] move it --- tools/kochdocs.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/kochdocs.nim b/tools/kochdocs.nim index 6fa64c73b9b0..1098da72bd12 100644 --- a/tools/kochdocs.nim +++ b/tools/kochdocs.nim @@ -14,7 +14,7 @@ const webUploadOutput = "web/upload" var nimExe*: string -const allowList = ["jsbigints.nim"] +const allowList = ["jsbigints.nim", "jsheaders.nim", "jsfetch.nim"] template isJsOnly(file: string): bool = file.isRelativeTo("lib/js") or From 8564714a8ed33b55954797c32feaf9973412c86e Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Sun, 24 Jan 2021 21:46:50 -0300 Subject: [PATCH 37/99] Update lib/std/jsfetch.nim Co-authored-by: Timothee Cour --- lib/std/jsfetch.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/std/jsfetch.nim b/lib/std/jsfetch.nim index 0bbf7833b603..4e86e961e8da 100644 --- a/lib/std/jsfetch.nim +++ b/lib/std/jsfetch.nim @@ -42,7 +42,7 @@ type Response* = ref object ## https://developer.mozilla.org/en-US/docs/Web/API/Response myBodyUsed, ok, redirected: bool - tipe {.importjs: "type".}: cstring + typ {.importjs: "type".}: cstring url, statusText: cstring status: cushort headers: Headers From 316cfa91044ab0387ef510a4aa784f30a339712d Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Sun, 24 Jan 2021 22:26:59 -0300 Subject: [PATCH 38/99] Update lib/std/jsfetch.nim Co-authored-by: Timothee Cour --- lib/std/jsfetch.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/std/jsfetch.nim b/lib/std/jsfetch.nim index 4e86e961e8da..f168b8a22ce6 100644 --- a/lib/std/jsfetch.nim +++ b/lib/std/jsfetch.nim @@ -48,7 +48,7 @@ type headers: Headers -template fetchMethodToCstring(metod: HttpMethod): cstring = +proc fetchMethodToCstring(metod: HttpMethod): cstring = ## Template that takes an `HttpMethod` and returns an *Uppercase* `cstring`, ## but *only* for the HTTP Methods that are supported by the fetch API. ## High performance and minimal code compared to just `$(HttpMethod)`. From 8be32d9fa23365863fd0856c75feba59af6d9ebb Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Mon, 25 Jan 2021 10:11:31 -0300 Subject: [PATCH 39/99] Improvements and fixes --- lib/std/jsheaders.nim | 50 ++++++++++++++++++++++++++++++++----------- 1 file changed, 38 insertions(+), 12 deletions(-) diff --git a/lib/std/jsheaders.nim b/lib/std/jsheaders.nim index 97045bab4009..88d020a9dc96 100644 --- a/lib/std/jsheaders.nim +++ b/lib/std/jsheaders.nim @@ -8,9 +8,11 @@ func newHeaders*(): Headers {.importjs: "new Headers()".} ## https://developer.mozilla.org/en-US/docs/Web/API/Headers func add*(this: Headers; key: cstring; value: cstring) {.importjs: "#.append(#, #)".} + ## Allows duplicated keys. ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/append func delete*(this: Headers; key: cstring) {.importjs: "#.$1(#)".} + ## Delete *all* items with `key` from the headers, including duplicated keys. ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/delete func hasKey*(this: Headers; key: cstring): bool {.importjs: "#.has(#)".} @@ -22,30 +24,54 @@ func keys*(this: Headers): seq[cstring] {.importjs: "Array.from(#.$1())".} func values*(this: Headers): seq[cstring] {.importjs: "Array.from(#.$1())".} ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/values -func entries*(this: Headers): seq[array[2, cstring]] {.importjs: "Array.from(#.$1())".} +func entries*(this: Headers): seq[tuple[key, value: cstring]] {.importjs: "Array.from(#.$1())".} ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/entries func `[]`*(this: Headers; key: cstring): cstring {.importjs: "#.get(#)".} + ## Get *all* items with `key` from the headers, including duplicated values. ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/get func `[]=`*(this: Headers; key: cstring; value: cstring) {.importjs: "#.set(#, #)".} + ## Do *not* allow duplicated keys, overwrites duplicated keys. ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/set func clear*(this: Headers) {.importjs: "(() => { const header = #; Array.from(header.keys()).forEach((key) => header.delete(key)) })()".} ## Convenience func to delete all items from `Headers`. +func toCstring*(this: Headers): cstring {.importjs: "JSON.stringify(Array.from(#.entries()))".} + ## Returns a `cstring` representation of `Headers`. + +func `$`*(this: Headers): string = $this.toCstring + runnableExamples: if defined(nimJsHeadersTests): - let header = newHeaders() - header.add("key", "value") - doAssert header.hasKey("key") - doAssert header.keys() == @["key".cstring] - doAssert header.values() == @["value".cstring] - doAssert header["key"] == "value".cstring - header["other"] = "another".cstring - doAssert header["other"] == "another".cstring - doAssert header.entries() == @[["key".cstring, "value"], ["other".cstring, "another"]] - header.delete("other") - doAssert header.entries() == @[] + block: + let header = newHeaders() + header.add("key", "value") + doAssert header.hasKey("key") + doAssert header.keys() == @["key".cstring] + doAssert header.values() == @["value".cstring] + doAssert header["key"] == "value".cstring + header["other"] = "another".cstring + doAssert header["other"] == "another".cstring + doAssert header.entries() == @[["key".cstring, "value"], ["other".cstring, "another"]] + doAssert header.toCstring() == """[["key","value"],["other","another"]]""".cstring + header.delete("other") + header.clear() + doAssert header.entries() == @[] + block: + let header = newHeaders() + header.add("key", "a") + header.add("key", "b") ## Duplicated. + header.add("key", "c") ## Duplicated. + doAssert header["key"] == "a, b, c".cstring + header["key"] = "value".cstring + doAssert header["key"] == "value".cstring + block: + let header = newHeaders() + header["key"] = "a" + header["key"] = "b" ## Duplicated. + header["key"] = "c" ## Duplicated. + doAssert header["key"] == "c".cstring From 9f842ebee677fd3e835825b0320ab018b9b5d299 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Mon, 25 Jan 2021 10:26:55 -0300 Subject: [PATCH 40/99] Improvements and fixes --- lib/std/jsheaders.nim | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/std/jsheaders.nim b/lib/std/jsheaders.nim index 88d020a9dc96..01074e5ab6ac 100644 --- a/lib/std/jsheaders.nim +++ b/lib/std/jsheaders.nim @@ -56,7 +56,7 @@ runnableExamples: doAssert header["key"] == "value".cstring header["other"] = "another".cstring doAssert header["other"] == "another".cstring - doAssert header.entries() == @[["key".cstring, "value"], ["other".cstring, "another"]] + doAssert header.entries() == @[("key".cstring, "value".cstring), ("other".cstring, "another".cstring)] doAssert header.toCstring() == """[["key","value"],["other","another"]]""".cstring header.delete("other") header.clear() @@ -75,3 +75,4 @@ runnableExamples: header["key"] = "b" ## Duplicated. header["key"] = "c" ## Duplicated. doAssert header["key"] == "c".cstring + From aa3af123261dc31fea087def6f66a43dfcf13cad Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Mon, 25 Jan 2021 10:28:22 -0300 Subject: [PATCH 41/99] Improvements and fixes --- lib/std/jsfetch.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/std/jsfetch.nim b/lib/std/jsfetch.nim index f168b8a22ce6..323e3a281544 100644 --- a/lib/std/jsfetch.nim +++ b/lib/std/jsfetch.nim @@ -44,7 +44,7 @@ type myBodyUsed, ok, redirected: bool typ {.importjs: "type".}: cstring url, statusText: cstring - status: cushort + status: cint headers: Headers From 2a9841bb0fb0d019d94d3471a6c90f5830bf5dfc Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Mon, 25 Jan 2021 10:32:40 -0300 Subject: [PATCH 42/99] doc --- lib/std/jsfetch.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/std/jsfetch.nim b/lib/std/jsfetch.nim index 323e3a281544..28b83c6c4472 100644 --- a/lib/std/jsfetch.nim +++ b/lib/std/jsfetch.nim @@ -49,7 +49,7 @@ type proc fetchMethodToCstring(metod: HttpMethod): cstring = - ## Template that takes an `HttpMethod` and returns an *Uppercase* `cstring`, + ## proc that takes an `HttpMethod` and returns an *Uppercase* `cstring`, ## but *only* for the HTTP Methods that are supported by the fetch API. ## High performance and minimal code compared to just `$(HttpMethod)`. assert metod notin {HttpTrace, HttpOptions, HttpConnect}, "HTTP Method not supported by Fetch API" From a2efb226c16e6d3f53522bc876ad8fb69005db79 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Mon, 25 Jan 2021 11:57:30 -0300 Subject: [PATCH 43/99] https://github.com/nim-lang/Nim/pull/12531#discussion_r563766815 --- lib/std/jsfetch.nim | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/lib/std/jsfetch.nim b/lib/std/jsfetch.nim index 28b83c6c4472..ca1cb971e76d 100644 --- a/lib/std/jsfetch.nim +++ b/lib/std/jsfetch.nim @@ -12,33 +12,33 @@ type body*, integrity*, referrer*, mode*, credentials*, cache*, redirect*, referrerPolicy*: cstring FetchModes* = enum ## JavaScript Fetch API mode options. - fmCors = "cors".cstring - fmNoCors = "no-cors".cstring - fmSameOrigin = "same-origin".cstring + fmCors = "cors". + fmNoCors = "no-cors" + fmSameOrigin = "same-origin" FetchCredentials* = enum ## JavaScript Fetch API Credential options. - fcInclude = "include".cstring - fcSameOrigin = "same-origin".cstring - fcOmit = "omit".cstring + fcInclude = "include" + fcSameOrigin = "same-origin" + fcOmit = "omit" FetchCaches* = enum ## https://developer.mozilla.org/docs/Web/API/Request/cache - fchDefault = "default".cstring - fchNoStore = "no-store".cstring - fchReload = "reload".cstring - fchNoCache = "no-cache".cstring - fchForceCache = "force-cache".cstring + fchDefault = "default" + fchNoStore = "no-store" + fchReload = "reload" + fchNoCache = "no-cache" + fchForceCache = "force-cache" FetchRedirects* = enum ## JavaScript Fetch API Redirects options. - frFollow = "follow".cstring - frError = "error".cstring - frManual = "manual".cstring + frFollow = "follow" + frError = "error" + frManual = "manual" FetchReferrerPolicies* = enum ## JavaScript Fetch API Referrer Policy options. - frpNoReferrer = "no-referrer".cstring - frpNoReferrerWhenDowngrade = "no-referrer-when-downgrade".cstring - frpOrigin = "origin".cstring - frpOriginWhenCrossOrigin = "origin-when-cross-origin".cstring - frpUnsafeUrl = "unsafe-url".cstring + frpNoReferrer = "no-referrer" + frpNoReferrerWhenDowngrade = "no-referrer-when-downgrade" + frpOrigin = "origin" + frpOriginWhenCrossOrigin = "origin-when-cross-origin" + frpUnsafeUrl = "unsafe-url" Response* = ref object ## https://developer.mozilla.org/en-US/docs/Web/API/Response myBodyUsed, ok, redirected: bool From fd5c57f3cfdd2c902dfbb6a53f60f0399ee68570 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Mon, 25 Jan 2021 12:05:18 -0300 Subject: [PATCH 44/99] https://github.com/nim-lang/Nim/pull/12531#discussion_r563766815 --- lib/std/jsfetch.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/std/jsfetch.nim b/lib/std/jsfetch.nim index ca1cb971e76d..208b4828915a 100644 --- a/lib/std/jsfetch.nim +++ b/lib/std/jsfetch.nim @@ -12,7 +12,7 @@ type body*, integrity*, referrer*, mode*, credentials*, cache*, redirect*, referrerPolicy*: cstring FetchModes* = enum ## JavaScript Fetch API mode options. - fmCors = "cors". + fmCors = "cors" fmNoCors = "no-cors" fmSameOrigin = "same-origin" From 7416b9fefff6fd79b96c94f319dbace23f7e3580 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Mon, 25 Jan 2021 12:34:22 -0300 Subject: [PATCH 45/99] Dollars --- lib/std/jsfetch.nim | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/std/jsfetch.nim b/lib/std/jsfetch.nim index 208b4828915a..de041a0ea19c 100644 --- a/lib/std/jsfetch.nim +++ b/lib/std/jsfetch.nim @@ -87,6 +87,10 @@ func fetch*(url: cstring): Future[Response] {.importjs: "fetch(#).then(response func fetch*(url: cstring, options: FetchOptions): Future[Response] {.importjs: "(await fetch(#, #).then(response => response))".} ## `fetch()` API that takes a `FetchOptions`, returns a `Response`. +func toCstring*(this: FetchOptions or Response): cstring {.importjs: "JSON.stringify(#)".} + +func `$`*(this: FetchOptions or Response): string = $this.toCstring + runnableExamples: import httpcore From bc592eda9a23df74b3d50b078bd8f96eaf876329 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Mon, 25 Jan 2021 12:36:23 -0300 Subject: [PATCH 46/99] Dollars --- lib/std/jsfetch.nim | 2 +- lib/std/jsheaders.nim | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/std/jsfetch.nim b/lib/std/jsfetch.nim index de041a0ea19c..bf7fb3142e2b 100644 --- a/lib/std/jsfetch.nim +++ b/lib/std/jsfetch.nim @@ -89,7 +89,7 @@ func fetch*(url: cstring, options: FetchOptions): Future[Response] {.importjs: " func toCstring*(this: FetchOptions or Response): cstring {.importjs: "JSON.stringify(#)".} -func `$`*(this: FetchOptions or Response): string = $this.toCstring +func `$`*(this: FetchOptions or Response): string = $toCstring(this) runnableExamples: diff --git a/lib/std/jsheaders.nim b/lib/std/jsheaders.nim index 01074e5ab6ac..0b0b5ca948fd 100644 --- a/lib/std/jsheaders.nim +++ b/lib/std/jsheaders.nim @@ -42,7 +42,7 @@ func clear*(this: Headers) {.importjs: func toCstring*(this: Headers): cstring {.importjs: "JSON.stringify(Array.from(#.entries()))".} ## Returns a `cstring` representation of `Headers`. -func `$`*(this: Headers): string = $this.toCstring +func `$`*(this: Headers): string = $toCstring(this) runnableExamples: From 76cb084a55102c137c4f3a09846f60287f60216a Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Mon, 25 Jan 2021 23:41:14 -0300 Subject: [PATCH 47/99] Update lib/std/jsheaders.nim Co-authored-by: Timothee Cour --- lib/std/jsheaders.nim | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/std/jsheaders.nim b/lib/std/jsheaders.nim index 0b0b5ca948fd..4b151d477b6c 100644 --- a/lib/std/jsheaders.nim +++ b/lib/std/jsheaders.nim @@ -72,7 +72,5 @@ runnableExamples: block: let header = newHeaders() header["key"] = "a" - header["key"] = "b" ## Duplicated. - header["key"] = "c" ## Duplicated. - doAssert header["key"] == "c".cstring - + header["key"] = "b" ## Overwrites. + doAssert header["key"] == "b".cstring From 0f306a18470293fe3fb7f0c68b5825b197b41700 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Fri, 29 Jan 2021 17:00:52 -0300 Subject: [PATCH 48/99] https://github.com/nim-lang/Nim/pull/12531/files#r564156627 --- lib/std/jsheaders.nim | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/std/jsheaders.nim b/lib/std/jsheaders.nim index 0b0b5ca948fd..1da444604dbf 100644 --- a/lib/std/jsheaders.nim +++ b/lib/std/jsheaders.nim @@ -59,6 +59,7 @@ runnableExamples: doAssert header.entries() == @[("key".cstring, "value".cstring), ("other".cstring, "another".cstring)] doAssert header.toCstring() == """[["key","value"],["other","another"]]""".cstring header.delete("other") + doAssert header.entries() == @[("key".cstring, "value".cstring)] header.clear() doAssert header.entries() == @[] block: From 73ef1f58e352dfd059751bff4b4aeadad897649b Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Fri, 29 Jan 2021 17:33:03 -0300 Subject: [PATCH 49/99] https://github.com/nim-lang/Nim/pull/12531#discussion_r564160044 --- lib/std/jsfetch.nim | 43 ++++++++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/lib/std/jsfetch.nim b/lib/std/jsfetch.nim index bf7fb3142e2b..e45ec6dbacbe 100644 --- a/lib/std/jsfetch.nim +++ b/lib/std/jsfetch.nim @@ -48,20 +48,6 @@ type headers: Headers -proc fetchMethodToCstring(metod: HttpMethod): cstring = - ## proc that takes an `HttpMethod` and returns an *Uppercase* `cstring`, - ## but *only* for the HTTP Methods that are supported by the fetch API. - ## High performance and minimal code compared to just `$(HttpMethod)`. - assert metod notin {HttpTrace, HttpOptions, HttpConnect}, "HTTP Method not supported by Fetch API" - case metod - of HttpHead: "HEAD".cstring - of HttpGet: "GET".cstring - of HttpPost: "POST".cstring - of HttpPut: "PUT".cstring - of HttpDelete: "DELETE".cstring - of HttpPatch: "PATCH".cstring - else: "GET".cstring - func unsafeNewFetchOptions*(metod, body, mode, credentials, cache, referrerPolicy: cstring, keepalive: bool, redirect = "follow".cstring, referrer = "client".cstring, integrity = "".cstring): FetchOptions {.importjs: "{method: #, body: #, mode: #, credentials: #, cache: #, referrerPolicy: #, keepalive: #, redirect: #, referrer: #, integrity: #}".} @@ -71,9 +57,19 @@ func newfetchOptions*(metod: HttpMethod, body: cstring, mode: FetchModes, credentials: FetchCredentials, cache: FetchCaches, referrerPolicy: FetchReferrerPolicies, keepalive: bool, redirect = frFollow, referrer = "client".cstring, integrity = "".cstring): FetchOptions = ## Constructor for `FetchOptions`. - result = FetchOptions(metod: fetchMethodToCstring(metod), body: body, mode: $mode, - credentials: $credentials, cache: $cache, referrerPolicy: $referrerPolicy, - keepalive: keepalive, redirect: $redirect , referrer: referrer, integrity: integrity) + result = FetchOptions( + body: body, mode: $mode, credentials: $credentials, cache: $cache, referrerPolicy: $referrerPolicy, + keepalive: keepalive, redirect: $redirect, referrer: referrer, integrity: integrity, + metod: (case metod + of HttpHead: "HEAD".cstring + of HttpGet: "GET".cstring + of HttpPost: "POST".cstring + of HttpPut: "PUT".cstring + of HttpDelete: "DELETE".cstring + of HttpPatch: "PATCH".cstring + else: "GET".cstring + ) + ) func fetchToCstring*(url: cstring): Future[cstring] {.importjs: "fetch(#).then(response => response.text()).then(text => text)".} ## Convenience func for `fetch()` API that returns a `cstring` directly. @@ -95,6 +91,7 @@ func `$`*(this: FetchOptions or Response): string = $toCstring(this) runnableExamples: import httpcore if defined(nimJsFetchTests): + block: let options0: FetchOptions = unsafeNewFetchOptions( metod = "POST".cstring, @@ -118,6 +115,7 @@ runnableExamples: doAssert options0.redirect == "follow".cstring doAssert options0.referrer == "client".cstring doAssert options0.integrity == "".cstring + block: let options1: FetchOptions = newFetchOptions( metod = HttpPost, @@ -141,3 +139,14 @@ runnableExamples: doAssert options1.redirect == $frFollow doAssert options1.referrer == "client".cstring doAssert options1.integrity == "".cstring + + when not defined(nodejs): + proc doFetch(): Future[Response] {.async.} = + fetch "http:httpbin.org/get" + + proc example() {.async.} = + let response: Response = await doFetch() + doAssert response.ok + doAssert response.status == 200.cint + + waitFor example() From afed536ae76579ce939070b72bff091cb26132d5 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Fri, 29 Jan 2021 17:41:15 -0300 Subject: [PATCH 50/99] https://github.com/nim-lang/Nim/pull/12531#discussion_r564160044 --- lib/std/jsfetch.nim | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/std/jsfetch.nim b/lib/std/jsfetch.nim index e45ec6dbacbe..37b236e046ed 100644 --- a/lib/std/jsfetch.nim +++ b/lib/std/jsfetch.nim @@ -141,6 +141,8 @@ runnableExamples: doAssert options1.integrity == "".cstring when not defined(nodejs): + import asyncjs + proc doFetch(): Future[Response] {.async.} = fetch "http:httpbin.org/get" From 3d8cb6a219ff6a8b0cebf53e3a19e581ee72f433 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Fri, 29 Jan 2021 17:50:23 -0300 Subject: [PATCH 51/99] https://github.com/nim-lang/Nim/pull/12531#discussion_r564160044 --- lib/std/jsfetch.nim | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/std/jsfetch.nim b/lib/std/jsfetch.nim index 37b236e046ed..b10d71b85bcb 100644 --- a/lib/std/jsfetch.nim +++ b/lib/std/jsfetch.nim @@ -89,7 +89,7 @@ func `$`*(this: FetchOptions or Response): string = $toCstring(this) runnableExamples: - import httpcore + import httpcore, asyncjs if defined(nimJsFetchTests): block: @@ -141,8 +141,6 @@ runnableExamples: doAssert options1.integrity == "".cstring when not defined(nodejs): - import asyncjs - proc doFetch(): Future[Response] {.async.} = fetch "http:httpbin.org/get" From b0a6f77b979b192f717d0a1fe6e3ec3bac3b5bca Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Fri, 29 Jan 2021 17:58:23 -0300 Subject: [PATCH 52/99] https://github.com/nim-lang/Nim/pull/12531#discussion_r564160044 --- lib/std/jsfetch.nim | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/lib/std/jsfetch.nim b/lib/std/jsfetch.nim index b10d71b85bcb..eb03044c7b58 100644 --- a/lib/std/jsfetch.nim +++ b/lib/std/jsfetch.nim @@ -41,11 +41,11 @@ type frpUnsafeUrl = "unsafe-url" Response* = ref object ## https://developer.mozilla.org/en-US/docs/Web/API/Response - myBodyUsed, ok, redirected: bool - typ {.importjs: "type".}: cstring - url, statusText: cstring - status: cint - headers: Headers + myBodyUsed*, ok*, redirected*: bool + typ* {.importjs: "type".}: cstring + url*, statusText*: cstring + status*: cint + headers*: Headers func unsafeNewFetchOptions*(metod, body, mode, credentials, cache, referrerPolicy: cstring, @@ -134,7 +134,9 @@ runnableExamples: doAssert options1.body == """{"key": "value"}""".cstring doAssert options1.mode == $fmNoCors doAssert options1.credentials == $fcOmit - doAssert options1.cache == $fchNoCache + doAssert options1.cache == $fchNoCimport r"/home/runner/work/Nim/Nim/lib/std/nimcache/runnableExamples/jsfetch_examples1.nim" +6321 +ache doAssert options1.referrerPolicy == $frpNoReferrer doAssert options1.redirect == $frFollow doAssert options1.referrer == "client".cstring From fd7a95b4d9e2b7c90bf5a39256a4ee3d2d729977 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Fri, 29 Jan 2021 18:09:17 -0300 Subject: [PATCH 53/99] https://github.com/nim-lang/Nim/pull/12531#discussion_r564160044 --- lib/std/jsfetch.nim | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/std/jsfetch.nim b/lib/std/jsfetch.nim index eb03044c7b58..65fecfebe33e 100644 --- a/lib/std/jsfetch.nim +++ b/lib/std/jsfetch.nim @@ -134,9 +134,7 @@ runnableExamples: doAssert options1.body == """{"key": "value"}""".cstring doAssert options1.mode == $fmNoCors doAssert options1.credentials == $fcOmit - doAssert options1.cache == $fchNoCimport r"/home/runner/work/Nim/Nim/lib/std/nimcache/runnableExamples/jsfetch_examples1.nim" -6321 -ache + doAssert options1.cache == $fchNoCimport doAssert options1.referrerPolicy == $frpNoReferrer doAssert options1.redirect == $frFollow doAssert options1.referrer == "client".cstring From caf515a355924d05c0732d04bef89e9deeb4dfbe Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Fri, 29 Jan 2021 18:18:31 -0300 Subject: [PATCH 54/99] https://github.com/nim-lang/Nim/pull/12531#discussion_r564160044 --- lib/std/jsfetch.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/std/jsfetch.nim b/lib/std/jsfetch.nim index 65fecfebe33e..2c28a958eb06 100644 --- a/lib/std/jsfetch.nim +++ b/lib/std/jsfetch.nim @@ -134,7 +134,7 @@ runnableExamples: doAssert options1.body == """{"key": "value"}""".cstring doAssert options1.mode == $fmNoCors doAssert options1.credentials == $fcOmit - doAssert options1.cache == $fchNoCimport + doAssert options1.cache == $fchNoCache doAssert options1.referrerPolicy == $frpNoReferrer doAssert options1.redirect == $frFollow doAssert options1.referrer == "client".cstring From 66bcc62ca1e51f7e3fb931293b7328e732a188f9 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Fri, 29 Jan 2021 18:32:51 -0300 Subject: [PATCH 55/99] https://github.com/nim-lang/Nim/pull/12531#discussion_r564160044 --- lib/std/jsfetch.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/std/jsfetch.nim b/lib/std/jsfetch.nim index 2c28a958eb06..938b7b836c47 100644 --- a/lib/std/jsfetch.nim +++ b/lib/std/jsfetch.nim @@ -149,4 +149,4 @@ runnableExamples: doAssert response.ok doAssert response.status == 200.cint - waitFor example() + example() From de906312491ba825c4da5a9b1e4bb931bb20ca36 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Fri, 29 Jan 2021 18:42:54 -0300 Subject: [PATCH 56/99] https://github.com/nim-lang/Nim/pull/12531#discussion_r564160044 --- lib/std/jsfetch.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/std/jsfetch.nim b/lib/std/jsfetch.nim index 938b7b836c47..2e13b1e67dfe 100644 --- a/lib/std/jsfetch.nim +++ b/lib/std/jsfetch.nim @@ -149,4 +149,4 @@ runnableExamples: doAssert response.ok doAssert response.status == 200.cint - example() + discard example() From 709ba355b858fdd5c9480aff0c3f6156d63ac818 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Fri, 29 Jan 2021 21:18:44 -0300 Subject: [PATCH 57/99] Update lib/std/jsfetch.nim Co-authored-by: Timothee Cour --- lib/std/jsfetch.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/std/jsfetch.nim b/lib/std/jsfetch.nim index 2e13b1e67dfe..8fe3ee4852fd 100644 --- a/lib/std/jsfetch.nim +++ b/lib/std/jsfetch.nim @@ -142,7 +142,7 @@ runnableExamples: when not defined(nodejs): proc doFetch(): Future[Response] {.async.} = - fetch "http:httpbin.org/get" + fetch "https://httpbin.org/get" proc example() {.async.} = let response: Response = await doFetch() From b2bb48dd7e0ff2cc6f6c070e914d977ca775f940 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Wed, 24 Feb 2021 21:33:05 -0300 Subject: [PATCH 58/99] Use new .then --- lib/std/jsfetch.nim | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/std/jsfetch.nim b/lib/std/jsfetch.nim index 8fe3ee4852fd..c8d92f35f301 100644 --- a/lib/std/jsfetch.nim +++ b/lib/std/jsfetch.nim @@ -1,6 +1,10 @@ ## - Fetch for the JavaScript target: https://developer.mozilla.org/docs/Web/API/Fetch_API +## +## .. Note:: Module jsfetch requires compiling using -d:nimExperimentalAsyncjsThen. when not defined(js): {.fatal: "Module jsfetch is designed to be used with the JavaScript backend.".} +when not defined(nimExperimentalAsyncjsThen): + {.warning: "Module jsfetch requires compiling using -d:nimExperimentalAsyncjsThen.".} import asyncjs, jsheaders from httpcore import HttpMethod @@ -77,10 +81,10 @@ func fetchToCstring*(url: cstring): Future[cstring] {.importjs: "fetch(#).then(r func fetchToCstring*(url: cstring, options: FetchOptions): Future[cstring] {.importjs: "fetch(#, #).then(response => response.text()).then(text => text)".} ## Convenience func for `fetch()` API that returns a `cstring` directly. -func fetch*(url: cstring): Future[Response] {.importjs: "fetch(#).then(response => response)".} +func fetch*(url: cstring): Future[Response] {.importjs: "fetch(#)".} ## `fetch()` API, simple `GET` only, returns a `Response`. -func fetch*(url: cstring, options: FetchOptions): Future[Response] {.importjs: "(await fetch(#, #).then(response => response))".} +func fetch*(url: cstring, options: FetchOptions): Future[Response] {.importjs: "fetch(#, #)".} ## `fetch()` API that takes a `FetchOptions`, returns a `Response`. func toCstring*(this: FetchOptions or Response): cstring {.importjs: "JSON.stringify(#)".} From 45ad1319c5d0126cfdeb21f43b30a7a7b1975e33 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Wed, 24 Feb 2021 21:42:23 -0300 Subject: [PATCH 59/99] I removed the toCstring because with the new .then() is more intuitive and clean --- lib/std/jsfetch.nim | 6 ------ 1 file changed, 6 deletions(-) diff --git a/lib/std/jsfetch.nim b/lib/std/jsfetch.nim index c8d92f35f301..aa1ae84d65a6 100644 --- a/lib/std/jsfetch.nim +++ b/lib/std/jsfetch.nim @@ -75,12 +75,6 @@ func newfetchOptions*(metod: HttpMethod, body: cstring, ) ) -func fetchToCstring*(url: cstring): Future[cstring] {.importjs: "fetch(#).then(response => response.text()).then(text => text)".} - ## Convenience func for `fetch()` API that returns a `cstring` directly. - -func fetchToCstring*(url: cstring, options: FetchOptions): Future[cstring] {.importjs: "fetch(#, #).then(response => response.text()).then(text => text)".} - ## Convenience func for `fetch()` API that returns a `cstring` directly. - func fetch*(url: cstring): Future[Response] {.importjs: "fetch(#)".} ## `fetch()` API, simple `GET` only, returns a `Response`. From b84410c13ceb80605d69d0490847a0195be81d67 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Wed, 24 Feb 2021 22:03:50 -0300 Subject: [PATCH 60/99] Clean out --- lib/std/jsfetch.nim | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/std/jsfetch.nim b/lib/std/jsfetch.nim index aa1ae84d65a6..fc4f99812c87 100644 --- a/lib/std/jsfetch.nim +++ b/lib/std/jsfetch.nim @@ -52,7 +52,7 @@ type headers*: Headers -func unsafeNewFetchOptions*(metod, body, mode, credentials, cache, referrerPolicy: cstring, +proc unsafeNewFetchOptions*(metod, body, mode, credentials, cache, referrerPolicy: cstring, keepalive: bool, redirect = "follow".cstring, referrer = "client".cstring, integrity = "".cstring): FetchOptions {.importjs: "{method: #, body: #, mode: #, credentials: #, cache: #, referrerPolicy: #, keepalive: #, redirect: #, referrer: #, integrity: #}".} ## **Unsafe** `newfetchOptions`. Low-level func for optimization. @@ -75,10 +75,10 @@ func newfetchOptions*(metod: HttpMethod, body: cstring, ) ) -func fetch*(url: cstring): Future[Response] {.importjs: "fetch(#)".} +proc fetch*(url: cstring): Future[Response] {.importjs: "fetch(#)".} ## `fetch()` API, simple `GET` only, returns a `Response`. -func fetch*(url: cstring, options: FetchOptions): Future[Response] {.importjs: "fetch(#, #)".} +proc fetch*(url: cstring, options: FetchOptions): Future[Response] {.importjs: "fetch(#, #)".} ## `fetch()` API that takes a `FetchOptions`, returns a `Response`. func toCstring*(this: FetchOptions or Response): cstring {.importjs: "JSON.stringify(#)".} @@ -138,7 +138,8 @@ runnableExamples: doAssert options1.referrer == "client".cstring doAssert options1.integrity == "".cstring - when not defined(nodejs): + when not defined(nodejs) and defined(nimExperimentalAsyncjsThen): + proc doFetch(): Future[Response] {.async.} = fetch "https://httpbin.org/get" From ec76fc4e89a794ab264315bc6fcba9d04bdcf301 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Wed, 24 Feb 2021 23:21:00 -0300 Subject: [PATCH 61/99] import std/ --- lib/std/jsfetch.nim | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/std/jsfetch.nim b/lib/std/jsfetch.nim index fc4f99812c87..8ddf5038caa4 100644 --- a/lib/std/jsfetch.nim +++ b/lib/std/jsfetch.nim @@ -6,8 +6,8 @@ when not defined(js): when not defined(nimExperimentalAsyncjsThen): {.warning: "Module jsfetch requires compiling using -d:nimExperimentalAsyncjsThen.".} -import asyncjs, jsheaders -from httpcore import HttpMethod +import std/[asyncjs, jsffi, jsheaders] +from std/httpcore import HttpMethod type FetchOptions* = ref object ## Options for Fetch API. @@ -81,13 +81,13 @@ proc fetch*(url: cstring): Future[Response] {.importjs: "fetch(#)".} proc fetch*(url: cstring, options: FetchOptions): Future[Response] {.importjs: "fetch(#, #)".} ## `fetch()` API that takes a `FetchOptions`, returns a `Response`. -func toCstring*(this: FetchOptions or Response): cstring {.importjs: "JSON.stringify(#)".} +func toCstring*(self: FetchOptions or Response): cstring {.importjs: "JSON.stringify(#)".} -func `$`*(this: FetchOptions or Response): string = $toCstring(this) +func `$`*(self: FetchOptions or Response): string = $toCstring(self) runnableExamples: - import httpcore, asyncjs + import std/[httpcore, asyncjs] if defined(nimJsFetchTests): block: From d918a0a893178f0c022291fddcff56be6437dd1c Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Thu, 25 Feb 2021 00:02:28 -0300 Subject: [PATCH 62/99] Response procs so it can be explicitly created and tested --- lib/std/jsfetch.nim | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/lib/std/jsfetch.nim b/lib/std/jsfetch.nim index 8ddf5038caa4..674e8818a51e 100644 --- a/lib/std/jsfetch.nim +++ b/lib/std/jsfetch.nim @@ -45,13 +45,25 @@ type frpUnsafeUrl = "unsafe-url" Response* = ref object ## https://developer.mozilla.org/en-US/docs/Web/API/Response - myBodyUsed*, ok*, redirected*: bool + bodyUsed*, ok*, redirected*: bool typ* {.importjs: "type".}: cstring url*, statusText*: cstring status*: cint headers*: Headers +func newResponse*(body: cstring): Response {.importjs: "(new Response(#))".} + ## Explicit constructor for a new `Response`. + +func clone*(self: Response): Response {.importjs: "#.$1()".} + ## https://developer.mozilla.org/en-US/docs/Web/API/Response/clone + +func error*(self: Response): Response {.importjs: "#.$1()".} + ## https://developer.mozilla.org/en-US/docs/Web/API/Response/error + +func redirect*(self: Response; url: cstring; status: 100..599): Response {.importjs: "#.$1(#, #)".} + ## https://developer.mozilla.org/en-US/docs/Web/API/Response/redirect + proc unsafeNewFetchOptions*(metod, body, mode, credentials, cache, referrerPolicy: cstring, keepalive: bool, redirect = "follow".cstring, referrer = "client".cstring, integrity = "".cstring): FetchOptions {.importjs: "{method: #, body: #, mode: #, credentials: #, cache: #, referrerPolicy: #, keepalive: #, redirect: #, referrer: #, integrity: #}".} @@ -138,6 +150,12 @@ runnableExamples: doAssert options1.referrer == "client".cstring doAssert options1.integrity == "".cstring + block: + let response: Response = newResponse(body = "-. .. --".cstring) + doAssert response.clone() is Response + let redirected: Response = response.redirect("http://nim-lang.org".cstring, 307) + doAssert redirected.url == "http://nim-lang.org".cstring + when not defined(nodejs) and defined(nimExperimentalAsyncjsThen): proc doFetch(): Future[Response] {.async.} = From daada08e96d247748cde6f29b0356580fa39a8a3 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Thu, 25 Feb 2021 01:35:25 -0300 Subject: [PATCH 63/99] Response procs so it can be explicitly created and tested --- lib/std/jsfetch.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/std/jsfetch.nim b/lib/std/jsfetch.nim index 674e8818a51e..9ed6b780534a 100644 --- a/lib/std/jsfetch.nim +++ b/lib/std/jsfetch.nim @@ -53,7 +53,7 @@ type func newResponse*(body: cstring): Response {.importjs: "(new Response(#))".} - ## Explicit constructor for a new `Response`. + ## Explicit constructor for a new `Response`. *This does not call `fetch()`.* func clone*(self: Response): Response {.importjs: "#.$1()".} ## https://developer.mozilla.org/en-US/docs/Web/API/Response/clone From 0f3ad781a4e723139f0710a637770eeef77a2ae7 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Thu, 25 Feb 2021 01:48:49 -0300 Subject: [PATCH 64/99] Clean out --- lib/std/jsheaders.nim | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/std/jsheaders.nim b/lib/std/jsheaders.nim index 63c2f0bf03a1..ba13cb99d633 100644 --- a/lib/std/jsheaders.nim +++ b/lib/std/jsheaders.nim @@ -47,8 +47,9 @@ func `$`*(this: Headers): string = $toCstring(this) runnableExamples: if defined(nimJsHeadersTests): + block: - let header = newHeaders() + let header: Headers = newHeaders() header.add("key", "value") doAssert header.hasKey("key") doAssert header.keys() == @["key".cstring] @@ -62,16 +63,18 @@ runnableExamples: doAssert header.entries() == @[("key".cstring, "value".cstring)] header.clear() doAssert header.entries() == @[] + block: - let header = newHeaders() + let header: Headers = newHeaders() header.add("key", "a") header.add("key", "b") ## Duplicated. header.add("key", "c") ## Duplicated. doAssert header["key"] == "a, b, c".cstring header["key"] = "value".cstring doAssert header["key"] == "value".cstring + block: - let header = newHeaders() + let header: Headers = newHeaders() header["key"] = "a" header["key"] = "b" ## Overwrites. doAssert header["key"] == "b".cstring From 9fd32bafebfeb13dc7435f653e0db7d8027edefe Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Thu, 25 Feb 2021 02:25:16 -0300 Subject: [PATCH 65/99] Let the Body hit the floor --- lib/std/jsfetch.nim | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/std/jsfetch.nim b/lib/std/jsfetch.nim index 9ed6b780534a..0717b880a2cb 100644 --- a/lib/std/jsfetch.nim +++ b/lib/std/jsfetch.nim @@ -44,12 +44,16 @@ type frpOriginWhenCrossOrigin = "origin-when-cross-origin" frpUnsafeUrl = "unsafe-url" + Body* = ref object ## https://developer.mozilla.org/en-US/docs/Web/API/Body + bodyUsed*: bool + Response* = ref object ## https://developer.mozilla.org/en-US/docs/Web/API/Response bodyUsed*, ok*, redirected*: bool typ* {.importjs: "type".}: cstring url*, statusText*: cstring status*: cint headers*: Headers + body*: Body func newResponse*(body: cstring): Response {.importjs: "(new Response(#))".} @@ -64,10 +68,16 @@ func error*(self: Response): Response {.importjs: "#.$1()".} func redirect*(self: Response; url: cstring; status: 100..599): Response {.importjs: "#.$1(#, #)".} ## https://developer.mozilla.org/en-US/docs/Web/API/Response/redirect +proc text*(self: Body): Future[cstring] {.importjs: "#.$1()".} + ## https://developer.mozilla.org/en-US/docs/Web/API/Body/text + +proc json*(self: Body): Future[JsObject] {.importjs: "#.$1()".} + ## https://developer.mozilla.org/en-US/docs/Web/API/Body/json + proc unsafeNewFetchOptions*(metod, body, mode, credentials, cache, referrerPolicy: cstring, keepalive: bool, redirect = "follow".cstring, referrer = "client".cstring, integrity = "".cstring): FetchOptions {.importjs: "{method: #, body: #, mode: #, credentials: #, cache: #, referrerPolicy: #, keepalive: #, redirect: #, referrer: #, integrity: #}".} - ## **Unsafe** `newfetchOptions`. Low-level func for optimization. + ## **Unsafe** `newfetchOptions`. Low-level proc for optimization. func newfetchOptions*(metod: HttpMethod, body: cstring, mode: FetchModes, credentials: FetchCredentials, cache: FetchCaches, referrerPolicy: FetchReferrerPolicies, From 7c315c8afec488fd5b0ae33947b2160aa50f05c8 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Thu, 25 Feb 2021 03:20:27 -0300 Subject: [PATCH 66/99] Improve the code --- changelog.md | 3 ++- lib/std/jsfetch.nim | 24 +++++++++-------- lib/std/jsformdata.nim | 58 ++++++++++++++++++++++++++++++++++++++++++ tools/kochdocs.nim | 2 +- 4 files changed, 75 insertions(+), 12 deletions(-) create mode 100644 lib/std/jsformdata.nim diff --git a/changelog.md b/changelog.md index 5d6fbcecebec..7e6c1e48e134 100644 --- a/changelog.md +++ b/changelog.md @@ -130,7 +130,7 @@ with other backends. see #9125. Use `-d:nimLegacyJsRound` for previous behavior. - Deprecated `any`. See https://github.com/nim-lang/RFCs/issues/281 -- Added `std/sysrand` module to get random numbers from a secure source +- Added `std/sysrand` module to get random numbers from a secure source provided by the operating system. - Added optional `options` argument to `copyFile`, `copyFileToDir`, and @@ -182,6 +182,7 @@ provided by the operating system. and `$none(int)` to `"none(int)"` instead of `"None[int]"`. - Added `jsfetch` module [Fetch](https://developer.mozilla.org/docs/Web/API/Fetch_API) wrapper for JavaScript target. - Added `jsheaders` module [Headers](https://developer.mozilla.org/en-US/docs/Web/API/Headers) wrapper for JavaScript target. +- Added `jsformdata` module [FormData](https://developer.mozilla.org/en-US/docs/Web/API/FormData) wrapper for JavaScript target. ## Language changes diff --git a/lib/std/jsfetch.nim b/lib/std/jsfetch.nim index 0717b880a2cb..64a46ce78059 100644 --- a/lib/std/jsfetch.nim +++ b/lib/std/jsfetch.nim @@ -1,12 +1,8 @@ ## - Fetch for the JavaScript target: https://developer.mozilla.org/docs/Web/API/Fetch_API -## -## .. Note:: Module jsfetch requires compiling using -d:nimExperimentalAsyncjsThen. when not defined(js): {.fatal: "Module jsfetch is designed to be used with the JavaScript backend.".} -when not defined(nimExperimentalAsyncjsThen): - {.warning: "Module jsfetch requires compiling using -d:nimExperimentalAsyncjsThen.".} -import std/[asyncjs, jsffi, jsheaders] +import std/[asyncjs, jsffi, jsheaders, jsformdata] from std/httpcore import HttpMethod type @@ -56,8 +52,8 @@ type body*: Body -func newResponse*(body: cstring): Response {.importjs: "(new Response(#))".} - ## Explicit constructor for a new `Response`. *This does not call `fetch()`.* +func newResponse*(body: cstring or FormData): Response {.importjs: "(new Response(#))".} + ## Explicit constructor for a new `Response`. This does *not* call `fetch()`. func clone*(self: Response): Response {.importjs: "#.$1()".} ## https://developer.mozilla.org/en-US/docs/Web/API/Response/clone @@ -74,6 +70,9 @@ proc text*(self: Body): Future[cstring] {.importjs: "#.$1()".} proc json*(self: Body): Future[JsObject] {.importjs: "#.$1()".} ## https://developer.mozilla.org/en-US/docs/Web/API/Body/json +proc formData*(self: Body): Future[FormData] {.importjs: "#.$1()".} + ## https://developer.mozilla.org/en-US/docs/Web/API/Body/formData + proc unsafeNewFetchOptions*(metod, body, mode, credentials, cache, referrerPolicy: cstring, keepalive: bool, redirect = "follow".cstring, referrer = "client".cstring, integrity = "".cstring): FetchOptions {.importjs: "{method: #, body: #, mode: #, credentials: #, cache: #, referrerPolicy: #, keepalive: #, redirect: #, referrer: #, integrity: #}".} @@ -109,7 +108,7 @@ func `$`*(self: FetchOptions or Response): string = $toCstring(self) runnableExamples: - import std/[httpcore, asyncjs] + import std/[httpcore, asyncjs, jsheaders, jsformdata] if defined(nimJsFetchTests): block: @@ -166,8 +165,7 @@ runnableExamples: let redirected: Response = response.redirect("http://nim-lang.org".cstring, 307) doAssert redirected.url == "http://nim-lang.org".cstring - when not defined(nodejs) and defined(nimExperimentalAsyncjsThen): - + if not defined(nodejs): proc doFetch(): Future[Response] {.async.} = fetch "https://httpbin.org/get" @@ -175,5 +173,11 @@ runnableExamples: let response: Response = await doFetch() doAssert response.ok doAssert response.status == 200.cint + doAssert response.headers is Headers + doAssert response.body is Body + ## -d:nimExperimentalAsyncjsThen + when defined(nimExperimentalAsyncjsThen): + let contents: string = await response.body + .then((data: cstring) => $data) discard example() diff --git a/lib/std/jsformdata.nim b/lib/std/jsformdata.nim new file mode 100644 index 000000000000..e5158798d1c0 --- /dev/null +++ b/lib/std/jsformdata.nim @@ -0,0 +1,58 @@ +## - `FormData` for the JavaScript target: https://developer.mozilla.org/en-US/docs/Web/API/FormData +when not defined(js): + {.fatal: "Module jsformdata is designed to be used with the JavaScript backend.".} + +type FormData* = ref object of JsRoot ## FormData API. + +func newFormData*(): FormData {.importjs: "new FormData()".} + +func add*(this: FormData; name: cstring; value: SomeNumber | bool | cstring) {.importjs: "#.append(#, #)".} + ## https://developer.mozilla.org/en-US/docs/Web/API/FormData/append + ## Duplicate keys are allowed and order is preserved. + +func add*(this: FormData; name: cstring; value: SomeNumber | bool | cstring, filename: cstring) {.importjs: "#.append(#, #, #)".} + ## https://developer.mozilla.org/en-US/docs/Web/API/FormData/append + ## Duplicate keys are allowed and order is preserved. + +func delete*(this: FormData; name: cstring) {.importjs: "#.$1(#)".} + ## https://developer.mozilla.org/en-US/docs/Web/API/FormData/delete + ## Deletes *all items* with the same key name. + +func getAll*(this: FormData; name: cstring): seq[cstring] {.importjs: "#.$1(#)".} + ## https://developer.mozilla.org/en-US/docs/Web/API/FormData/getAll + +func hasKey*(this: FormData; name: cstring): bool {.importjs: "#.has(#)".} + ## https://developer.mozilla.org/en-US/docs/Web/API/FormData/has + +func keys*(this: FormData): seq[cstring] {.importjs: "Array.from(#.$1())".} + ## https://developer.mozilla.org/en-US/docs/Web/API/FormData/keys + +func values*(this: FormData): seq[cstring] {.importjs: "Array.from(#.$1())".} + ## https://developer.mozilla.org/en-US/docs/Web/API/FormData/values + +func pairs*(this: FormData): seq[tuple[key, val: cstring]] {.importjs: "Array.from(#.entries())".} + ## https://developer.mozilla.org/en-US/docs/Web/API/FormData/entries + +func put*(this: FormData; name, value, filename: cstring) {.importjs: "#.set(#, #, #)".} + ## https://developer.mozilla.org/en-US/docs/Web/API/FormData/set + +func `[]=`*(this: FormData; name, value: cstring) {.importjs: "#.set(#, #)".} + ## https://developer.mozilla.org/en-US/docs/Web/API/FormData/set + +func `[]`*(this: FormData; name: cstring): cstring {.importjs: "#.get(#)".} + ## https://developer.mozilla.org/en-US/docs/Web/API/FormData/get + +func clear*(this: FormData) {.importjs: + "(() => { const frmdt = #; Array.from(frmdt.keys()).forEach((key) => frmdt.delete(key)) })()".} + ## Convenience func to delete all items from `FormData`. + + +runnableExamples: + if defined(fusionJsFormdataTests): + let data: FormData = newFormData() + data["key0"] = "value0".cstring + data.add("key1".cstring, "value1".cstring) + data.delete("key1") + doAssert data.hasKey("key0") + doAssert data["key0"] == "value0".cstring + data.clear() diff --git a/tools/kochdocs.nim b/tools/kochdocs.nim index 1ff360ae7158..530ce8571214 100644 --- a/tools/kochdocs.nim +++ b/tools/kochdocs.nim @@ -14,7 +14,7 @@ const webUploadOutput = "web/upload" var nimExe*: string -const allowList = ["jsbigints.nim", "jsheaders.nim", "jsfetch.nim"] +const allowList = ["jsbigints.nim", "jsheaders.nim", "jsformdata.nim", "jsfetch.nim"] template isJsOnly(file: string): bool = file.isRelativeTo("lib/js") or From 0a24d26a11be5759733251efc1e9a1c099742e7a Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Thu, 25 Feb 2021 03:21:25 -0300 Subject: [PATCH 67/99] Improve the code --- lib/std/jsformdata.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/std/jsformdata.nim b/lib/std/jsformdata.nim index e5158798d1c0..56222bc11c64 100644 --- a/lib/std/jsformdata.nim +++ b/lib/std/jsformdata.nim @@ -48,7 +48,7 @@ func clear*(this: FormData) {.importjs: runnableExamples: - if defined(fusionJsFormdataTests): + if defined(nimJsFormdataTests): let data: FormData = newFormData() data["key0"] = "value0".cstring data.add("key1".cstring, "value1".cstring) From f53d6e59c55f274896100db11efbc236ece41544 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Thu, 25 Feb 2021 03:26:52 -0300 Subject: [PATCH 68/99] Improve the code --- lib/std/jsfetch.nim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/std/jsfetch.nim b/lib/std/jsfetch.nim index 64a46ce78059..046e6a04a3ef 100644 --- a/lib/std/jsfetch.nim +++ b/lib/std/jsfetch.nim @@ -102,9 +102,9 @@ proc fetch*(url: cstring): Future[Response] {.importjs: "fetch(#)".} proc fetch*(url: cstring, options: FetchOptions): Future[Response] {.importjs: "fetch(#, #)".} ## `fetch()` API that takes a `FetchOptions`, returns a `Response`. -func toCstring*(self: FetchOptions or Response): cstring {.importjs: "JSON.stringify(#)".} +func toCstring*(self: FetchOptions or Response or Body): cstring {.importjs: "JSON.stringify(#)".} -func `$`*(self: FetchOptions or Response): string = $toCstring(self) +func `$`*(self: FetchOptions or Response or Body): string = $toCstring(self) runnableExamples: From cebbe8c6026378f1648f406e3b87df312eaeaf57 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Thu, 25 Feb 2021 20:48:40 -0300 Subject: [PATCH 69/99] Progressive progress --- lib/std/jsfetch.nim | 46 +++++++++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/lib/std/jsfetch.nim b/lib/std/jsfetch.nim index 046e6a04a3ef..1b7f85c63323 100644 --- a/lib/std/jsfetch.nim +++ b/lib/std/jsfetch.nim @@ -51,20 +51,25 @@ type headers*: Headers body*: Body + Request* = ref object ## https://developer.mozilla.org/en-US/docs/Web/API/Request + bodyUsed*, ok*, redirected*: bool + typ* {.importjs: "type".}: cstring + url*, statusText*: cstring + status*: cint + headers*: Headers + body*: Body -func newResponse*(body: cstring or FormData): Response {.importjs: "(new Response(#))".} - ## Explicit constructor for a new `Response`. This does *not* call `fetch()`. -func clone*(self: Response): Response {.importjs: "#.$1()".} - ## https://developer.mozilla.org/en-US/docs/Web/API/Response/clone +func newResponse*(body: cstring or FormData): Response {.importjs: "(new Response(#))".} + ## Constructor for `Response`. This does *not* call `fetch()`. Same as `new Response()`. -func error*(self: Response): Response {.importjs: "#.$1()".} - ## https://developer.mozilla.org/en-US/docs/Web/API/Response/error +func newRequest*(url: cstring): Request {.importjs: "(new Request(#))".} + ## Constructor for `Request`. This does *not* call `fetch()`. Same as `new Request()`. -func redirect*(self: Response; url: cstring; status: 100..599): Response {.importjs: "#.$1(#, #)".} - ## https://developer.mozilla.org/en-US/docs/Web/API/Response/redirect +func clone*(self: Response or Request): Response {.importjs: "#.$1()".} + ## https://developer.mozilla.org/en-US/docs/Web/API/Response/clone -proc text*(self: Body): Future[cstring] {.importjs: "#.$1()".} +proc text*(self: Body or Request): Future[cstring] {.importjs: "#.$1()".} ## https://developer.mozilla.org/en-US/docs/Web/API/Body/text proc json*(self: Body): Future[JsObject] {.importjs: "#.$1()".} @@ -96,15 +101,15 @@ func newfetchOptions*(metod: HttpMethod, body: cstring, ) ) -proc fetch*(url: cstring): Future[Response] {.importjs: "fetch(#)".} - ## `fetch()` API, simple `GET` only, returns a `Response`. +proc fetch*(url: cstring or Request): Future[Response] {.importjs: "$1(#)".} + ## `fetch()` API, simple `GET` only, returns a `Future[Response]`. -proc fetch*(url: cstring, options: FetchOptions): Future[Response] {.importjs: "fetch(#, #)".} - ## `fetch()` API that takes a `FetchOptions`, returns a `Response`. +proc fetch*(url: cstring or Request, options: FetchOptions): Future[Response] {.importjs: "$1(#, #)".} + ## `fetch()` API that takes a `FetchOptions`, returns a `Future[Response]`. -func toCstring*(self: FetchOptions or Response or Body): cstring {.importjs: "JSON.stringify(#)".} +func toCstring*(self: Request or Response or Body or FetchOptions): cstring {.importjs: "JSON.stringify(#)".} -func `$`*(self: FetchOptions or Response or Body): string = $toCstring(self) +func `$`*(self: Request or Response or Body or FetchOptions): string = $toCstring(self) runnableExamples: @@ -134,6 +139,7 @@ runnableExamples: doAssert options0.redirect == "follow".cstring doAssert options0.referrer == "client".cstring doAssert options0.integrity == "".cstring + doAssert options0.toCstring is cstring block: let options1: FetchOptions = newFetchOptions( @@ -158,12 +164,15 @@ runnableExamples: doAssert options1.redirect == $frFollow doAssert options1.referrer == "client".cstring doAssert options1.integrity == "".cstring + doAssert options1.toCstring is cstring block: let response: Response = newResponse(body = "-. .. --".cstring) - doAssert response.clone() is Response - let redirected: Response = response.redirect("http://nim-lang.org".cstring, 307) - doAssert redirected.url == "http://nim-lang.org".cstring + doAssert response.clone() is Response ## Cloned. + doAssert response.toCstring is cstring + let request: Request = newRequest(url = "http://nim-lang.org".cstring) + doAssert request.clone() is Request ## Cloned. + doAssert request.toCstring is cstring if not defined(nodejs): proc doFetch(): Future[Response] {.async.} = @@ -175,6 +184,7 @@ runnableExamples: doAssert response.status == 200.cint doAssert response.headers is Headers doAssert response.body is Body + doAssert toCstring(response.body) is cstring ## -d:nimExperimentalAsyncjsThen when defined(nimExperimentalAsyncjsThen): let contents: string = await response.body From bd90b9bb9558989011fa67ecdb927a53acfc6668 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Thu, 25 Feb 2021 20:59:51 -0300 Subject: [PATCH 70/99] cstring instead --- lib/std/jsfetch.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/std/jsfetch.nim b/lib/std/jsfetch.nim index 1b7f85c63323..93ae44261dcc 100644 --- a/lib/std/jsfetch.nim +++ b/lib/std/jsfetch.nim @@ -176,7 +176,7 @@ runnableExamples: if not defined(nodejs): proc doFetch(): Future[Response] {.async.} = - fetch "https://httpbin.org/get" + fetch "https://httpbin.org/get".cstring proc example() {.async.} = let response: Response = await doFetch() From 842dc5c9dc149ba5e93dde546bd8a9c269dd2778 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Sat, 27 Feb 2021 15:50:44 -0300 Subject: [PATCH 71/99] this --> self --- lib/std/jsformdata.nim | 24 ++++++++++++------------ lib/std/jsheaders.nim | 22 +++++++++++----------- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/lib/std/jsformdata.nim b/lib/std/jsformdata.nim index 56222bc11c64..c850eae6cc62 100644 --- a/lib/std/jsformdata.nim +++ b/lib/std/jsformdata.nim @@ -6,43 +6,43 @@ type FormData* = ref object of JsRoot ## FormData API. func newFormData*(): FormData {.importjs: "new FormData()".} -func add*(this: FormData; name: cstring; value: SomeNumber | bool | cstring) {.importjs: "#.append(#, #)".} +func add*(self: FormData; name: cstring; value: SomeNumber | bool | cstring) {.importjs: "#.append(#, #)".} ## https://developer.mozilla.org/en-US/docs/Web/API/FormData/append ## Duplicate keys are allowed and order is preserved. -func add*(this: FormData; name: cstring; value: SomeNumber | bool | cstring, filename: cstring) {.importjs: "#.append(#, #, #)".} +func add*(self: FormData; name: cstring; value: SomeNumber | bool | cstring, filename: cstring) {.importjs: "#.append(#, #, #)".} ## https://developer.mozilla.org/en-US/docs/Web/API/FormData/append ## Duplicate keys are allowed and order is preserved. -func delete*(this: FormData; name: cstring) {.importjs: "#.$1(#)".} +func delete*(self: FormData; name: cstring) {.importjs: "#.$1(#)".} ## https://developer.mozilla.org/en-US/docs/Web/API/FormData/delete ## Deletes *all items* with the same key name. -func getAll*(this: FormData; name: cstring): seq[cstring] {.importjs: "#.$1(#)".} +func getAll*(self: FormData; name: cstring): seq[cstring] {.importjs: "#.$1(#)".} ## https://developer.mozilla.org/en-US/docs/Web/API/FormData/getAll -func hasKey*(this: FormData; name: cstring): bool {.importjs: "#.has(#)".} +func hasKey*(self: FormData; name: cstring): bool {.importjs: "#.has(#)".} ## https://developer.mozilla.org/en-US/docs/Web/API/FormData/has -func keys*(this: FormData): seq[cstring] {.importjs: "Array.from(#.$1())".} +func keys*(self: FormData): seq[cstring] {.importjs: "Array.from(#.$1())".} ## https://developer.mozilla.org/en-US/docs/Web/API/FormData/keys -func values*(this: FormData): seq[cstring] {.importjs: "Array.from(#.$1())".} +func values*(self: FormData): seq[cstring] {.importjs: "Array.from(#.$1())".} ## https://developer.mozilla.org/en-US/docs/Web/API/FormData/values -func pairs*(this: FormData): seq[tuple[key, val: cstring]] {.importjs: "Array.from(#.entries())".} +func pairs*(self: FormData): seq[tuple[key, val: cstring]] {.importjs: "Array.from(#.entries())".} ## https://developer.mozilla.org/en-US/docs/Web/API/FormData/entries -func put*(this: FormData; name, value, filename: cstring) {.importjs: "#.set(#, #, #)".} +func put*(self: FormData; name, value, filename: cstring) {.importjs: "#.set(#, #, #)".} ## https://developer.mozilla.org/en-US/docs/Web/API/FormData/set -func `[]=`*(this: FormData; name, value: cstring) {.importjs: "#.set(#, #)".} +func `[]=`*(self: FormData; name, value: cstring) {.importjs: "#.set(#, #)".} ## https://developer.mozilla.org/en-US/docs/Web/API/FormData/set -func `[]`*(this: FormData; name: cstring): cstring {.importjs: "#.get(#)".} +func `[]`*(self: FormData; name: cstring): cstring {.importjs: "#.get(#)".} ## https://developer.mozilla.org/en-US/docs/Web/API/FormData/get -func clear*(this: FormData) {.importjs: +func clear*(self: FormData) {.importjs: "(() => { const frmdt = #; Array.from(frmdt.keys()).forEach((key) => frmdt.delete(key)) })()".} ## Convenience func to delete all items from `FormData`. diff --git a/lib/std/jsheaders.nim b/lib/std/jsheaders.nim index ba13cb99d633..279dfe311efe 100644 --- a/lib/std/jsheaders.nim +++ b/lib/std/jsheaders.nim @@ -7,42 +7,42 @@ type Headers* = ref object of JsRoot ## HTTP Headers for the JavaScript target. func newHeaders*(): Headers {.importjs: "new Headers()".} ## https://developer.mozilla.org/en-US/docs/Web/API/Headers -func add*(this: Headers; key: cstring; value: cstring) {.importjs: "#.append(#, #)".} +func add*(self: Headers; key: cstring; value: cstring) {.importjs: "#.append(#, #)".} ## Allows duplicated keys. ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/append -func delete*(this: Headers; key: cstring) {.importjs: "#.$1(#)".} +func delete*(self: Headers; key: cstring) {.importjs: "#.$1(#)".} ## Delete *all* items with `key` from the headers, including duplicated keys. ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/delete -func hasKey*(this: Headers; key: cstring): bool {.importjs: "#.has(#)".} +func hasKey*(self: Headers; key: cstring): bool {.importjs: "#.has(#)".} ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/has -func keys*(this: Headers): seq[cstring] {.importjs: "Array.from(#.$1())".} +func keys*(self: Headers): seq[cstring] {.importjs: "Array.from(#.$1())".} ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/keys -func values*(this: Headers): seq[cstring] {.importjs: "Array.from(#.$1())".} +func values*(self: Headers): seq[cstring] {.importjs: "Array.from(#.$1())".} ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/values -func entries*(this: Headers): seq[tuple[key, value: cstring]] {.importjs: "Array.from(#.$1())".} +func entries*(self: Headers): seq[tuple[key, value: cstring]] {.importjs: "Array.from(#.$1())".} ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/entries -func `[]`*(this: Headers; key: cstring): cstring {.importjs: "#.get(#)".} +func `[]`*(self: Headers; key: cstring): cstring {.importjs: "#.get(#)".} ## Get *all* items with `key` from the headers, including duplicated values. ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/get -func `[]=`*(this: Headers; key: cstring; value: cstring) {.importjs: "#.set(#, #)".} +func `[]=`*(self: Headers; key: cstring; value: cstring) {.importjs: "#.set(#, #)".} ## Do *not* allow duplicated keys, overwrites duplicated keys. ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/set -func clear*(this: Headers) {.importjs: +func clear*(self: Headers) {.importjs: "(() => { const header = #; Array.from(header.keys()).forEach((key) => header.delete(key)) })()".} ## Convenience func to delete all items from `Headers`. -func toCstring*(this: Headers): cstring {.importjs: "JSON.stringify(Array.from(#.entries()))".} +func toCstring*(self: Headers): cstring {.importjs: "JSON.stringify(Array.from(#.entries()))".} ## Returns a `cstring` representation of `Headers`. -func `$`*(this: Headers): string = $toCstring(this) +func `$`*(self: Headers): string = $toCstring(this) runnableExamples: From bb2abf725619da9285288e443630776c3fef68fd Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Sat, 27 Feb 2021 16:01:07 -0300 Subject: [PATCH 72/99] this --> self --- lib/std/jsheaders.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/std/jsheaders.nim b/lib/std/jsheaders.nim index 279dfe311efe..bcfac1526a3f 100644 --- a/lib/std/jsheaders.nim +++ b/lib/std/jsheaders.nim @@ -42,7 +42,7 @@ func clear*(self: Headers) {.importjs: func toCstring*(self: Headers): cstring {.importjs: "JSON.stringify(Array.from(#.entries()))".} ## Returns a `cstring` representation of `Headers`. -func `$`*(self: Headers): string = $toCstring(this) +func `$`*(self: Headers): string = $toCstring(self) runnableExamples: From 2eea903084bc23bcc69f84674b424b777f44b92f Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Sat, 27 Feb 2021 16:46:01 -0300 Subject: [PATCH 73/99] Dollars, more Dollars for everyone --- lib/std/jsformdata.nim | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/std/jsformdata.nim b/lib/std/jsformdata.nim index c850eae6cc62..226962dd7b74 100644 --- a/lib/std/jsformdata.nim +++ b/lib/std/jsformdata.nim @@ -46,6 +46,12 @@ func clear*(self: FormData) {.importjs: "(() => { const frmdt = #; Array.from(frmdt.keys()).forEach((key) => frmdt.delete(key)) })()".} ## Convenience func to delete all items from `FormData`. +func toCstring*(self: FormData): cstring {.importjs: "JSON.stringify(#)".} + +func `$`*(self: FormData): string = $toCstring(self) + +func len*(self: FormData): int {.importjs: "Array.from(#.entries()).length".} + runnableExamples: if defined(nimJsFormdataTests): @@ -55,4 +61,6 @@ runnableExamples: data.delete("key1") doAssert data.hasKey("key0") doAssert data["key0"] == "value0".cstring + doAssert data.toCstring is cstring data.clear() + doAssert data.len == 0 From 60a350efe4db1a78715f410ee23c54016ebcac84 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Sat, 27 Feb 2021 16:46:10 -0300 Subject: [PATCH 74/99] Dollars, more Dollars for everyone --- lib/std/jsheaders.nim | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/std/jsheaders.nim b/lib/std/jsheaders.nim index bcfac1526a3f..1fb012cf5af4 100644 --- a/lib/std/jsheaders.nim +++ b/lib/std/jsheaders.nim @@ -44,6 +44,8 @@ func toCstring*(self: Headers): cstring {.importjs: "JSON.stringify(Array.from(# func `$`*(self: Headers): string = $toCstring(self) +func len*(self: Headers): int {.importjs: "Array.from(#.entries()).length".} + runnableExamples: if defined(nimJsHeadersTests): @@ -63,6 +65,7 @@ runnableExamples: doAssert header.entries() == @[("key".cstring, "value".cstring)] header.clear() doAssert header.entries() == @[] + doAssert header.len == 0 block: let header: Headers = newHeaders() From 112ae074ef7c504bd9323df53d51f862fbe7847f Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Sat, 27 Feb 2021 17:14:32 -0300 Subject: [PATCH 75/99] https://github.com/nim-lang/Nim/pull/17189#issuecomment-787127954 --- lib/std/jsfetch.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/std/jsfetch.nim b/lib/std/jsfetch.nim index 93ae44261dcc..cf310174b57a 100644 --- a/lib/std/jsfetch.nim +++ b/lib/std/jsfetch.nim @@ -72,7 +72,7 @@ func clone*(self: Response or Request): Response {.importjs: "#.$1()".} proc text*(self: Body or Request): Future[cstring] {.importjs: "#.$1()".} ## https://developer.mozilla.org/en-US/docs/Web/API/Body/text -proc json*(self: Body): Future[JsObject] {.importjs: "#.$1()".} +proc json*(self: Response): Future[JsObject] {.importjs: "#.$1()".} ## https://developer.mozilla.org/en-US/docs/Web/API/Body/json proc formData*(self: Body): Future[FormData] {.importjs: "#.$1()".} From 4950d004cc1c69e1e1ca343c54aa6e0c3508588a Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Sat, 27 Feb 2021 18:20:11 -0300 Subject: [PATCH 76/99] Clean out --- lib/std/jsfetch.nim | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/std/jsfetch.nim b/lib/std/jsfetch.nim index cf310174b57a..297da9b29bc9 100644 --- a/lib/std/jsfetch.nim +++ b/lib/std/jsfetch.nim @@ -2,8 +2,9 @@ when not defined(js): {.fatal: "Module jsfetch is designed to be used with the JavaScript backend.".} -import std/[asyncjs, jsffi, jsheaders, jsformdata] +import std/[asyncjs, jsheaders, jsformdata] from std/httpcore import HttpMethod +from std/jsffi import JsObject type FetchOptions* = ref object ## Options for Fetch API. From a0ebcf95256db5fdd15de94e2606b960d9f36ba3 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Sat, 27 Feb 2021 18:32:38 -0300 Subject: [PATCH 77/99] .then .catch --- lib/std/jsfetch.nim | 43 +++++++++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/lib/std/jsfetch.nim b/lib/std/jsfetch.nim index 297da9b29bc9..ec02e511ebe7 100644 --- a/lib/std/jsfetch.nim +++ b/lib/std/jsfetch.nim @@ -114,9 +114,9 @@ func `$`*(self: Request or Response or Body or FetchOptions): string = $toCstrin runnableExamples: - import std/[httpcore, asyncjs, jsheaders, jsformdata] - if defined(nimJsFetchTests): + import std/[httpcore, asyncjs, sugar, jsconsole jsheaders, jsformdata] + if defined(nimJsFetchTests): block: let options0: FetchOptions = unsafeNewFetchOptions( metod = "POST".cstring, @@ -176,19 +176,26 @@ runnableExamples: doAssert request.toCstring is cstring if not defined(nodejs): - proc doFetch(): Future[Response] {.async.} = - fetch "https://httpbin.org/get".cstring - - proc example() {.async.} = - let response: Response = await doFetch() - doAssert response.ok - doAssert response.status == 200.cint - doAssert response.headers is Headers - doAssert response.body is Body - doAssert toCstring(response.body) is cstring - ## -d:nimExperimentalAsyncjsThen - when defined(nimExperimentalAsyncjsThen): - let contents: string = await response.body - .then((data: cstring) => $data) - - discard example() + block: + proc doFetch(): Future[Response] {.async.} = + fetch "https://httpbin.org/get".cstring + + proc example() {.async.} = + let response: Response = await doFetch() + doAssert response.ok + doAssert response.status == 200.cint + doAssert response.headers is Headers + doAssert response.body is Body + doAssert toCstring(response.body) is cstring + + discard example() + + when defined(nimExperimentalAsyncjsThen): + block: + proc example2 {.async.} = + await fetch("https://api.github.com/users/torvalds".cstring) + .then((response: Response) => response.json()) + .then((json: JsObject) => console.log(json)) + .catch((err: Error) => console.log("Request Failed", err)) + + discard example2() From 60e5329046b8246b60f3d996590d7ce4e4870164 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Sat, 27 Feb 2021 18:33:44 -0300 Subject: [PATCH 78/99] .then .catch --- lib/std/jsfetch.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/std/jsfetch.nim b/lib/std/jsfetch.nim index ec02e511ebe7..bfb078aca033 100644 --- a/lib/std/jsfetch.nim +++ b/lib/std/jsfetch.nim @@ -114,7 +114,7 @@ func `$`*(self: Request or Response or Body or FetchOptions): string = $toCstrin runnableExamples: - import std/[httpcore, asyncjs, sugar, jsconsole jsheaders, jsformdata] + import std/[httpcore, asyncjs, sugar, jsconsole, jsheaders, jsformdata] if defined(nimJsFetchTests): block: From 36b5717d05b882a45a25b41bfa29c50408ef23f6 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Sat, 27 Feb 2021 18:35:29 -0300 Subject: [PATCH 79/99] text response --- lib/std/jsfetch.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/std/jsfetch.nim b/lib/std/jsfetch.nim index bfb078aca033..1942d29288c9 100644 --- a/lib/std/jsfetch.nim +++ b/lib/std/jsfetch.nim @@ -70,7 +70,7 @@ func newRequest*(url: cstring): Request {.importjs: "(new Request(#))".} func clone*(self: Response or Request): Response {.importjs: "#.$1()".} ## https://developer.mozilla.org/en-US/docs/Web/API/Response/clone -proc text*(self: Body or Request): Future[cstring] {.importjs: "#.$1()".} +proc text*(self: Body or Response): Future[cstring] {.importjs: "#.$1()".} ## https://developer.mozilla.org/en-US/docs/Web/API/Body/text proc json*(self: Response): Future[JsObject] {.importjs: "#.$1()".} From 23c0be5efa1c8a9a7ccfda491014ff2523991b78 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Sat, 27 Feb 2021 18:52:24 -0300 Subject: [PATCH 80/99] text response --- lib/std/jsfetch.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/std/jsfetch.nim b/lib/std/jsfetch.nim index 1942d29288c9..4541127193fd 100644 --- a/lib/std/jsfetch.nim +++ b/lib/std/jsfetch.nim @@ -70,7 +70,7 @@ func newRequest*(url: cstring): Request {.importjs: "(new Request(#))".} func clone*(self: Response or Request): Response {.importjs: "#.$1()".} ## https://developer.mozilla.org/en-US/docs/Web/API/Response/clone -proc text*(self: Body or Response): Future[cstring] {.importjs: "#.$1()".} +proc text*(self: Response): Future[cstring] {.importjs: "#.$1()".} ## https://developer.mozilla.org/en-US/docs/Web/API/Body/text proc json*(self: Response): Future[JsObject] {.importjs: "#.$1()".} From 17bfea0e3740558be20fe840ff856844d4eb9b60 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Sat, 27 Feb 2021 19:13:21 -0300 Subject: [PATCH 81/99] ref object of JsRoot --- lib/std/jsfetch.nim | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/std/jsfetch.nim b/lib/std/jsfetch.nim index 4541127193fd..798a84d4996e 100644 --- a/lib/std/jsfetch.nim +++ b/lib/std/jsfetch.nim @@ -7,7 +7,7 @@ from std/httpcore import HttpMethod from std/jsffi import JsObject type - FetchOptions* = ref object ## Options for Fetch API. + FetchOptions* = ref object of JsRoot ## Options for Fetch API. keepalive*: bool metod* {.importjs: "method".}: cstring body*, integrity*, referrer*, mode*, credentials*, cache*, redirect*, referrerPolicy*: cstring @@ -41,10 +41,10 @@ type frpOriginWhenCrossOrigin = "origin-when-cross-origin" frpUnsafeUrl = "unsafe-url" - Body* = ref object ## https://developer.mozilla.org/en-US/docs/Web/API/Body + Body* = ref object of JsRoot ## https://developer.mozilla.org/en-US/docs/Web/API/Body bodyUsed*: bool - Response* = ref object ## https://developer.mozilla.org/en-US/docs/Web/API/Response + Response* = ref object of JsRoot ## https://developer.mozilla.org/en-US/docs/Web/API/Response bodyUsed*, ok*, redirected*: bool typ* {.importjs: "type".}: cstring url*, statusText*: cstring @@ -52,7 +52,7 @@ type headers*: Headers body*: Body - Request* = ref object ## https://developer.mozilla.org/en-US/docs/Web/API/Request + Request* = ref object of JsRoot ## https://developer.mozilla.org/en-US/docs/Web/API/Request bodyUsed*, ok*, redirected*: bool typ* {.importjs: "type".}: cstring url*, statusText*: cstring From 669d6fa7fc93bfe093db20f498be01b1ad742c60 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Sat, 27 Feb 2021 19:47:24 -0300 Subject: [PATCH 82/99] nimExperimentalJsfetch --- lib/std/jsfetch.nim | 212 ++++++++++++++++++++++---------------------- 1 file changed, 107 insertions(+), 105 deletions(-) diff --git a/lib/std/jsfetch.nim b/lib/std/jsfetch.nim index 798a84d4996e..cc4c9f33d26c 100644 --- a/lib/std/jsfetch.nim +++ b/lib/std/jsfetch.nim @@ -1,119 +1,121 @@ ## - Fetch for the JavaScript target: https://developer.mozilla.org/docs/Web/API/Fetch_API +## .. Note:: jsfetch is Experimental. jsfetch module requires `-d:nimExperimentalJsfetch` when not defined(js): {.fatal: "Module jsfetch is designed to be used with the JavaScript backend.".} -import std/[asyncjs, jsheaders, jsformdata] -from std/httpcore import HttpMethod -from std/jsffi import JsObject - -type - FetchOptions* = ref object of JsRoot ## Options for Fetch API. - keepalive*: bool - metod* {.importjs: "method".}: cstring - body*, integrity*, referrer*, mode*, credentials*, cache*, redirect*, referrerPolicy*: cstring - - FetchModes* = enum ## JavaScript Fetch API mode options. - fmCors = "cors" - fmNoCors = "no-cors" - fmSameOrigin = "same-origin" - - FetchCredentials* = enum ## JavaScript Fetch API Credential options. - fcInclude = "include" - fcSameOrigin = "same-origin" - fcOmit = "omit" - - FetchCaches* = enum ## https://developer.mozilla.org/docs/Web/API/Request/cache - fchDefault = "default" - fchNoStore = "no-store" - fchReload = "reload" - fchNoCache = "no-cache" - fchForceCache = "force-cache" - - FetchRedirects* = enum ## JavaScript Fetch API Redirects options. - frFollow = "follow" - frError = "error" - frManual = "manual" - - FetchReferrerPolicies* = enum ## JavaScript Fetch API Referrer Policy options. - frpNoReferrer = "no-referrer" - frpNoReferrerWhenDowngrade = "no-referrer-when-downgrade" - frpOrigin = "origin" - frpOriginWhenCrossOrigin = "origin-when-cross-origin" - frpUnsafeUrl = "unsafe-url" - - Body* = ref object of JsRoot ## https://developer.mozilla.org/en-US/docs/Web/API/Body - bodyUsed*: bool - - Response* = ref object of JsRoot ## https://developer.mozilla.org/en-US/docs/Web/API/Response - bodyUsed*, ok*, redirected*: bool - typ* {.importjs: "type".}: cstring - url*, statusText*: cstring - status*: cint - headers*: Headers - body*: Body - - Request* = ref object of JsRoot ## https://developer.mozilla.org/en-US/docs/Web/API/Request - bodyUsed*, ok*, redirected*: bool - typ* {.importjs: "type".}: cstring - url*, statusText*: cstring - status*: cint - headers*: Headers - body*: Body - - -func newResponse*(body: cstring or FormData): Response {.importjs: "(new Response(#))".} - ## Constructor for `Response`. This does *not* call `fetch()`. Same as `new Response()`. - -func newRequest*(url: cstring): Request {.importjs: "(new Request(#))".} - ## Constructor for `Request`. This does *not* call `fetch()`. Same as `new Request()`. - -func clone*(self: Response or Request): Response {.importjs: "#.$1()".} - ## https://developer.mozilla.org/en-US/docs/Web/API/Response/clone - -proc text*(self: Response): Future[cstring] {.importjs: "#.$1()".} - ## https://developer.mozilla.org/en-US/docs/Web/API/Body/text - -proc json*(self: Response): Future[JsObject] {.importjs: "#.$1()".} - ## https://developer.mozilla.org/en-US/docs/Web/API/Body/json - -proc formData*(self: Body): Future[FormData] {.importjs: "#.$1()".} - ## https://developer.mozilla.org/en-US/docs/Web/API/Body/formData - -proc unsafeNewFetchOptions*(metod, body, mode, credentials, cache, referrerPolicy: cstring, - keepalive: bool, redirect = "follow".cstring, referrer = "client".cstring, integrity = "".cstring): FetchOptions {.importjs: - "{method: #, body: #, mode: #, credentials: #, cache: #, referrerPolicy: #, keepalive: #, redirect: #, referrer: #, integrity: #}".} - ## **Unsafe** `newfetchOptions`. Low-level proc for optimization. - -func newfetchOptions*(metod: HttpMethod, body: cstring, - mode: FetchModes, credentials: FetchCredentials, cache: FetchCaches, referrerPolicy: FetchReferrerPolicies, - keepalive: bool, redirect = frFollow, referrer = "client".cstring, integrity = "".cstring): FetchOptions = - ## Constructor for `FetchOptions`. - result = FetchOptions( - body: body, mode: $mode, credentials: $credentials, cache: $cache, referrerPolicy: $referrerPolicy, - keepalive: keepalive, redirect: $redirect, referrer: referrer, integrity: integrity, - metod: (case metod - of HttpHead: "HEAD".cstring - of HttpGet: "GET".cstring - of HttpPost: "POST".cstring - of HttpPut: "PUT".cstring - of HttpDelete: "DELETE".cstring - of HttpPatch: "PATCH".cstring - else: "GET".cstring +when defined(nimExperimentalJsfetch): + import std/[asyncjs, jsheaders, jsformdata] + from std/httpcore import HttpMethod + from std/jsffi import JsObject + + type + FetchOptions* = ref object of JsRoot ## Options for Fetch API. + keepalive*: bool + metod* {.importjs: "method".}: cstring + body*, integrity*, referrer*, mode*, credentials*, cache*, redirect*, referrerPolicy*: cstring + + FetchModes* = enum ## JavaScript Fetch API mode options. + fmCors = "cors" + fmNoCors = "no-cors" + fmSameOrigin = "same-origin" + + FetchCredentials* = enum ## JavaScript Fetch API Credential options. + fcInclude = "include" + fcSameOrigin = "same-origin" + fcOmit = "omit" + + FetchCaches* = enum ## https://developer.mozilla.org/docs/Web/API/Request/cache + fchDefault = "default" + fchNoStore = "no-store" + fchReload = "reload" + fchNoCache = "no-cache" + fchForceCache = "force-cache" + + FetchRedirects* = enum ## JavaScript Fetch API Redirects options. + frFollow = "follow" + frError = "error" + frManual = "manual" + + FetchReferrerPolicies* = enum ## JavaScript Fetch API Referrer Policy options. + frpNoReferrer = "no-referrer" + frpNoReferrerWhenDowngrade = "no-referrer-when-downgrade" + frpOrigin = "origin" + frpOriginWhenCrossOrigin = "origin-when-cross-origin" + frpUnsafeUrl = "unsafe-url" + + Body* = ref object of JsRoot ## https://developer.mozilla.org/en-US/docs/Web/API/Body + bodyUsed*: bool + + Response* = ref object of JsRoot ## https://developer.mozilla.org/en-US/docs/Web/API/Response + bodyUsed*, ok*, redirected*: bool + typ* {.importjs: "type".}: cstring + url*, statusText*: cstring + status*: cint + headers*: Headers + body*: Body + + Request* = ref object of JsRoot ## https://developer.mozilla.org/en-US/docs/Web/API/Request + bodyUsed*, ok*, redirected*: bool + typ* {.importjs: "type".}: cstring + url*, statusText*: cstring + status*: cint + headers*: Headers + body*: Body + + + func newResponse*(body: cstring or FormData): Response {.importjs: "(new Response(#))".} + ## Constructor for `Response`. This does *not* call `fetch()`. Same as `new Response()`. + + func newRequest*(url: cstring): Request {.importjs: "(new Request(#))".} + ## Constructor for `Request`. This does *not* call `fetch()`. Same as `new Request()`. + + func clone*(self: Response or Request): Response {.importjs: "#.$1()".} + ## https://developer.mozilla.org/en-US/docs/Web/API/Response/clone + + proc text*(self: Response): Future[cstring] {.importjs: "#.$1()".} + ## https://developer.mozilla.org/en-US/docs/Web/API/Body/text + + proc json*(self: Response): Future[JsObject] {.importjs: "#.$1()".} + ## https://developer.mozilla.org/en-US/docs/Web/API/Body/json + + proc formData*(self: Body): Future[FormData] {.importjs: "#.$1()".} + ## https://developer.mozilla.org/en-US/docs/Web/API/Body/formData + + proc unsafeNewFetchOptions*(metod, body, mode, credentials, cache, referrerPolicy: cstring, + keepalive: bool, redirect = "follow".cstring, referrer = "client".cstring, integrity = "".cstring): FetchOptions {.importjs: + "{method: #, body: #, mode: #, credentials: #, cache: #, referrerPolicy: #, keepalive: #, redirect: #, referrer: #, integrity: #}".} + ## **Unsafe** `newfetchOptions`. Low-level proc for optimization. + + func newfetchOptions*(metod: HttpMethod, body: cstring, + mode: FetchModes, credentials: FetchCredentials, cache: FetchCaches, referrerPolicy: FetchReferrerPolicies, + keepalive: bool, redirect = frFollow, referrer = "client".cstring, integrity = "".cstring): FetchOptions = + ## Constructor for `FetchOptions`. + result = FetchOptions( + body: body, mode: $mode, credentials: $credentials, cache: $cache, referrerPolicy: $referrerPolicy, + keepalive: keepalive, redirect: $redirect, referrer: referrer, integrity: integrity, + metod: (case metod + of HttpHead: "HEAD".cstring + of HttpGet: "GET".cstring + of HttpPost: "POST".cstring + of HttpPut: "PUT".cstring + of HttpDelete: "DELETE".cstring + of HttpPatch: "PATCH".cstring + else: "GET".cstring + ) ) - ) -proc fetch*(url: cstring or Request): Future[Response] {.importjs: "$1(#)".} - ## `fetch()` API, simple `GET` only, returns a `Future[Response]`. + proc fetch*(url: cstring or Request): Future[Response] {.importjs: "$1(#)".} + ## `fetch()` API, simple `GET` only, returns a `Future[Response]`. -proc fetch*(url: cstring or Request, options: FetchOptions): Future[Response] {.importjs: "$1(#, #)".} - ## `fetch()` API that takes a `FetchOptions`, returns a `Future[Response]`. + proc fetch*(url: cstring or Request, options: FetchOptions): Future[Response] {.importjs: "$1(#, #)".} + ## `fetch()` API that takes a `FetchOptions`, returns a `Future[Response]`. -func toCstring*(self: Request or Response or Body or FetchOptions): cstring {.importjs: "JSON.stringify(#)".} + func toCstring*(self: Request or Response or Body or FetchOptions): cstring {.importjs: "JSON.stringify(#)".} -func `$`*(self: Request or Response or Body or FetchOptions): string = $toCstring(self) + func `$`*(self: Request or Response or Body or FetchOptions): string = $toCstring(self) -runnableExamples: +runnableExamples("-d:nimExperimentalJsfetch"): import std/[httpcore, asyncjs, sugar, jsconsole, jsheaders, jsformdata] if defined(nimJsFetchTests): From 7e8f773244952ee9de49f891bc57e463d2582046 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Sat, 27 Feb 2021 20:23:22 -0300 Subject: [PATCH 83/99] Otherwise doc is empty --- lib/std/jsfetch.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/std/jsfetch.nim b/lib/std/jsfetch.nim index cc4c9f33d26c..7af45320818e 100644 --- a/lib/std/jsfetch.nim +++ b/lib/std/jsfetch.nim @@ -3,7 +3,7 @@ when not defined(js): {.fatal: "Module jsfetch is designed to be used with the JavaScript backend.".} -when defined(nimExperimentalJsfetch): +when defined(nimExperimentalJsfetch) or defined(nimdoc): import std/[asyncjs, jsheaders, jsformdata] from std/httpcore import HttpMethod from std/jsffi import JsObject From b48a9975f4fdf280251af709eb10fce04cfe43b4 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Sat, 6 Mar 2021 20:58:26 -0300 Subject: [PATCH 84/99] Update lib/std/jsformdata.nim Co-authored-by: Timothee Cour --- lib/std/jsformdata.nim | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/lib/std/jsformdata.nim b/lib/std/jsformdata.nim index 226962dd7b74..d44f91d58493 100644 --- a/lib/std/jsformdata.nim +++ b/lib/std/jsformdata.nim @@ -53,14 +53,13 @@ func `$`*(self: FormData): string = $toCstring(self) func len*(self: FormData): int {.importjs: "Array.from(#.entries()).length".} -runnableExamples: - if defined(nimJsFormdataTests): - let data: FormData = newFormData() - data["key0"] = "value0".cstring - data.add("key1".cstring, "value1".cstring) - data.delete("key1") - doAssert data.hasKey("key0") - doAssert data["key0"] == "value0".cstring - doAssert data.toCstring is cstring - data.clear() - doAssert data.len == 0 +runnableExamples("-r:off"): + let data: FormData = newFormData() + data["key0"] = "value0".cstring + data.add("key1".cstring, "value1".cstring) + data.delete("key1") + doAssert data.hasKey("key0") + doAssert data["key0"] == "value0".cstring + doAssert data.toCstring is cstring + data.clear() + doAssert data.len == 0 From b8e17982e7964777cba4084d7e0d4100633aa2f4 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Sat, 6 Mar 2021 21:46:21 -0300 Subject: [PATCH 85/99] Update lib/std/jsfetch.nim Co-authored-by: Timothee Cour --- lib/std/jsfetch.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/std/jsfetch.nim b/lib/std/jsfetch.nim index 7af45320818e..ff5991109565 100644 --- a/lib/std/jsfetch.nim +++ b/lib/std/jsfetch.nim @@ -115,7 +115,7 @@ when defined(nimExperimentalJsfetch) or defined(nimdoc): func `$`*(self: Request or Response or Body or FetchOptions): string = $toCstring(self) -runnableExamples("-d:nimExperimentalJsfetch"): +runnableExamples("-d:nimExperimentalJsfetch -r:off"): import std/[httpcore, asyncjs, sugar, jsconsole, jsheaders, jsformdata] if defined(nimJsFetchTests): From 8789424afb608c0c498d94599cabe869c80e6c6b Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Sat, 6 Mar 2021 21:46:48 -0300 Subject: [PATCH 86/99] Update lib/std/jsfetch.nim Co-authored-by: Timothee Cour --- lib/std/jsfetch.nim | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/std/jsfetch.nim b/lib/std/jsfetch.nim index ff5991109565..77ef4d36b457 100644 --- a/lib/std/jsfetch.nim +++ b/lib/std/jsfetch.nim @@ -117,6 +117,7 @@ when defined(nimExperimentalJsfetch) or defined(nimdoc): runnableExamples("-d:nimExperimentalJsfetch -r:off"): import std/[httpcore, asyncjs, sugar, jsconsole, jsheaders, jsformdata] + from std/jsffi import JsObject if defined(nimJsFetchTests): block: From 6b845e59a72007978816b19612aa775a844d8520 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Sat, 6 Mar 2021 22:06:49 -0300 Subject: [PATCH 87/99] Sync and feedback --- lib/std/jsheaders.nim | 67 +++++++++++++++++++++---------------------- 1 file changed, 33 insertions(+), 34 deletions(-) diff --git a/lib/std/jsheaders.nim b/lib/std/jsheaders.nim index 1fb012cf5af4..e59f1e1a4eec 100644 --- a/lib/std/jsheaders.nim +++ b/lib/std/jsheaders.nim @@ -47,37 +47,36 @@ func `$`*(self: Headers): string = $toCstring(self) func len*(self: Headers): int {.importjs: "Array.from(#.entries()).length".} -runnableExamples: - if defined(nimJsHeadersTests): - - block: - let header: Headers = newHeaders() - header.add("key", "value") - doAssert header.hasKey("key") - doAssert header.keys() == @["key".cstring] - doAssert header.values() == @["value".cstring] - doAssert header["key"] == "value".cstring - header["other"] = "another".cstring - doAssert header["other"] == "another".cstring - doAssert header.entries() == @[("key".cstring, "value".cstring), ("other".cstring, "another".cstring)] - doAssert header.toCstring() == """[["key","value"],["other","another"]]""".cstring - header.delete("other") - doAssert header.entries() == @[("key".cstring, "value".cstring)] - header.clear() - doAssert header.entries() == @[] - doAssert header.len == 0 - - block: - let header: Headers = newHeaders() - header.add("key", "a") - header.add("key", "b") ## Duplicated. - header.add("key", "c") ## Duplicated. - doAssert header["key"] == "a, b, c".cstring - header["key"] = "value".cstring - doAssert header["key"] == "value".cstring - - block: - let header: Headers = newHeaders() - header["key"] = "a" - header["key"] = "b" ## Overwrites. - doAssert header["key"] == "b".cstring +runnableExamples("-r:off"): + + block: + let header: Headers = newHeaders() + header.add("key", "value") + assert header.hasKey("key") + assert header.keys() == @["key".cstring] + assert header.values() == @["value".cstring] + assert header["key"] == "value".cstring + header["other"] = "another".cstring + assert header["other"] == "another".cstring + assert header.entries() == @[("key".cstring, "value".cstring), ("other".cstring, "another".cstring)] + assert header.toCstring() == """[["key","value"],["other","another"]]""".cstring + header.delete("other") + assert header.entries() == @[("key".cstring, "value".cstring)] + header.clear() + assert header.entries() == @[] + assert header.len == 0 + + block: + let header: Headers = newHeaders() + header.add("key", "a") + header.add("key", "b") ## Duplicated. + header.add("key", "c") ## Duplicated. + assert header["key"] == "a, b, c".cstring + header["key"] = "value".cstring + assert header["key"] == "value".cstring + + block: + let header: Headers = newHeaders() + header["key"] = "a" + header["key"] = "b" ## Overwrites. + assert header["key"] == "b".cstring From fe7a55211ec6621f268530ac11a2a06ac901ea03 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Sat, 6 Mar 2021 22:07:51 -0300 Subject: [PATCH 88/99] Sync and feedback --- lib/std/jsformdata.nim | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/std/jsformdata.nim b/lib/std/jsformdata.nim index d44f91d58493..06bdad350883 100644 --- a/lib/std/jsformdata.nim +++ b/lib/std/jsformdata.nim @@ -58,8 +58,8 @@ runnableExamples("-r:off"): data["key0"] = "value0".cstring data.add("key1".cstring, "value1".cstring) data.delete("key1") - doAssert data.hasKey("key0") - doAssert data["key0"] == "value0".cstring - doAssert data.toCstring is cstring + assert data.hasKey("key0") + assert data["key0"] == "value0".cstring + assert data.toCstring is cstring data.clear() - doAssert data.len == 0 + assert data.len == 0 From 7040c483916beb3ae60baad2ad1099935fd4804e Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Sat, 6 Mar 2021 22:12:18 -0300 Subject: [PATCH 89/99] Sync and feedback --- lib/std/jsfetch.nim | 74 ++++++++++++++++++++++----------------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/lib/std/jsfetch.nim b/lib/std/jsfetch.nim index 77ef4d36b457..627d484e2628 100644 --- a/lib/std/jsfetch.nim +++ b/lib/std/jsfetch.nim @@ -63,13 +63,13 @@ when defined(nimExperimentalJsfetch) or defined(nimdoc): body*: Body - func newResponse*(body: cstring or FormData): Response {.importjs: "(new Response(#))".} + func newResponse*(body: cstring | FormData): Response {.importjs: "(new Response(#))".} ## Constructor for `Response`. This does *not* call `fetch()`. Same as `new Response()`. func newRequest*(url: cstring): Request {.importjs: "(new Request(#))".} ## Constructor for `Request`. This does *not* call `fetch()`. Same as `new Request()`. - func clone*(self: Response or Request): Response {.importjs: "#.$1()".} + func clone*(self: Response | Request): Response {.importjs: "#.$1()".} ## https://developer.mozilla.org/en-US/docs/Web/API/Response/clone proc text*(self: Response): Future[cstring] {.importjs: "#.$1()".} @@ -104,15 +104,15 @@ when defined(nimExperimentalJsfetch) or defined(nimdoc): ) ) - proc fetch*(url: cstring or Request): Future[Response] {.importjs: "$1(#)".} + proc fetch*(url: cstring | Request): Future[Response] {.importjs: "$1(#)".} ## `fetch()` API, simple `GET` only, returns a `Future[Response]`. - proc fetch*(url: cstring or Request, options: FetchOptions): Future[Response] {.importjs: "$1(#, #)".} + proc fetch*(url: cstring | Request; options: FetchOptions): Future[Response] {.importjs: "$1(#, #)".} ## `fetch()` API that takes a `FetchOptions`, returns a `Future[Response]`. - func toCstring*(self: Request or Response or Body or FetchOptions): cstring {.importjs: "JSON.stringify(#)".} + func toCstring*(self: Request | Response | Body | FetchOptions): cstring {.importjs: "JSON.stringify(#)".} - func `$`*(self: Request or Response or Body or FetchOptions): string = $toCstring(self) + func `$`*(self: Request | Response | Body | FetchOptions): string = $toCstring(self) runnableExamples("-d:nimExperimentalJsfetch -r:off"): @@ -133,17 +133,17 @@ runnableExamples("-d:nimExperimentalJsfetch -r:off"): referrer = "client".cstring, integrity = "".cstring ) - doAssert options0.keepalive == false - doAssert options0.metod == "POST".cstring - doAssert options0.body == """{"key": "value"}""".cstring - doAssert options0.mode == "no-cors".cstring - doAssert options0.credentials == "omit".cstring - doAssert options0.cache == "no-cache".cstring - doAssert options0.referrerPolicy == "no-referrer".cstring - doAssert options0.redirect == "follow".cstring - doAssert options0.referrer == "client".cstring - doAssert options0.integrity == "".cstring - doAssert options0.toCstring is cstring + assert options0.keepalive == false + assert options0.metod == "POST".cstring + assert options0.body == """{"key": "value"}""".cstring + assert options0.mode == "no-cors".cstring + assert options0.credentials == "omit".cstring + assert options0.cache == "no-cache".cstring + assert options0.referrerPolicy == "no-referrer".cstring + assert options0.redirect == "follow".cstring + assert options0.referrer == "client".cstring + assert options0.integrity == "".cstring + assert options0.toCstring is cstring block: let options1: FetchOptions = newFetchOptions( @@ -158,25 +158,25 @@ runnableExamples("-d:nimExperimentalJsfetch -r:off"): referrer = "client".cstring, integrity = "".cstring ) - doAssert options1.keepalive == false - doAssert options1.metod == $HttpPost - doAssert options1.body == """{"key": "value"}""".cstring - doAssert options1.mode == $fmNoCors - doAssert options1.credentials == $fcOmit - doAssert options1.cache == $fchNoCache - doAssert options1.referrerPolicy == $frpNoReferrer - doAssert options1.redirect == $frFollow - doAssert options1.referrer == "client".cstring - doAssert options1.integrity == "".cstring - doAssert options1.toCstring is cstring + assert options1.keepalive == false + assert options1.metod == $HttpPost + assert options1.body == """{"key": "value"}""".cstring + assert options1.mode == $fmNoCors + assert options1.credentials == $fcOmit + assert options1.cache == $fchNoCache + assert options1.referrerPolicy == $frpNoReferrer + assert options1.redirect == $frFollow + assert options1.referrer == "client".cstring + assert options1.integrity == "".cstring + assert options1.toCstring is cstring block: let response: Response = newResponse(body = "-. .. --".cstring) - doAssert response.clone() is Response ## Cloned. - doAssert response.toCstring is cstring + assert response.clone() is Response ## Cloned. + assert response.toCstring is cstring let request: Request = newRequest(url = "http://nim-lang.org".cstring) - doAssert request.clone() is Request ## Cloned. - doAssert request.toCstring is cstring + assert request.clone() is Request ## Cloned. + assert request.toCstring is cstring if not defined(nodejs): block: @@ -185,11 +185,11 @@ runnableExamples("-d:nimExperimentalJsfetch -r:off"): proc example() {.async.} = let response: Response = await doFetch() - doAssert response.ok - doAssert response.status == 200.cint - doAssert response.headers is Headers - doAssert response.body is Body - doAssert toCstring(response.body) is cstring + assert response.ok + assert response.status == 200.cint + assert response.headers is Headers + assert response.body is Body + assert toCstring(response.body) is cstring discard example() From 85d5846146d6f6344c230f666a7e9c07836a90eb Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Sat, 6 Mar 2021 22:17:07 -0300 Subject: [PATCH 90/99] Sync and feedback --- lib/std/jsfetch.nim | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/lib/std/jsfetch.nim b/lib/std/jsfetch.nim index 627d484e2628..ef04295149cb 100644 --- a/lib/std/jsfetch.nim +++ b/lib/std/jsfetch.nim @@ -81,14 +81,14 @@ when defined(nimExperimentalJsfetch) or defined(nimdoc): proc formData*(self: Body): Future[FormData] {.importjs: "#.$1()".} ## https://developer.mozilla.org/en-US/docs/Web/API/Body/formData - proc unsafeNewFetchOptions*(metod, body, mode, credentials, cache, referrerPolicy: cstring, - keepalive: bool, redirect = "follow".cstring, referrer = "client".cstring, integrity = "".cstring): FetchOptions {.importjs: + proc unsafeNewFetchOptions*(metod, body, mode, credentials, cache, referrerPolicy: cstring; + keepalive: bool; redirect = "follow".cstring; referrer = "client".cstring; integrity = "".cstring): FetchOptions {.importjs: "{method: #, body: #, mode: #, credentials: #, cache: #, referrerPolicy: #, keepalive: #, redirect: #, referrer: #, integrity: #}".} ## **Unsafe** `newfetchOptions`. Low-level proc for optimization. - func newfetchOptions*(metod: HttpMethod, body: cstring, - mode: FetchModes, credentials: FetchCredentials, cache: FetchCaches, referrerPolicy: FetchReferrerPolicies, - keepalive: bool, redirect = frFollow, referrer = "client".cstring, integrity = "".cstring): FetchOptions = + func newfetchOptions*(metod: HttpMethod; body: cstring; + mode: FetchModes; credentials: FetchCredentials; cache: FetchCaches; referrerPolicy: FetchReferrerPolicies; + keepalive: bool; redirect = frFollow; referrer = "client".cstring; integrity = "".cstring): FetchOptions = ## Constructor for `FetchOptions`. result = FetchOptions( body: body, mode: $mode, credentials: $credentials, cache: $cache, referrerPolicy: $referrerPolicy, @@ -172,11 +172,7 @@ runnableExamples("-d:nimExperimentalJsfetch -r:off"): block: let response: Response = newResponse(body = "-. .. --".cstring) - assert response.clone() is Response ## Cloned. - assert response.toCstring is cstring let request: Request = newRequest(url = "http://nim-lang.org".cstring) - assert request.clone() is Request ## Cloned. - assert request.toCstring is cstring if not defined(nodejs): block: From 642c0ffbae6670889f06ae738177865878291ef3 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Sat, 6 Mar 2021 22:32:33 -0300 Subject: [PATCH 91/99] Sync and feedback --- lib/std/jsfetch.nim | 147 ++++++++++++++++++++++---------------------- 1 file changed, 73 insertions(+), 74 deletions(-) diff --git a/lib/std/jsfetch.nim b/lib/std/jsfetch.nim index ef04295149cb..a66983f7efb3 100644 --- a/lib/std/jsfetch.nim +++ b/lib/std/jsfetch.nim @@ -119,82 +119,81 @@ runnableExamples("-d:nimExperimentalJsfetch -r:off"): import std/[httpcore, asyncjs, sugar, jsconsole, jsheaders, jsformdata] from std/jsffi import JsObject - if defined(nimJsFetchTests): + block: + let options0: FetchOptions = unsafeNewFetchOptions( + metod = "POST".cstring, + body = """{"key": "value"}""".cstring, + mode = "no-cors".cstring, + credentials = "omit".cstring, + cache = "no-cache".cstring, + referrerPolicy = "no-referrer".cstring, + keepalive = false, + redirect = "follow".cstring, + referrer = "client".cstring, + integrity = "".cstring + ) + assert options0.keepalive == false + assert options0.metod == "POST".cstring + assert options0.body == """{"key": "value"}""".cstring + assert options0.mode == "no-cors".cstring + assert options0.credentials == "omit".cstring + assert options0.cache == "no-cache".cstring + assert options0.referrerPolicy == "no-referrer".cstring + assert options0.redirect == "follow".cstring + assert options0.referrer == "client".cstring + assert options0.integrity == "".cstring + assert options0.toCstring is cstring + + block: + let options1: FetchOptions = newFetchOptions( + metod = HttpPost, + body = """{"key": "value"}""".cstring, + mode = fmNoCors, + credentials = fcOmit, + cache = fchNoCache, + referrerPolicy = frpNoReferrer, + keepalive = false, + redirect = frFollow, + referrer = "client".cstring, + integrity = "".cstring + ) + assert options1.keepalive == false + assert options1.metod == $HttpPost + assert options1.body == """{"key": "value"}""".cstring + assert options1.mode == $fmNoCors + assert options1.credentials == $fcOmit + assert options1.cache == $fchNoCache + assert options1.referrerPolicy == $frpNoReferrer + assert options1.redirect == $frFollow + assert options1.referrer == "client".cstring + assert options1.integrity == "".cstring + assert options1.toCstring is cstring + + block: + let response: Response = newResponse(body = "-. .. --".cstring) + let request: Request = newRequest(url = "http://nim-lang.org".cstring) + + if not defined(nodejs): block: - let options0: FetchOptions = unsafeNewFetchOptions( - metod = "POST".cstring, - body = """{"key": "value"}""".cstring, - mode = "no-cors".cstring, - credentials = "omit".cstring, - cache = "no-cache".cstring, - referrerPolicy = "no-referrer".cstring, - keepalive = false, - redirect = "follow".cstring, - referrer = "client".cstring, - integrity = "".cstring - ) - assert options0.keepalive == false - assert options0.metod == "POST".cstring - assert options0.body == """{"key": "value"}""".cstring - assert options0.mode == "no-cors".cstring - assert options0.credentials == "omit".cstring - assert options0.cache == "no-cache".cstring - assert options0.referrerPolicy == "no-referrer".cstring - assert options0.redirect == "follow".cstring - assert options0.referrer == "client".cstring - assert options0.integrity == "".cstring - assert options0.toCstring is cstring + proc doFetch(): Future[Response] {.async.} = + fetch "https://httpbin.org/get".cstring - block: - let options1: FetchOptions = newFetchOptions( - metod = HttpPost, - body = """{"key": "value"}""".cstring, - mode = fmNoCors, - credentials = fcOmit, - cache = fchNoCache, - referrerPolicy = frpNoReferrer, - keepalive = false, - redirect = frFollow, - referrer = "client".cstring, - integrity = "".cstring - ) - assert options1.keepalive == false - assert options1.metod == $HttpPost - assert options1.body == """{"key": "value"}""".cstring - assert options1.mode == $fmNoCors - assert options1.credentials == $fcOmit - assert options1.cache == $fchNoCache - assert options1.referrerPolicy == $frpNoReferrer - assert options1.redirect == $frFollow - assert options1.referrer == "client".cstring - assert options1.integrity == "".cstring - assert options1.toCstring is cstring + proc example() {.async.} = + let response: Response = await doFetch() + assert response.ok + assert response.status == 200.cint + assert response.headers is Headers + assert response.body is Body + assert toCstring(response.body) is cstring - block: - let response: Response = newResponse(body = "-. .. --".cstring) - let request: Request = newRequest(url = "http://nim-lang.org".cstring) + discard example() - if not defined(nodejs): + when defined(nimExperimentalAsyncjsThen): block: - proc doFetch(): Future[Response] {.async.} = - fetch "https://httpbin.org/get".cstring - - proc example() {.async.} = - let response: Response = await doFetch() - assert response.ok - assert response.status == 200.cint - assert response.headers is Headers - assert response.body is Body - assert toCstring(response.body) is cstring - - discard example() - - when defined(nimExperimentalAsyncjsThen): - block: - proc example2 {.async.} = - await fetch("https://api.github.com/users/torvalds".cstring) - .then((response: Response) => response.json()) - .then((json: JsObject) => console.log(json)) - .catch((err: Error) => console.log("Request Failed", err)) - - discard example2() + proc example2 {.async.} = + await fetch("https://api.github.com/users/torvalds".cstring) + .then((response: Response) => response.json()) + .then((json: JsObject) => console.log(json)) + .catch((err: Error) => console.log("Request Failed", err)) + + discard example2() From ade2c5f8e429ed75697156f2bfddfb5ebb70883e Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Sat, 6 Mar 2021 23:31:11 -0300 Subject: [PATCH 92/99] Sync and feedback --- lib/std/jsfetch.nim | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/std/jsfetch.nim b/lib/std/jsfetch.nim index a66983f7efb3..5396277afb5a 100644 --- a/lib/std/jsfetch.nim +++ b/lib/std/jsfetch.nim @@ -84,7 +84,7 @@ when defined(nimExperimentalJsfetch) or defined(nimdoc): proc unsafeNewFetchOptions*(metod, body, mode, credentials, cache, referrerPolicy: cstring; keepalive: bool; redirect = "follow".cstring; referrer = "client".cstring; integrity = "".cstring): FetchOptions {.importjs: "{method: #, body: #, mode: #, credentials: #, cache: #, referrerPolicy: #, keepalive: #, redirect: #, referrer: #, integrity: #}".} - ## **Unsafe** `newfetchOptions`. Low-level proc for optimization. + ## .. Warning:: Unsafe `newfetchOptions`. func newfetchOptions*(metod: HttpMethod; body: cstring; mode: FetchModes; credentials: FetchCredentials; cache: FetchCaches; referrerPolicy: FetchReferrerPolicies; @@ -116,8 +116,10 @@ when defined(nimExperimentalJsfetch) or defined(nimdoc): runnableExamples("-d:nimExperimentalJsfetch -r:off"): - import std/[httpcore, asyncjs, sugar, jsconsole, jsheaders, jsformdata] + import std/[asyncjs, jsconsole, jsheaders, jsformdata] + from std/httpcore import HttpMethod from std/jsffi import JsObject + from std/sugar import `=>` block: let options0: FetchOptions = unsafeNewFetchOptions( From 8c95566677cc9e9e46098b7cae182e6464208098 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Sun, 7 Mar 2021 00:13:22 -0300 Subject: [PATCH 93/99] tiny --- lib/std/jsfetch.nim | 3 --- 1 file changed, 3 deletions(-) diff --git a/lib/std/jsfetch.nim b/lib/std/jsfetch.nim index 5396277afb5a..495a91035f5d 100644 --- a/lib/std/jsfetch.nim +++ b/lib/std/jsfetch.nim @@ -144,7 +144,6 @@ runnableExamples("-d:nimExperimentalJsfetch -r:off"): assert options0.redirect == "follow".cstring assert options0.referrer == "client".cstring assert options0.integrity == "".cstring - assert options0.toCstring is cstring block: let options1: FetchOptions = newFetchOptions( @@ -169,7 +168,6 @@ runnableExamples("-d:nimExperimentalJsfetch -r:off"): assert options1.redirect == $frFollow assert options1.referrer == "client".cstring assert options1.integrity == "".cstring - assert options1.toCstring is cstring block: let response: Response = newResponse(body = "-. .. --".cstring) @@ -186,7 +184,6 @@ runnableExamples("-d:nimExperimentalJsfetch -r:off"): assert response.status == 200.cint assert response.headers is Headers assert response.body is Body - assert toCstring(response.body) is cstring discard example() From 96abbb1ee48aed94f56846d2d68ccb3f711cffda Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Sun, 7 Mar 2021 00:23:45 -0300 Subject: [PATCH 94/99] tiny --- lib/std/jsformdata.nim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/std/jsformdata.nim b/lib/std/jsformdata.nim index 06bdad350883..2728fbdd0ab6 100644 --- a/lib/std/jsformdata.nim +++ b/lib/std/jsformdata.nim @@ -16,7 +16,8 @@ func add*(self: FormData; name: cstring; value: SomeNumber | bool | cstring, fil func delete*(self: FormData; name: cstring) {.importjs: "#.$1(#)".} ## https://developer.mozilla.org/en-US/docs/Web/API/FormData/delete - ## Deletes *all items* with the same key name. + ## + ## .. Warning:: Deletes *all items* with the same key name. func getAll*(self: FormData; name: cstring): seq[cstring] {.importjs: "#.$1(#)".} ## https://developer.mozilla.org/en-US/docs/Web/API/FormData/getAll @@ -60,6 +61,5 @@ runnableExamples("-r:off"): data.delete("key1") assert data.hasKey("key0") assert data["key0"] == "value0".cstring - assert data.toCstring is cstring data.clear() assert data.len == 0 From 53e05a4dd8369d04ee384d3477cd7f48d18e3ef8 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Sun, 7 Mar 2021 00:23:49 -0300 Subject: [PATCH 95/99] tiny --- lib/std/jsheaders.nim | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/std/jsheaders.nim b/lib/std/jsheaders.nim index e59f1e1a4eec..2a2285874738 100644 --- a/lib/std/jsheaders.nim +++ b/lib/std/jsheaders.nim @@ -12,8 +12,9 @@ func add*(self: Headers; key: cstring; value: cstring) {.importjs: "#.append(#, ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/append func delete*(self: Headers; key: cstring) {.importjs: "#.$1(#)".} - ## Delete *all* items with `key` from the headers, including duplicated keys. ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/delete + ## + ## .. Warning:: Delete *all* items with `key` from the headers, including duplicated keys. func hasKey*(self: Headers; key: cstring): bool {.importjs: "#.has(#)".} ## https://developer.mozilla.org/en-US/docs/Web/API/Headers/has From 222d654ba5ae53b749cad5a67d820032e5ab33f3 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Sun, 7 Mar 2021 00:31:49 -0300 Subject: [PATCH 96/99] tiny --- lib/std/jsfetch.nim | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/std/jsfetch.nim b/lib/std/jsfetch.nim index 495a91035f5d..25debb2b15e1 100644 --- a/lib/std/jsfetch.nim +++ b/lib/std/jsfetch.nim @@ -14,12 +14,12 @@ when defined(nimExperimentalJsfetch) or defined(nimdoc): metod* {.importjs: "method".}: cstring body*, integrity*, referrer*, mode*, credentials*, cache*, redirect*, referrerPolicy*: cstring - FetchModes* = enum ## JavaScript Fetch API mode options. + FetchModes* = enum ## Mode options. fmCors = "cors" fmNoCors = "no-cors" fmSameOrigin = "same-origin" - FetchCredentials* = enum ## JavaScript Fetch API Credential options. + FetchCredentials* = enum ## Credential options. fcInclude = "include" fcSameOrigin = "same-origin" fcOmit = "omit" @@ -31,12 +31,12 @@ when defined(nimExperimentalJsfetch) or defined(nimdoc): fchNoCache = "no-cache" fchForceCache = "force-cache" - FetchRedirects* = enum ## JavaScript Fetch API Redirects options. + FetchRedirects* = enum ## Redirects options. frFollow = "follow" frError = "error" frManual = "manual" - FetchReferrerPolicies* = enum ## JavaScript Fetch API Referrer Policy options. + FetchReferrerPolicies* = enum ## Referrer Policy options. frpNoReferrer = "no-referrer" frpNoReferrerWhenDowngrade = "no-referrer-when-downgrade" frpOrigin = "origin" From e5859db1f24be19793b390f390f647fa4f7ec790 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Sun, 7 Mar 2021 00:31:52 -0300 Subject: [PATCH 97/99] tiny --- lib/std/jsheaders.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/std/jsheaders.nim b/lib/std/jsheaders.nim index 2a2285874738..a67e54ef7aea 100644 --- a/lib/std/jsheaders.nim +++ b/lib/std/jsheaders.nim @@ -2,7 +2,7 @@ when not defined(js): {.fatal: "Module jsheaders is designed to be used with the JavaScript backend.".} -type Headers* = ref object of JsRoot ## HTTP Headers for the JavaScript target. +type Headers* = ref object of JsRoot ## HTTP Headers API. func newHeaders*(): Headers {.importjs: "new Headers()".} ## https://developer.mozilla.org/en-US/docs/Web/API/Headers From 3b28469a85c09c7eb2f374e472696c4daaf267e6 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Sun, 7 Mar 2021 00:45:21 -0300 Subject: [PATCH 98/99] Update lib/std/jsfetch.nim Co-authored-by: Timothee Cour --- lib/std/jsfetch.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/std/jsfetch.nim b/lib/std/jsfetch.nim index 25debb2b15e1..2ff894985e35 100644 --- a/lib/std/jsfetch.nim +++ b/lib/std/jsfetch.nim @@ -19,7 +19,7 @@ when defined(nimExperimentalJsfetch) or defined(nimdoc): fmNoCors = "no-cors" fmSameOrigin = "same-origin" - FetchCredentials* = enum ## Credential options. + FetchCredentials* = enum ## Credential options. See https://developer.mozilla.org/en-US/docs/Web/API/Request/credentials fcInclude = "include" fcSameOrigin = "same-origin" fcOmit = "omit" From e0d8342cd60c180c7547943b1e395643169a5f22 Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Sun, 7 Mar 2021 00:57:41 -0300 Subject: [PATCH 99/99] Update changelog.md Co-authored-by: flywind --- changelog.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/changelog.md b/changelog.md index 483fcb399ba9..3e9ed6276d73 100644 --- a/changelog.md +++ b/changelog.md @@ -192,9 +192,9 @@ provided by the operating system. - `std/options` changed `$some(3)` to `"some(3)"` instead of `"Some(3)"` and `$none(int)` to `"none(int)"` instead of `"None[int]"`. -- Added `jsfetch` module [Fetch](https://developer.mozilla.org/docs/Web/API/Fetch_API) wrapper for JavaScript target. -- Added `jsheaders` module [Headers](https://developer.mozilla.org/en-US/docs/Web/API/Headers) wrapper for JavaScript target. -- Added `jsformdata` module [FormData](https://developer.mozilla.org/en-US/docs/Web/API/FormData) wrapper for JavaScript target. +- Added `std/jsfetch` module [Fetch](https://developer.mozilla.org/docs/Web/API/Fetch_API) wrapper for JavaScript target. +- Added `std/jsheaders` module [Headers](https://developer.mozilla.org/en-US/docs/Web/API/Headers) wrapper for JavaScript target. +- Added `std/jsformdata` module [FormData](https://developer.mozilla.org/en-US/docs/Web/API/FormData) wrapper for JavaScript target. - `system.addEscapedChar` now renders `\r` as `\r` instead of `\c`, to be compatible