From 2528404a155d9a5deae11175148b2fbb9f7d86ce Mon Sep 17 00:00:00 2001 From: krisbitney Date: Fri, 26 May 2023 11:25:38 +0200 Subject: [PATCH 1/3] added feature-complete interface draft --- interface/package.json | 4 +- interface/polywrap.deploy.yaml | 3 +- interface/polywrap.graphql | 543 +++++++++++++++++++++++++++++++-- interface/polywrap.yaml | 1 - interface/resources/README.md | 138 +++++++-- interface/yarn.lock | 86 +++--- 6 files changed, 677 insertions(+), 98 deletions(-) diff --git a/interface/package.json b/interface/package.json index 5c3accc..11a6b80 100644 --- a/interface/package.json +++ b/interface/package.json @@ -1,13 +1,13 @@ { "name": "@polywrap/http-interface", - "description": "Polywrap Http Interface", + "description": "Polywrap HTTP Interface", "version": "0.10.0", "scripts": { "build": "npx polywrap build", "deploy": "npx polywrap deploy -o deployment.json" }, "devDependencies": { - "polywrap": "0.10.2" + "polywrap": "0.10.3" }, "publishConfig": { "access": "public" diff --git a/interface/polywrap.deploy.yaml b/interface/polywrap.deploy.yaml index f314e95..e36638b 100644 --- a/interface/polywrap.deploy.yaml +++ b/interface/polywrap.deploy.yaml @@ -1,5 +1,4 @@ -format: 0.3.0 -primaryJobName: ipfs_deploy +format: 0.2.0 jobs: ipfs_deploy: steps: diff --git a/interface/polywrap.graphql b/interface/polywrap.graphql index e1131fc..e7c2660 100644 --- a/interface/polywrap.graphql +++ b/interface/polywrap.graphql @@ -1,42 +1,527 @@ +""" +Response: Represents the server's response to an HTTP request. +""" type Response { - status: Int! - statusText: String! - headers: Map @annotate(type: "Map") - body: String + """ + status: HTTP status code of the response. + """ + status: Int! + + """ + statusText: The text phrase corresponding to the status code. + """ + statusText: String! + + """ + headers: List of HTTP headers in the response. + """ + headers: [HTTPHeader!] + + """ + body: The body of the response, if any. + """ + body: String + + """ + httpVersion: The HTTP version used in the response. + """ + httpVersion: HTTPVersion! + + """ + cookies: List of cookies sent in the response. + """ + cookies: [Cookie!] } +""" +Request: Represents an HTTP request to be sent to a server. +""" type Request { - headers: Map @annotate(type: "Map") - urlParams: Map @annotate(type: "Map") - responseType: ResponseType! - """The body of the request. If present, the `formData` property will be ignored.""" - body: String - """ - An alternative to the standard request body, 'formData' is expected to be in the 'multipart/form-data' format. - If present, the `body` property is not null, `formData` will be ignored. - Otherwise, if formData is not null, the following header will be added to the request: 'Content-Type: multipart/form-data'. - """ - formData: [FormDataEntry!] - timeout: UInt32 + """ + headers: List of HTTP headers to be included in the request. + """ + headers: [HTTPHeader!] + + """ + urlParams: Query parameters to be appended to the request URL. + """ + urlParams: Map @annotate(type: "Map") + + """ + responseType: Desired format of the response. + """ + responseType: ResponseType! + + """ + body: The body of the request, if any. If body is present, formData is ignored. + """ + body: String + + """ + formData: List of form data entries to be included in the request, if body is not present. + """ + formData: [FormDataEntry!] + + """ + timeout: Timeout for the request in milliseconds. If not set, the request will not timeout. + """ + timeout: Int + + """ + auth: Authentication details for the request. + """ + auth: Auth + + """ + mode: The CORS mode of the request. + """ + mode: CORSMode + + """ + withCredentials: Indicates whether or not cross-site Access-Control requests should be made using credentials. + """ + withCredentials: Boolean + + """ + httpVersion: The HTTP version to use for the request. + """ + httpVersion: HTTPVersion + + """ + maxRedirects: The maximum number of redirects to follow for this request. If not set, defaults to system-configured value. + """ + maxRedirects: Int + + """ + proxy: The proxy settings to use for this request. + """ + proxy: Proxy + + """ + cookies: List of cookies to be included in the request. + """ + cookies: [Cookie!] + + """ + cache: The caching policy for this request. + """ + cache: CachePolicy } +""" +HTTPHeader: Represents a single HTTP header. +""" +type HTTPHeader { + """ + key: The name of the header. + """ + key: String! + + """ + value: The value of the header. + """ + value: String! +} + +""" +FormDataEntry: Represents a single form data entry. +""" type FormDataEntry { - """FormData entry key""" - name: String! - """If 'type' is defined, value is treated as a base64 byte string""" - value: String - """File name to report to the server""" - fileName: String - """MIME type (https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types). Defaults to empty string.""" - type: String + """ + name: The name of the form data entry. + """ + name: String! + + """ + value: The value of the form data entry, if any. + """ + value: String + + """ + fileName: The file name if the form data entry is a file. + """ + fileName: String + + """ + type: The content type of the form data entry. + """ + type: String } +""" +Auth: Represents the authentication details for an HTTP request. +At most one of the authentication methods can be used for a request. +""" +type Auth { + """ + basicAuth: Specifies the credentials for Basic Authentication. + """ + basicAuth: BasicAuth + + """ + digestAuth: Specifies the credentials for Digest Authentication. + """ + digestAuth: DigestAuth + + """ + bearerToken: Specifies the Bearer token for Bearer Token Authentication. + """ + bearerToken: BearerToken + + """ + oauth: Specifies the credentials for OAuth Authentication. + """ + oauth: OAuth +} + +""" +BasicAuth: Represents the credentials for Basic Authentication, which +transmits credentials as user ID/password pairs, encoded using base64. +""" +type BasicAuth { + """ + username: The username for Basic Authentication. + """ + username: String! + + """ + password: The password for Basic Authentication. + """ + password: String! +} + +""" +DigestAuth: Represents the credentials for Digest Authentication, which +is a method of HTTP authentication that applies a cryptographic function +to a password before sending it over the network. +""" +type DigestAuth { + """ + username: The username for Digest Authentication. + """ + username: String! + + """ + password: The password for Digest Authentication. + """ + password: String! + + """ + realm: A string that the server may provide to identify the protection space. + """ + realm: String + + """ + nonce: A server-specified data string which should be uniquely generated each time. + """ + nonce: String + + """ + uri: The URI from Request-URI of the Request-Line; duplicated here because proxies are allowed to change the Request-Line in transit. + """ + uri: String + + """ + response: A string of 32 hex digits computed as defined in RFC 2617, which proves that the user knows a password. + """ + response: String + + """ + opaque: A string of data, specified by the server, which should be returned by the client unchanged. + """ + opaque: String +} + +""" +BearerToken: Represents the Bearer token for Bearer Token Authentication, +which is an HTTP authentication scheme that involves security tokens called bearer tokens. +""" +type BearerToken { + """ + token: The bearer token which will be included in the request. + """ + token: String! +} + +""" +OAuth: Represents the credentials for OAuth Authentication, +which is a protocol that allows a user to grant a third-party website or application +access to their resources, without necessarily revealing their credentials. +""" +type OAuth { + """ + consumerKey: The consumer key for OAuth Authentication. + """ + consumerKey: String! + + """ + consumerSecret: The consumer secret for OAuth Authentication. + """ + consumerSecret: String! + + """ + accessToken: The access token for OAuth Authentication. + """ + accessToken: String! + + """ + tokenSecret: The token secret for OAuth Authentication. + """ + tokenSecret: String! +} + +""" +Proxy: Represents a proxy configuration. +""" +type Proxy { + """ + host: The hostname or IP address of the proxy server. + """ + host: String! + + """ + port: The port number of the proxy server. + """ + port: Int! + + """ + auth: The basic authentication credentials for the proxy server, if required. + """ + auth: BasicAuth +} + +""" +Cookie: Represents an HTTP cookie, a small piece of data stored on the user's computer by the web browser while browsing a website. +""" +type Cookie { + """ + name: The name of the cookie. This field is mandatory for a cookie. + """ + name: String! + + """ + value: The value of the cookie. This field is mandatory for a cookie. + """ + value: String! + + """ + domain: Specifies the domain for which the cookie is valid. An explicitly specified domain must always start with a dot. + """ + domain: String + + """ + path: Specifies a path that must exist in the requested URL for the browser to send the Cookie header. + """ + path: String + + """ + expires: The Unix timestamp (seconds since January 1st, 1970 at UTC) at which the cookie expires. If not set, the cookie will expire at the end of the session (when the browser closes). + """ + expires: Int + + """ + secure: If true, the cookie will only be sent over an encrypted connection (HTTPS). + """ + secure: Boolean + + """ + httpOnly: If true, the cookie is inaccessible to the JavaScript Document.cookie API; it is sent only to the server. For defense against cross-site scripting (XSS) attacks. + """ + httpOnly: Boolean + + """ + sameSite: The SameSite attribute of the cookie. This attribute allows you to declare if your cookie should be restricted to a first-party or same-site context. + """ + sameSite: CookieSameSitePolicy +} + +""" +CookieSameSitePolicy: Represents the SameSite policy of a cookie. +This attribute is used to assert that a cookie ought not to be sent along with cross-site requests. +""" +enum CookieSameSitePolicy { + """ + STRICT: The browser sends the cookie only for same-site requests (that is, requests originating from the same site that set the cookie). + If the request originated from a different URL than the URL of the current location, no cookies with the SameSite=Strict attribute are sent. + """ + STRICT + + """ + LAX: The browser sends the cookie for same-site requests, and for cross-site top-level navigation GET requests. + This is the default value in modern browsers when the SameSite attribute is not specified. + """ + LAX + + """ + NONE: The browser sends the cookie both for same-site and cross-site requests. + Note that the Secure attribute must be set when SameSite is set to None. + """ + NONE +} + +""" +CORSMode: Specifies how the CORS (Cross-Origin Resource Sharing) request is handled. +""" +enum CORSMode { + """ + CORS: Cross-origin request with explicit access control request headers. + """ + CORS + + """ + NO_CORS: Request without any CORS headers; limited to certain resource types. + """ + NO_CORS + + """ + SAME_ORIGIN: Request that only works within the same origin; CORS headers are ignored. + """ + SAME_ORIGIN +} + +""" +ResponseType: Specifies the expected format of the response from the server. +""" enum ResponseType { - TEXT - BINARY + """ + TEXT: The response should be returned in text format. + """ + TEXT + + """ + BINARY: The response should be returned in binary format (i.e. a base64 string). + """ + BINARY +} + +""" +HTTPMethod: Specifies the HTTP method to be used when making the request. +""" +enum HTTPMethod { + """ + GET: The HTTP GET method requests a representation of the specified resource. + """ + GET + + """ + POST: The HTTP POST method sends data to the server to create a new resource. + """ + POST + + """ + PUT: The HTTP PUT method updates a current resource with new data. + """ + PUT + + """ + DELETE: The HTTP DELETE method deletes the specified resource. + """ + DELETE + + """ + HEAD: The HTTP HEAD method asks for a response identical to that of a GET request, but without the response body. + """ + HEAD + + """ + PATCH: The HTTP PATCH method is used to apply partial modifications to a resource. + """ + PATCH + + """ + OPTIONS: The HTTP OPTIONS method describes the communication options for the target resource. + """ + OPTIONS +} + +""" +HTTPVersion: Specifies the version of HTTP to be used when making the request. +""" +enum HTTPVersion { + """ + HTTP1_1: Use HTTP version 1.1. + """ + HTTP1_1 + + """ + HTTP2: Use HTTP version 2. + """ + HTTP2 + + """ + HTTP3: Use HTTP version 3. + """ + HTTP3 +} + +""" +CachePolicy: Specifies the caching policy to be used for the request. +""" +enum CachePolicy { + """ + NO_CACHE: The resource must be fetched from the network and not from the cache. + """ + NO_CACHE + + """ + RELOAD: The resource must be fetched from the network, bypassing any cache. + """ + RELOAD + + """ + NO_STORE: The resource, once fetched, must not be stored in any cache. + """ + NO_STORE + + """ + FORCE_CACHE: The resource is fetched from the cache if available, otherwise from the network. + """ + FORCE_CACHE + + """ + ONLY_IF_CACHED: The resource is fetched only from the cache. + """ + ONLY_IF_CACHED } type Module { - get(url: String!, request: Request): Response - post(url: String!, request: Request): Response -} \ No newline at end of file + """ + Send an HTTP Request to the specified URL using the specified method. + """ + request(url: String!, method: HTTPMethod!, request: Request): Response + + """ + Sends a GET request to the specified URL. + """ + get(url: String!, request: Request): Response + + """ + Sends a POST request to the specified URL. + """ + post(url: String!, request: Request): Response + + """ + Sends a PUT request to the specified URL. + """ + put(url: String!, request: Request): Response + + """ + Sends a DELETE request to the specified URL. + """ + delete(url: String!, request: Request): Response + + """ + Sends a HEAD request to the specified URL. + """ + head(url: String!, request: Request): Response + + """ + Sends a PATCH request to the specified URL. + """ + patch(url: String!, request: Request): Response + + """ + Sends a OPTIONS request to the specified URL. + """ + options(url: String!, request: Request): Response +} diff --git a/interface/polywrap.yaml b/interface/polywrap.yaml index 09bc732..761683d 100644 --- a/interface/polywrap.yaml +++ b/interface/polywrap.yaml @@ -4,4 +4,3 @@ project: type: interface source: schema: ./polywrap.graphql -resources: ./resources diff --git a/interface/resources/README.md b/interface/resources/README.md index 76ff1de..66705d8 100644 --- a/interface/resources/README.md +++ b/interface/resources/README.md @@ -1,65 +1,161 @@ -# HTTP Wrapper Interface +# Datetime Wrapper Interface -| Version | URI | WRAP Version | -|-|-|-| -| 1.0.0 | [`wrap://ens/wraps.eth:http@1.0.0`](https://wrappers.io/v/ens/wraps.eth:http@1.0.0) | 0.1 | -| 1.1.0 | [`wrap://ens/wraps.eth:http@1.1.0`](https://wrappers.io/v/ens/wraps.eth:http@1.1.0) | 0.1 | +| Version | URI | WRAP Version | +|---------|-------------------------------------------------------------------------------------|-| +| 2.0.0 | [`wrap://ens/wraps.eth:http@2.0.0`](https://wrappers.io/v/ens/wraps.eth:http@2.0.0) | 0.1 | ## Interface ```graphql type Response { status: Int! statusText: String! - headers: Map @annotate(type: "Map") + headers: [HTTPHeader!] body: String + httpVersion: HTTPVersion! + cookies: [Cookie!] } type Request { - headers: Map @annotate(type: "Map") + headers: [HTTPHeader!] urlParams: Map @annotate(type: "Map") responseType: ResponseType! - """The body of the request. If present, the `formData` property will be ignored.""" body: String - """ - An alternative to the standard request body, 'formData' is expected to be in the 'multipart/form-data' format. - If present, the `body` property is not null, `formData` will be ignored. - Otherwise, if formData is not null, the following header will be added to the request: 'Content-Type: multipart/form-data'. - """ formData: [FormDataEntry!] - timeout: UInt32 + timeout: Int + auth: Auth + mode: CORSMode + withCredentials: Boolean + httpVersion: HTTPVersion + maxRedirects: Int + proxy: Proxy + cookies: [Cookie!] + cache: CachePolicy +} + +type HTTPHeader { + key: String! + value: String! } type FormDataEntry { - """FormData entry key""" name: String! - """If 'type' is defined, value is treated as a base64 byte string""" value: String - """File name to report to the server""" fileName: String - """MIME type (https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types). Defaults to empty string.""" type: String } +type Auth { + basicAuth: BasicAuth + digestAuth: DigestAuth + bearerToken: BearerToken + oauth: OAuth +} + +type BasicAuth { + username: String! + password: String! +} + +type DigestAuth { + username: String! + password: String! + realm: String + nonce: String + uri: String + response: String + opaque: String +} + +type BearerToken { + token: String! +} + +type OAuth { + consumerKey: String! + consumerSecret: String! + accessToken: String! + tokenSecret: String! +} + +type Proxy { + host: String! + port: Int! + auth: BasicAuth +} + +type Cookie { + name: String! + value: String! + domain: String + path: String + expires: Int + secure: Boolean + httpOnly: Boolean + sameSite: CookieSameSitePolicy +} + +enum CookieSameSitePolicy { + STRICT + LAX + NONE +} + +enum CORSMode { + CORS + NO_CORS + SAME_ORIGIN +} + enum ResponseType { TEXT BINARY } +enum HTTPMethod { + GET + POST + PUT + DELETE + HEAD + PATCH + OPTIONS +} + +enum HTTPVersion { + HTTP1_1 + HTTP2 + HTTP3 +} + +enum CachePolicy { + NO_CACHE + RELOAD + NO_STORE + FORCE_CACHE + ONLY_IF_CACHED +} + type Module { + request(url: String!, method: HTTPMethod!, request: Request): Response get(url: String!, request: Request): Response post(url: String!, request: Request): Response + put(url: String!, request: Request): Response + delete(url: String!, request: Request): Response + head(url: String!, request: Request): Response + patch(url: String!, request: Request): Response + options(url: String!, request: Request): Response } ``` ## Usage ```graphql -#import * from "ens/wraps.eth:http@1.1.0" +#import * from "ens/wraps.eth:http@2.0.0" ``` -And implement the `get` + `post` methods within your programming language of choice. +And implement the interface methods within your programming language of choice. ## Source Code -[Link](https://github.com/polywrap/http) +[Link](https://github.com/polywrap/std/http) ## Known Implementations [Link](https://github.com/polywrap/http/tree/master/implementations) \ No newline at end of file diff --git a/interface/yarn.lock b/interface/yarn.lock index a01bc36..a0ae00c 100644 --- a/interface/yarn.lock +++ b/interface/yarn.lock @@ -728,10 +728,10 @@ "@polywrap/core-js" "0.10.0-pre.10" "@polywrap/plugin-js" "0.10.0-pre.10" -"@polywrap/logging-js@0.10.2": - version "0.10.2" - resolved "https://registry.yarnpkg.com/@polywrap/logging-js/-/logging-js-0.10.2.tgz#cc89544e82440400de682ed7af4ad0eaef89f864" - integrity sha512-mglQRHNJULl3F4YPRPkUUL1Zp/IjRfaNarXgXR4NLlEINU3+pzshGuJoMGCj2/mUWjsox3L8OjfzCjVBy+N+vw== +"@polywrap/logging-js@0.10.3": + version "0.10.3" + resolved "https://registry.yarnpkg.com/@polywrap/logging-js/-/logging-js-0.10.3.tgz#356524d3b7381da3621138e2b68363055e253e71" + integrity sha512-3zQe6cWz5RWXttoPLlQiWOHKHwrYixKV80Ob49+ntpLxJ2ymEa2ZZMQChFCBYyl/F39JMolKNX4qWGjSK0V86w== "@polywrap/msgpack-js@0.10.0": version "0.10.0" @@ -754,10 +754,10 @@ dependencies: "@msgpack/msgpack" "2.7.2" -"@polywrap/os-js@0.10.2": - version "0.10.2" - resolved "https://registry.yarnpkg.com/@polywrap/os-js/-/os-js-0.10.2.tgz#26ea20d96ffbe328900bc6bf6b646a9d1cbcac9a" - integrity sha512-bTShjmw9vBcI6ZdC/rLdFlWuWXh2Xha6B/He+vzA4/vF5I9eyAxABfrsl4/ySqFFSsLdMITeQRzyFQXfcd0+FQ== +"@polywrap/os-js@0.10.3": + version "0.10.3" + resolved "https://registry.yarnpkg.com/@polywrap/os-js/-/os-js-0.10.3.tgz#980ca439c25265ef1450467286324edae650c3c2" + integrity sha512-if6LYsRsRGJcMl65nBVTimjzPpz4xfa7OjhfYzRdmASTVeOSEn4bdIm5PVAGOA+jEzVv1HQ0pFnF+n08tfjlUA== "@polywrap/plugin-js@0.10.0": version "0.10.0" @@ -792,18 +792,18 @@ "@polywrap/tracing-js" "0.10.0-pre.12" "@polywrap/wrap-manifest-types-js" "0.10.0-pre.12" -"@polywrap/polywrap-manifest-schemas@0.10.2": - version "0.10.2" - resolved "https://registry.yarnpkg.com/@polywrap/polywrap-manifest-schemas/-/polywrap-manifest-schemas-0.10.2.tgz#369c9e12d9260b971ac2ff57dda2b886595435bb" - integrity sha512-5AggU1dz6pIXs0FfpxToyXcZdF31+3Ap3TdmOCnlOImhTDiYBaHj9wnvaffIm5TCe97QTTiND7KSljKtMd51Pg== +"@polywrap/polywrap-manifest-schemas@0.10.3": + version "0.10.3" + resolved "https://registry.yarnpkg.com/@polywrap/polywrap-manifest-schemas/-/polywrap-manifest-schemas-0.10.3.tgz#4da56f8d35849366e6f66bbcaf90c95b468d9fb2" + integrity sha512-XzIzDbtQLqa6/W+130r/STTnSbphn23gfdkKiyju6Yws9NSW5zFwnr26CcHEuQLIHXjacTcV2ULYDOTwoJLXlA== -"@polywrap/polywrap-manifest-types-js@0.10.2": - version "0.10.2" - resolved "https://registry.yarnpkg.com/@polywrap/polywrap-manifest-types-js/-/polywrap-manifest-types-js-0.10.2.tgz#5777888497429db6767c68ba2cf8ae1e4c0a44b3" - integrity sha512-bHlCp74W0dXMPI3ZZslTIWIuHMVaWKRv/OQ6UAS+d1pMoIgDdAA5xkNorW+rfRaRQWeGMTRdqBi7i/PPh+mrYA== +"@polywrap/polywrap-manifest-types-js@0.10.3": + version "0.10.3" + resolved "https://registry.yarnpkg.com/@polywrap/polywrap-manifest-types-js/-/polywrap-manifest-types-js-0.10.3.tgz#9be5d23f0efa93ebd500fa4f9c3af1ff75124d07" + integrity sha512-oPlUNh++goGoWPmZvdt4fv10JpHARf5Yniwt6JTGVqb/JdhKjQggRU92NIFMRs+KHDx1qqivwl1FtQV5Dk/cyQ== dependencies: - "@polywrap/logging-js" "0.10.2" - "@polywrap/polywrap-manifest-schemas" "0.10.2" + "@polywrap/logging-js" "0.10.3" + "@polywrap/polywrap-manifest-schemas" "0.10.3" jsonschema "1.4.0" semver "7.5.0" yaml "2.2.2" @@ -823,30 +823,30 @@ resolved "https://registry.yarnpkg.com/@polywrap/result/-/result-0.10.0-pre.12.tgz#530f8f5ced2bef189466f9fb8b41a520b12e9372" integrity sha512-KnGRJMBy1SCJt3mymO3ob0e1asqYOyY+NNKySQ5ocvG/iMlhtODs4dy2EeEtcIFZ+c7TyBPVD4SI863qHQGOUQ== -"@polywrap/schema-bind@0.10.2": - version "0.10.2" - resolved "https://registry.yarnpkg.com/@polywrap/schema-bind/-/schema-bind-0.10.2.tgz#219c5fe618357be2d83a28739cf7048706cbbd7d" - integrity sha512-7PObwLAgdd/uwReG1yi70SvtlFlL4KtYqBaLtjQeDO8Iocx0y+MnI11VnGdAI/vY+Qu8L5IlG3yFN/hhXZu5hQ== +"@polywrap/schema-bind@0.10.3": + version "0.10.3" + resolved "https://registry.yarnpkg.com/@polywrap/schema-bind/-/schema-bind-0.10.3.tgz#15b35bed1f045ca817184e7b897678d7eb810ef2" + integrity sha512-TLyX+nVXr/Hw18KC58KJvKYNxF888wjaqtrQvPN8ZmSCu++pRhZDMG0WaBDid+NKELrFpnRkBSnC7SKDRyBzBQ== dependencies: - "@polywrap/os-js" "0.10.2" - "@polywrap/schema-parse" "0.10.2" + "@polywrap/os-js" "0.10.3" + "@polywrap/schema-parse" "0.10.3" "@polywrap/wrap-manifest-types-js" "0.10.0" mustache "4.0.1" -"@polywrap/schema-compose@0.10.2": - version "0.10.2" - resolved "https://registry.yarnpkg.com/@polywrap/schema-compose/-/schema-compose-0.10.2.tgz#6a4bf769605d5508e4ab5655b8e5a3526b1640b3" - integrity sha512-S1b0W2yhqLZduXVVh2k18aQ96SFoqmmQOxXL8zG4dbOOFs1k5VvO45rKHhC/Yy8TmT0TGs0IWSiU5Iq5P6KdGA== +"@polywrap/schema-compose@0.10.3": + version "0.10.3" + resolved "https://registry.yarnpkg.com/@polywrap/schema-compose/-/schema-compose-0.10.3.tgz#44c5540e4dca823cea3ac892d110c665ce6c10d1" + integrity sha512-heMq61cKvSQB6PORRjYnKDwGIVqcSHM1Co5v994vf3eBwGHNTmfkeTGspmdotgF9uwRp2yG038Leijni55o4cQ== dependencies: - "@polywrap/schema-parse" "0.10.2" + "@polywrap/schema-parse" "0.10.3" "@polywrap/wrap-manifest-types-js" "0.10.0" graphql "15.5.0" mustache "4.0.1" -"@polywrap/schema-parse@0.10.2": - version "0.10.2" - resolved "https://registry.yarnpkg.com/@polywrap/schema-parse/-/schema-parse-0.10.2.tgz#d4436555602dbd645051a5686ec05a342f749a99" - integrity sha512-9lO5l4pOlc4+VW4XJrWEXkiXjtsUvqiiZRJAX57Q58zRXenUrDq/DS4SukmY+Bls8By+4+WMya+Mgfg4LZS7kQ== +"@polywrap/schema-parse@0.10.3": + version "0.10.3" + resolved "https://registry.yarnpkg.com/@polywrap/schema-parse/-/schema-parse-0.10.3.tgz#9dbb146eb9fbac8a4e4fd258500d0658a2c3a718" + integrity sha512-3ksFvk/adVsR5StLJ5OK26OYhP9lYIBr0ipZMVMyA3c+2DGN7LH8i9Hn3v5tJgjvojzwAIWyNWBrbUBTIV2Tsg== dependencies: "@dorgjelli/graphql-schema-cycles" "1.1.4" "@polywrap/wrap-manifest-types-js" "0.10.0" @@ -2457,10 +2457,10 @@ picomatch@^2.0.4, picomatch@^2.2.1: resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== -polywrap@0.10.2: - version "0.10.2" - resolved "https://registry.yarnpkg.com/polywrap/-/polywrap-0.10.2.tgz#ed70f76459c7a57c99932aea220b1ccba054e778" - integrity sha512-MH28MdM9XcdE2Y3kvK8wyvJ7GXKe9X34i3IdbcrGzy/tc1ki3RAzUazse7tLMX1qnatUsJSgNC+wF8Bfae/Jhg== +polywrap@0.10.3: + version "0.10.3" + resolved "https://registry.yarnpkg.com/polywrap/-/polywrap-0.10.3.tgz#3c476b2116fa4a0351406df0cc86165bff8edff5" + integrity sha512-3VC+CKaLgYLjsnvJGK9TAhYESXpFOk2BrtQAnkK2J+/B0ppqT0DfNLcHeutOjqPQ/9TMmXbLQ7ljnAov2hzyMQ== dependencies: "@apidevtools/json-schema-ref-parser" "9.0.9" "@ethersproject/providers" "5.6.8" @@ -2471,13 +2471,13 @@ polywrap@0.10.2: "@polywrap/client-js" "0.10.0" "@polywrap/core-js" "0.10.0" "@polywrap/ethereum-provider-js-v1" "npm:@polywrap/ethereum-provider-js@~0.2.4" - "@polywrap/logging-js" "0.10.2" - "@polywrap/os-js" "0.10.2" - "@polywrap/polywrap-manifest-types-js" "0.10.2" + "@polywrap/logging-js" "0.10.3" + "@polywrap/os-js" "0.10.3" + "@polywrap/polywrap-manifest-types-js" "0.10.3" "@polywrap/result" "0.10.0" - "@polywrap/schema-bind" "0.10.2" - "@polywrap/schema-compose" "0.10.2" - "@polywrap/schema-parse" "0.10.2" + "@polywrap/schema-bind" "0.10.3" + "@polywrap/schema-compose" "0.10.3" + "@polywrap/schema-parse" "0.10.3" "@polywrap/uri-resolver-extensions-js" "0.10.0" "@polywrap/uri-resolvers-js" "0.10.0" "@polywrap/wasm-js" "0.10.0" From 723cd2341c5971e70d3427ef7ea60c14adf792d3 Mon Sep 17 00:00:00 2001 From: krisbitney Date: Thu, 8 Jun 2023 16:57:29 -0500 Subject: [PATCH 2/3] significantly simplified http interface --- interface/polywrap.graphql | 421 +--------------------------------- interface/resources/README.md | 110 +-------- 2 files changed, 7 insertions(+), 524 deletions(-) diff --git a/interface/polywrap.graphql b/interface/polywrap.graphql index e7c2660..77e63d0 100644 --- a/interface/polywrap.graphql +++ b/interface/polywrap.graphql @@ -13,24 +13,14 @@ type Response { statusText: String! """ - headers: List of HTTP headers in the response. + headers: HTTP headers in the response. """ - headers: [HTTPHeader!] + headers: Map @annotate(type: "Map") """ body: The body of the response, if any. """ body: String - - """ - httpVersion: The HTTP version used in the response. - """ - httpVersion: HTTPVersion! - - """ - cookies: List of cookies sent in the response. - """ - cookies: [Cookie!] } """ @@ -38,9 +28,9 @@ Request: Represents an HTTP request to be sent to a server. """ type Request { """ - headers: List of HTTP headers to be included in the request. + headers: HTTP headers to be included in the request. """ - headers: [HTTPHeader!] + headers: Map @annotate(type: "Map") """ urlParams: Query parameters to be appended to the request URL. @@ -53,330 +43,14 @@ type Request { responseType: ResponseType! """ - body: The body of the request, if any. If body is present, formData is ignored. + body: The body of the request, if any. """ body: String - """ - formData: List of form data entries to be included in the request, if body is not present. - """ - formData: [FormDataEntry!] - """ timeout: Timeout for the request in milliseconds. If not set, the request will not timeout. """ timeout: Int - - """ - auth: Authentication details for the request. - """ - auth: Auth - - """ - mode: The CORS mode of the request. - """ - mode: CORSMode - - """ - withCredentials: Indicates whether or not cross-site Access-Control requests should be made using credentials. - """ - withCredentials: Boolean - - """ - httpVersion: The HTTP version to use for the request. - """ - httpVersion: HTTPVersion - - """ - maxRedirects: The maximum number of redirects to follow for this request. If not set, defaults to system-configured value. - """ - maxRedirects: Int - - """ - proxy: The proxy settings to use for this request. - """ - proxy: Proxy - - """ - cookies: List of cookies to be included in the request. - """ - cookies: [Cookie!] - - """ - cache: The caching policy for this request. - """ - cache: CachePolicy -} - -""" -HTTPHeader: Represents a single HTTP header. -""" -type HTTPHeader { - """ - key: The name of the header. - """ - key: String! - - """ - value: The value of the header. - """ - value: String! -} - -""" -FormDataEntry: Represents a single form data entry. -""" -type FormDataEntry { - """ - name: The name of the form data entry. - """ - name: String! - - """ - value: The value of the form data entry, if any. - """ - value: String - - """ - fileName: The file name if the form data entry is a file. - """ - fileName: String - - """ - type: The content type of the form data entry. - """ - type: String -} - -""" -Auth: Represents the authentication details for an HTTP request. -At most one of the authentication methods can be used for a request. -""" -type Auth { - """ - basicAuth: Specifies the credentials for Basic Authentication. - """ - basicAuth: BasicAuth - - """ - digestAuth: Specifies the credentials for Digest Authentication. - """ - digestAuth: DigestAuth - - """ - bearerToken: Specifies the Bearer token for Bearer Token Authentication. - """ - bearerToken: BearerToken - - """ - oauth: Specifies the credentials for OAuth Authentication. - """ - oauth: OAuth -} - -""" -BasicAuth: Represents the credentials for Basic Authentication, which -transmits credentials as user ID/password pairs, encoded using base64. -""" -type BasicAuth { - """ - username: The username for Basic Authentication. - """ - username: String! - - """ - password: The password for Basic Authentication. - """ - password: String! -} - -""" -DigestAuth: Represents the credentials for Digest Authentication, which -is a method of HTTP authentication that applies a cryptographic function -to a password before sending it over the network. -""" -type DigestAuth { - """ - username: The username for Digest Authentication. - """ - username: String! - - """ - password: The password for Digest Authentication. - """ - password: String! - - """ - realm: A string that the server may provide to identify the protection space. - """ - realm: String - - """ - nonce: A server-specified data string which should be uniquely generated each time. - """ - nonce: String - - """ - uri: The URI from Request-URI of the Request-Line; duplicated here because proxies are allowed to change the Request-Line in transit. - """ - uri: String - - """ - response: A string of 32 hex digits computed as defined in RFC 2617, which proves that the user knows a password. - """ - response: String - - """ - opaque: A string of data, specified by the server, which should be returned by the client unchanged. - """ - opaque: String -} - -""" -BearerToken: Represents the Bearer token for Bearer Token Authentication, -which is an HTTP authentication scheme that involves security tokens called bearer tokens. -""" -type BearerToken { - """ - token: The bearer token which will be included in the request. - """ - token: String! -} - -""" -OAuth: Represents the credentials for OAuth Authentication, -which is a protocol that allows a user to grant a third-party website or application -access to their resources, without necessarily revealing their credentials. -""" -type OAuth { - """ - consumerKey: The consumer key for OAuth Authentication. - """ - consumerKey: String! - - """ - consumerSecret: The consumer secret for OAuth Authentication. - """ - consumerSecret: String! - - """ - accessToken: The access token for OAuth Authentication. - """ - accessToken: String! - - """ - tokenSecret: The token secret for OAuth Authentication. - """ - tokenSecret: String! -} - -""" -Proxy: Represents a proxy configuration. -""" -type Proxy { - """ - host: The hostname or IP address of the proxy server. - """ - host: String! - - """ - port: The port number of the proxy server. - """ - port: Int! - - """ - auth: The basic authentication credentials for the proxy server, if required. - """ - auth: BasicAuth -} - -""" -Cookie: Represents an HTTP cookie, a small piece of data stored on the user's computer by the web browser while browsing a website. -""" -type Cookie { - """ - name: The name of the cookie. This field is mandatory for a cookie. - """ - name: String! - - """ - value: The value of the cookie. This field is mandatory for a cookie. - """ - value: String! - - """ - domain: Specifies the domain for which the cookie is valid. An explicitly specified domain must always start with a dot. - """ - domain: String - - """ - path: Specifies a path that must exist in the requested URL for the browser to send the Cookie header. - """ - path: String - - """ - expires: The Unix timestamp (seconds since January 1st, 1970 at UTC) at which the cookie expires. If not set, the cookie will expire at the end of the session (when the browser closes). - """ - expires: Int - - """ - secure: If true, the cookie will only be sent over an encrypted connection (HTTPS). - """ - secure: Boolean - - """ - httpOnly: If true, the cookie is inaccessible to the JavaScript Document.cookie API; it is sent only to the server. For defense against cross-site scripting (XSS) attacks. - """ - httpOnly: Boolean - - """ - sameSite: The SameSite attribute of the cookie. This attribute allows you to declare if your cookie should be restricted to a first-party or same-site context. - """ - sameSite: CookieSameSitePolicy -} - -""" -CookieSameSitePolicy: Represents the SameSite policy of a cookie. -This attribute is used to assert that a cookie ought not to be sent along with cross-site requests. -""" -enum CookieSameSitePolicy { - """ - STRICT: The browser sends the cookie only for same-site requests (that is, requests originating from the same site that set the cookie). - If the request originated from a different URL than the URL of the current location, no cookies with the SameSite=Strict attribute are sent. - """ - STRICT - - """ - LAX: The browser sends the cookie for same-site requests, and for cross-site top-level navigation GET requests. - This is the default value in modern browsers when the SameSite attribute is not specified. - """ - LAX - - """ - NONE: The browser sends the cookie both for same-site and cross-site requests. - Note that the Secure attribute must be set when SameSite is set to None. - """ - NONE -} - -""" -CORSMode: Specifies how the CORS (Cross-Origin Resource Sharing) request is handled. -""" -enum CORSMode { - """ - CORS: Cross-origin request with explicit access control request headers. - """ - CORS - - """ - NO_CORS: Request without any CORS headers; limited to certain resource types. - """ - NO_CORS - - """ - SAME_ORIGIN: Request that only works within the same origin; CORS headers are ignored. - """ - SAME_ORIGIN } """ @@ -434,94 +108,9 @@ enum HTTPMethod { OPTIONS } -""" -HTTPVersion: Specifies the version of HTTP to be used when making the request. -""" -enum HTTPVersion { - """ - HTTP1_1: Use HTTP version 1.1. - """ - HTTP1_1 - - """ - HTTP2: Use HTTP version 2. - """ - HTTP2 - - """ - HTTP3: Use HTTP version 3. - """ - HTTP3 -} - -""" -CachePolicy: Specifies the caching policy to be used for the request. -""" -enum CachePolicy { - """ - NO_CACHE: The resource must be fetched from the network and not from the cache. - """ - NO_CACHE - - """ - RELOAD: The resource must be fetched from the network, bypassing any cache. - """ - RELOAD - - """ - NO_STORE: The resource, once fetched, must not be stored in any cache. - """ - NO_STORE - - """ - FORCE_CACHE: The resource is fetched from the cache if available, otherwise from the network. - """ - FORCE_CACHE - - """ - ONLY_IF_CACHED: The resource is fetched only from the cache. - """ - ONLY_IF_CACHED -} - type Module { """ Send an HTTP Request to the specified URL using the specified method. """ request(url: String!, method: HTTPMethod!, request: Request): Response - - """ - Sends a GET request to the specified URL. - """ - get(url: String!, request: Request): Response - - """ - Sends a POST request to the specified URL. - """ - post(url: String!, request: Request): Response - - """ - Sends a PUT request to the specified URL. - """ - put(url: String!, request: Request): Response - - """ - Sends a DELETE request to the specified URL. - """ - delete(url: String!, request: Request): Response - - """ - Sends a HEAD request to the specified URL. - """ - head(url: String!, request: Request): Response - - """ - Sends a PATCH request to the specified URL. - """ - patch(url: String!, request: Request): Response - - """ - Sends a OPTIONS request to the specified URL. - """ - options(url: String!, request: Request): Response } diff --git a/interface/resources/README.md b/interface/resources/README.md index 66705d8..5d1b748 100644 --- a/interface/resources/README.md +++ b/interface/resources/README.md @@ -9,101 +9,16 @@ type Response { status: Int! statusText: String! - headers: [HTTPHeader!] + headers: Map @annotate(type: "Map") body: String - httpVersion: HTTPVersion! - cookies: [Cookie!] } type Request { - headers: [HTTPHeader!] + headers: Map @annotate(type: "Map") urlParams: Map @annotate(type: "Map") responseType: ResponseType! body: String - formData: [FormDataEntry!] timeout: Int - auth: Auth - mode: CORSMode - withCredentials: Boolean - httpVersion: HTTPVersion - maxRedirects: Int - proxy: Proxy - cookies: [Cookie!] - cache: CachePolicy -} - -type HTTPHeader { - key: String! - value: String! -} - -type FormDataEntry { - name: String! - value: String - fileName: String - type: String -} - -type Auth { - basicAuth: BasicAuth - digestAuth: DigestAuth - bearerToken: BearerToken - oauth: OAuth -} - -type BasicAuth { - username: String! - password: String! -} - -type DigestAuth { - username: String! - password: String! - realm: String - nonce: String - uri: String - response: String - opaque: String -} - -type BearerToken { - token: String! -} - -type OAuth { - consumerKey: String! - consumerSecret: String! - accessToken: String! - tokenSecret: String! -} - -type Proxy { - host: String! - port: Int! - auth: BasicAuth -} - -type Cookie { - name: String! - value: String! - domain: String - path: String - expires: Int - secure: Boolean - httpOnly: Boolean - sameSite: CookieSameSitePolicy -} - -enum CookieSameSitePolicy { - STRICT - LAX - NONE -} - -enum CORSMode { - CORS - NO_CORS - SAME_ORIGIN } enum ResponseType { @@ -121,29 +36,8 @@ enum HTTPMethod { OPTIONS } -enum HTTPVersion { - HTTP1_1 - HTTP2 - HTTP3 -} - -enum CachePolicy { - NO_CACHE - RELOAD - NO_STORE - FORCE_CACHE - ONLY_IF_CACHED -} - type Module { request(url: String!, method: HTTPMethod!, request: Request): Response - get(url: String!, request: Request): Response - post(url: String!, request: Request): Response - put(url: String!, request: Request): Response - delete(url: String!, request: Request): Response - head(url: String!, request: Request): Response - patch(url: String!, request: Request): Response - options(url: String!, request: Request): Response } ``` From c468b0486772c30dd659961eeef0b52f5f270375 Mon Sep 17 00:00:00 2001 From: krisbitney Date: Thu, 8 Jun 2023 17:24:03 -0500 Subject: [PATCH 3/3] Further simplified http interface --- interface/polywrap.graphql | 59 ++++++++++++++++------------------- interface/resources/README.md | 13 +++----- 2 files changed, 32 insertions(+), 40 deletions(-) diff --git a/interface/polywrap.graphql b/interface/polywrap.graphql index 77e63d0..62aac58 100644 --- a/interface/polywrap.graphql +++ b/interface/polywrap.graphql @@ -28,89 +28,84 @@ Request: Represents an HTTP request to be sent to a server. """ type Request { """ - headers: HTTP headers to be included in the request. + The request destination """ - headers: Map @annotate(type: "Map") + url: String!, """ - urlParams: Query parameters to be appended to the request URL. + The HTTP request method to use """ - urlParams: Map @annotate(type: "Map") + method: HTTPMethod!, """ - responseType: Desired format of the response. + HTTP headers to be included in the request. """ - responseType: ResponseType! + headers: Map @annotate(type: "Map") """ - body: The body of the request, if any. + The body of the request, if any. """ body: String """ - timeout: Timeout for the request in milliseconds. If not set, the request will not timeout. + Timeout for the request in milliseconds. If not set, the request will not timeout. """ timeout: Int } """ -ResponseType: Specifies the expected format of the response from the server. -""" -enum ResponseType { - """ - TEXT: The response should be returned in text format. - """ - TEXT - - """ - BINARY: The response should be returned in binary format (i.e. a base64 string). - """ - BINARY -} - -""" -HTTPMethod: Specifies the HTTP method to be used when making the request. +Specifies the HTTP method to be used when making the request. """ enum HTTPMethod { """ - GET: The HTTP GET method requests a representation of the specified resource. + The HTTP GET method requests a representation of the specified resource. """ GET """ - POST: The HTTP POST method sends data to the server to create a new resource. + The HTTP POST method sends data to the server to create a new resource. """ POST """ - PUT: The HTTP PUT method updates a current resource with new data. + The HTTP PUT method updates a current resource with new data. """ PUT """ - DELETE: The HTTP DELETE method deletes the specified resource. + The HTTP DELETE method deletes the specified resource. """ DELETE """ - HEAD: The HTTP HEAD method asks for a response identical to that of a GET request, but without the response body. + The HTTP HEAD method asks for a response identical to that of a GET request, but without the response body. """ HEAD """ - PATCH: The HTTP PATCH method is used to apply partial modifications to a resource. + The HTTP PATCH method is used to apply partial modifications to a resource. """ PATCH """ - OPTIONS: The HTTP OPTIONS method describes the communication options for the target resource. + The HTTP OPTIONS method describes the communication options for the target resource. """ OPTIONS + + """ + The HTTP CONNECT method is used by the client to establish a network connection to a web resource via HTTP, usually to facilitate HTTPS-secured communication (SSL Tunneling). + """ + CONNECT + + """ + The HTTP TRACE method performs a message loop-back test along the path to the target resource, providing a useful diagnostic tool for seeing what's being received at the other end. + """ + TRACE } type Module { """ Send an HTTP Request to the specified URL using the specified method. """ - request(url: String!, method: HTTPMethod!, request: Request): Response + request(request: Request): Response } diff --git a/interface/resources/README.md b/interface/resources/README.md index 5d1b748..4db61dc 100644 --- a/interface/resources/README.md +++ b/interface/resources/README.md @@ -14,18 +14,13 @@ type Response { } type Request { + url: String! + method: HTTPMethod! headers: Map @annotate(type: "Map") - urlParams: Map @annotate(type: "Map") - responseType: ResponseType! body: String timeout: Int } -enum ResponseType { - TEXT - BINARY -} - enum HTTPMethod { GET POST @@ -34,10 +29,12 @@ enum HTTPMethod { HEAD PATCH OPTIONS + CONNECT + TRACE } type Module { - request(url: String!, method: HTTPMethod!, request: Request): Response + request(request: Request): Response } ```