Page Not Found
We could not find what you were looking for.
Please contact the owner of the site that linked you to the original URL and let them know their link is broken.
diff --git a/404.html b/404.html index b6e663cb1..d6ad29f9b 100644 --- a/404.html +++ b/404.html @@ -10,10 +10,10 @@ - + - - + +
We could not find what you were looking for.
Please contact the owner of the site that linked you to the original URL and let them know their link is broken.
@http
Directive Definition",id:"http-directive-definition",level:2},{value:"Example: Basic Usage of @http
",id:"example-basic-usage-of-http",level:2},{value:"Directive Arguments",id:"directive-arguments",level:2},{value:"url",id:"url",level:3},{value:"method",id:"method",level:3},{value:"query",id:"query",level:3},{value:"Query Fields:",id:"query-fields",level:4},{value:"body",id:"body",level:3},{value:"headers",id:"headers",level:3},{value:"batchKey",id:"batchkey",level:3},{value:"onRequest",id:"onrequest",level:3},{value:"onResponseBody",id:"onresponsebody",level:3},{value:"select",id:"select",level:3},{value:"dedupe",id:"dedupe",level:3},{value:"Batching with POST Requests",id:"batching-with-post-requests",level:2},{value:"Mechanism",id:"mechanism",level:3},{value:"Configuration",id:"configuration",level:3},{value:"Current Limitations",id:"current-limitations",level:3},{value:"Combining Multiple Directives",id:"combining-multiple-directives",level:2}];function o(e){const s={a:"a",admonition:"admonition",code:"code",h2:"h2",h3:"h3",h4:"h4",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)(s.p,{children:["The ",(0,r.jsx)(s.code,{children:"@http"})," directive enables GraphQL fields to be resolved using REST API endpoints, simplifying the integration of external data sources."]}),"\n",(0,r.jsxs)(s.h2,{id:"http-directive-definition",children:[(0,r.jsx)(s.code,{children:"@http"})," Directive Definition"]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-graphql",metastring:'title="Directive Definition" showLineNumbers',children:"directive @http(\n url: String!\n method: Method\n query: [InputKeyValue!]\n body: JSON\n headers: [InputKeyValue!]\n batchKey: [String!]\n onRequest: String\n onResponseBody: String\n select: JSON\n dedupe: Boolean\n) on FIELD_DEFINITION\n"})}),"\n",(0,r.jsxs)(s.h2,{id:"example-basic-usage-of-http",children:["Example: Basic Usage of ",(0,r.jsx)(s.code,{children:"@http"})]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-graphql",metastring:"showLineNumbers",children:'type Query {\n users: [User]\n @http(url: "https://jsonplaceholder.typicode.com/users")\n}\n'})}),"\n",(0,r.jsxs)(s.p,{children:["In this example, adding the ",(0,r.jsx)(s.code,{children:"@http"})," directive to the ",(0,r.jsx)(s.code,{children:"users"})," field of the ",(0,r.jsx)(s.code,{children:"Query"})," type indicates reliance on a REST API for the ",(0,r.jsx)(s.code,{children:"users"})," field. The ",(0,r.jsx)(s.a,{href:"#url",children:"url"})," argument specifies the REST API's url, which is ",(0,r.jsx)(s.code,{children:"https://jsonplaceholder.typicode.com/users"})," in this scenario. Querying the ",(0,r.jsx)(s.code,{children:"users"})," field prompts the GraphQL server to issue a GET request to ",(0,r.jsx)(s.code,{children:"https://jsonplaceholder.typicode.com/users"}),"."]}),"\n",(0,r.jsx)(s.h2,{id:"directive-arguments",children:"Directive Arguments"}),"\n",(0,r.jsx)(s.h3,{id:"url",children:"url"}),"\n",(0,r.jsxs)(s.p,{children:["The ",(0,r.jsx)(s.code,{children:"url"})," parameter defines the API endpoint. It can also contain dynamic segments with Mustache templates for variable substitution:"]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-graphql",metastring:"showLineNumbers",children:'type Query {\n user(id: ID!): User\n @http(\n url: "https://jsonplaceholder.typicode.com/users/{{.args.id}}"\n )\n}\n'})}),"\n",(0,r.jsx)(s.h3,{id:"method",children:"method"}),"\n",(0,r.jsxs)(s.p,{children:["Specifies the HTTP method for the request. Defaults to ",(0,r.jsx)(s.code,{children:"GET"})," if not specified:"]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-graphql",metastring:"showLineNumbers",children:'type Mutation {\n createUser(input: UserInput!): User\n @http(\n method: "POST"\n url: "https://jsonplaceholder.typicode.com/users"\n )\n}\n'})}),"\n",(0,r.jsx)(s.h3,{id:"query",children:"query"}),"\n",(0,r.jsx)(s.p,{children:"Represents the API call's query parameters, either as a static object or with dynamic parameters using Mustache templates. These parameters append to the URL."}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-graphql",metastring:"showLineNumbers",children:'type Query {\n userPosts(id: ID!): [Post]\n @http(\n url: "https://jsonplaceholder.typicode.com/posts"\n query: [\n {\n key: "userId"\n value: "{{.args.id}}"\n skipEmpty: false\n }\n ]\n )\n}\n'})}),"\n",(0,r.jsx)(s.h4,{id:"query-fields",children:"Query Fields:"}),"\n",(0,r.jsxs)(s.ol,{children:["\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.strong,{children:"key"})," : Represents the name of the query parameter."]}),"\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.strong,{children:"value"})," : A string literal or a mustache template representing the value of query parameter."]}),"\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.strong,{children:"skipEmpty"})," : When set to ",(0,r.jsx)(s.code,{children:"true"})," the query parameter is skipped if the value of the parameter is null, defaults to false."]}),"\n"]}),"\n",(0,r.jsx)(s.admonition,{type:"important",children:(0,r.jsxs)(s.p,{children:["When ",(0,r.jsx)(s.code,{children:"batchKey"})," is present, Tailcall considers the first ",(0,r.jsx)(s.code,{children:"query"})," parameter to be the batch query key, so remember to adjust the order of the items accordingly."]})}),"\n",(0,r.jsx)(s.h3,{id:"body",children:"body"}),"\n",(0,r.jsx)(s.p,{children:"Defines the API call's body, necessary for methods like POST or PUT. Pass it as a static object or use Mustache templates for variable substitution from the GraphQL variables."}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-graphql",metastring:"showLineNumbers",children:'type Mutation {\n createUser(input: UserInput!): User\n @http(\n method: "POST"\n url: "https://jsonplaceholder.typicode.com/users"\n body: "{{.args.input}}"\n )\n}\n'})}),"\n",(0,r.jsxs)(s.p,{children:["In the example above, the ",(0,r.jsx)(s.code,{children:"createUser"})," mutation sends a POST request to ",(0,r.jsx)(s.code,{children:"/users"}),", with the input object converted to JSON and included in the request body."]}),"\n",(0,r.jsx)(s.h3,{id:"headers",children:"headers"}),"\n",(0,r.jsxs)(s.p,{children:["Customizes the HTTP request headers made by the ",(0,r.jsx)(s.code,{children:"@http"})," directive. Specify a key-value map of header names and values."]}),"\n",(0,r.jsx)(s.p,{children:"For instance:"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-graphql",metastring:"showLineNumbers",children:'type Mutation {\n createUser(input: UserInput!): User\n @http(\n url: "https://jsonplaceholder.typicode.com/users"\n headers: [{key: "X-Server", value: "Tailcall"}]\n )\n}\n'})}),"\n",(0,r.jsxs)(s.p,{children:["In this example, a request to ",(0,r.jsx)(s.code,{children:"/users"})," will include a HTTP header ",(0,r.jsx)(s.code,{children:"X-Server"})," with the value ",(0,r.jsx)(s.code,{children:"Tailcall"}),"."]}),"\n",(0,r.jsxs)(s.p,{children:["You can make use of mustache templates to provide dynamic values for headers, derived from the arguments or ",(0,r.jsx)(s.a,{href:"/docs/graphql-resolver-context-tailcall",children:"context"})," provided in the request. For example:"]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-graphql",metastring:"showLineNumbers",children:'type Mutation {\n users(name: String): User\n @http(\n url: "https://jsonplaceholder.typicode.com/users"\n headers: [\n {key: "X-Server", value: "Tailcall"}\n {key: "User-Name", value: "{{.args.name}}"}\n ]\n )\n}\n'})}),"\n",(0,r.jsxs)(s.p,{children:["In this scenario, the ",(0,r.jsx)(s.code,{children:"User-Name"})," header's value will dynamically adjust according to the ",(0,r.jsx)(s.code,{children:"name"})," argument passed in the request."]}),"\n",(0,r.jsx)(s.h3,{id:"batchkey",children:"batchKey"}),"\n",(0,r.jsxs)(s.p,{children:["Groups data requests into a single call, enhancing efficiency. Refer to our ",(0,r.jsx)(s.a,{href:"/docs/graphql-n-plus-one-problem-solved-tailcall",children:"n + 1 guide"})," for more details."]}),"\n",(0,r.jsx)(s.admonition,{type:"important",children:(0,r.jsxs)(s.p,{children:["When ",(0,r.jsx)(s.code,{children:"batchKey"})," is present, Tailcall considers the first ",(0,r.jsx)(s.code,{children:"query"})," parameter to be the batch query key, so remember to adjust the order of the items accordingly. Whereas, the last item from ",(0,r.jsx)(s.code,{children:"batchKey"})," is used to instruct which field is the ID of an object. In case that the returned result is a nested property ",(0,r.jsx)(s.code,{children:"batchKey"})," can be used as a path to extract and group the items for the returned result."]})}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-graphql",metastring:"showLineNumbers",children:'type Post {\n id: Int!\n name: String!\n userId: Int!\n user: User\n @http(\n url: "https://jsonplaceholder.typicode.com/users"\n query: [{key: "user_id", value: "{{.value.userId}}"}]\n batchKey: ["users", "id"]\n )\n}\n'})}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.code,{children:'query: {key: "user_id", value: "{{.value.userId}}"}]'}),": Instructs Tailcall CLI to generate a URL aligning the user id with ",(0,r.jsx)(s.code,{children:"userId"})," from the parent ",(0,r.jsx)(s.code,{children:"Post"}),", compiling a single URL for a batch of posts, such as ",(0,r.jsx)(s.code,{children:"/users?user_id=1&user_id=2&user_id=3...user_id=10"}),", consolidating requests into one."]}),"\n"]}),"\n",(0,r.jsx)(s.h3,{id:"onrequest",children:"onRequest"}),"\n",(0,r.jsxs)(s.p,{children:["The ",(0,r.jsx)(s.code,{children:"onRequest"})," property accepts a string value representing the remote function to be called every time an HTTP request is initiated. Typically the remote function is defined in a linked JavaScript worker file."]}),"\n",(0,r.jsx)(s.admonition,{type:"note",children:(0,r.jsxs)(s.p,{children:["For defining a request middleware globally for all requests, refer to the ",(0,r.jsx)(s.a,{href:"/docs/upstream-directive#onrequest",children:"upstream directive documentation"}),"."]})}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-graphql",metastring:"showLineNumbers",children:'type Query {\n userPosts(id: ID!): [Post]\n @http(\n url: "https://jsonplaceholder.typicode.com/posts"\n query: [{key: "userId", value: "{{.args.id}}"}]\n onRequest: "someFunctionName"\n )\n}\n'})}),"\n",(0,r.jsx)(s.h3,{id:"onresponsebody",children:"onResponseBody"}),"\n",(0,r.jsxs)(s.p,{children:["This hook allows you to intercept and modify the response body from upstream services before it's processed by Tailcall. Like ",(0,r.jsx)(s.a,{href:"#onrequest",children:"onRequest"}),", it accepts a string value representing a middleware function defined in a JavaScript file. This function can be used to transform or validate the response data."]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-graphql",metastring:"showLineNumbers",children:'type Query {\n user(id: Int!): User\n @http(\n url: "https://jsonplaceholder.typicode.com/users/{{.args.id}}"\n onResponseBody: "onResponse"\n )\n}\n'})}),"\n",(0,r.jsx)(s.h3,{id:"select",children:"select"}),"\n",(0,r.jsxs)(s.p,{children:["You can use ",(0,r.jsx)(s.code,{children:"select"})," with mustache syntax to re-construct the directives\nresponse to the desired format. This is useful when data are deeply\nnested or want to keep specific fields only from the response."]}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["EXAMPLE 1: if we have a call that returns ",(0,r.jsx)(s.code,{children:'{ "user": { "items": [...], ... } ... }'})," we can use ",(0,r.jsx)(s.code,{children:'"{{.user.items}}"'}),", to extract the ",(0,r.jsx)(s.code,{children:"items"}),"."]}),"\n",(0,r.jsxs)(s.li,{children:["EXAMPLE 2: if we have a call that returns ",(0,r.jsx)(s.code,{children:'{ "foo": "bar", "fizz": { "buzz": "eggs", ... }, ... }'})," we can use ",(0,r.jsx)(s.code,{children:'{ foo: "{{.foo}}", buzz: "{{.fizz.buzz}}" }'})]}),"\n"]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-graphql",metastring:"showLineNumbers",children:'type Query {\n userCompany(id: Int!): Company\n @http(\n url: "https://jsonplaceholder.typicode.com/users/{{.args.id}}"\n select: "{{.company}}"\n )\n userDetails(id: Int!): UserDetails\n @http(\n url: "https://jsonplaceholder.typicode.com/users/{{.args.id}}"\n select: {\n id: "{{.id}}"\n city: "{{.address.city}}"\n phone: "{{.phone}}"\n }\n )\n}\n'})}),"\n",(0,r.jsx)(s.h3,{id:"dedupe",children:"dedupe"}),"\n",(0,r.jsxs)(s.p,{children:["A boolean flag, if set to ",(0,r.jsx)(s.code,{children:"true"}),", will enable deduplication of IO operations to enhance performance. This flag prevents duplicate IO requests from being executed concurrently, reducing resource load. If not specified, this feature defaults to ",(0,r.jsx)(s.code,{children:"false"}),"."]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-graphql",metastring:"showLineNumbers",children:'@http(\n url: "https://jsonplaceholder.typicode.com/users/"\n dedupe: true\n)\n'})}),"\n",(0,r.jsx)(s.h2,{id:"batching-with-post-requests",children:"Batching with POST Requests"}),"\n",(0,r.jsx)(s.p,{children:"In some cases, your batch API might use a POST request that accepts a list of items for processing. Tailcall can batch these requests similarly to how it handles GET requests, but instead of sending the input in query parameters, it sends them in the request body."}),"\n",(0,r.jsx)(s.h3,{id:"mechanism",children:"Mechanism"}),"\n",(0,r.jsx)(s.p,{children:"When Tailcall receives multiple POST requests that share the same endpoint but have different parameters, it:"}),"\n",(0,r.jsxs)(s.ol,{children:["\n",(0,r.jsx)(s.li,{children:"Collects these requests"}),"\n",(0,r.jsx)(s.li,{children:"Transforms them into a single POST request with an array of objects in the body"}),"\n",(0,r.jsx)(s.li,{children:"Sends this consolidated request to the upstream service"}),"\n",(0,r.jsx)(s.li,{children:"Maps the responses back to individual results"}),"\n"]}),"\n",(0,r.jsx)(s.h3,{id:"configuration",children:"Configuration"}),"\n",(0,r.jsx)(s.p,{children:"To enable batching, configure your schema as follows:"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-graphql",children:'type Query {\n posts: [Post]\n @http(url: "https://jsonplaceholder.typicode.com/posts")\n}\n\ntype Post {\n id: ID!\n name: String!\n user: User!\n @http(\n url: "https://jsonplaceholder.typicode.com/users"\n method: POST\n body: {\n userId: "{{.value.userId}}"\n staticValue: "static"\n }\n batchKey: ["userId"]\n )\n}\n\ntype User {\n id: ID!\n name: String!\n}\n'})}),"\n",(0,r.jsxs)(s.p,{children:["In this example, the ",(0,r.jsx)(s.code,{children:"posts"})," query fetches a list of posts, and the ",(0,r.jsx)(s.code,{children:"user"})," field fetches user details for each post. The ",(0,r.jsx)(s.code,{children:"batchKey"})," parameter groups the user requests into a single POST request, enhancing efficiency."]}),"\n",(0,r.jsx)(s.p,{children:"Let's say your GraphQL query needs to fetch user details for multiple posts:"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-graphql",children:"query {\n posts {\n id\n name\n user {\n id\n name\n }\n }\n}\n"})}),"\n",(0,r.jsx)(s.p,{children:"The posts endpoint returns:"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-json",children:'[\n {\n "id": 1,\n "name": "post-1",\n "userId": 1\n },\n {\n "id": 2,\n "name": "post-2",\n "userId": 2\n }\n]\n'})}),"\n",(0,r.jsx)(s.p,{children:"Instead of making separate POST requests for each user, Tailcall will batch them into a single request:"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:'POST https://jsonplaceholder.typicode.com/users\nContent-Type: application/json\nBody:\n[\n {\n "userId": 1,\n "staticValue": "static"\n },\n {\n "userId": 2,\n "staticValue": "static"\n }\n]\n'})}),"\n",(0,r.jsx)(s.h3,{id:"current-limitations",children:"Current Limitations"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsx)(s.li,{children:"Currently, supports only one dynamic parameter per batched request"}),"\n",(0,r.jsx)(s.li,{children:"All requests in a batch must share the same endpoint and method"}),"\n",(0,r.jsxs)(s.li,{children:["The dynamic parameter must be referenced using the ",(0,r.jsx)(s.code,{children:"{{.value.fieldName}}"})," syntax"]}),"\n"]}),"\n",(0,r.jsx)(s.h2,{id:"combining-multiple-directives",children:"Combining Multiple Directives"}),"\n",(0,r.jsxs)(s.p,{children:["The ",(0,r.jsx)(s.code,{children:"@http"})," directive can be used in combination with other ",(0,r.jsx)(s.a,{href:"/docs/tailcall-dsl-graphql-custom-directives#resolvable-directives",children:"resolvable directives"}),", with results merged deeply. This allows for powerful and flexible resolver configurations."]}),"\n",(0,r.jsxs)(s.p,{children:["For more details, see ",(0,r.jsx)(s.a,{href:"/docs/tailcall-dsl-graphql-custom-directives",children:"Directives Documentation"}),"."]})]})}function h(e={}){const{wrapper:s}={...(0,i.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(o,{...e})}):o(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>l,x:()=>a});var t=n(96540);const r={},i=t.createContext(r);function l(e){const s=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:l(e.components),t.createElement(i.Provider,{value:s},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/8fdf8779.bac05a75.js b/assets/js/8fdf8779.bac05a75.js
deleted file mode 100644
index 2c317c2b1..000000000
--- a/assets/js/8fdf8779.bac05a75.js
+++ /dev/null
@@ -1 +0,0 @@
-"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5944],{23415:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>a,contentTitle:()=>d,default:()=>h,frontMatter:()=>l,metadata:()=>n,toc:()=>o});const n=JSON.parse('{"id":"directives/http","title":"@http","description":"The @http directive indicates a field or node relies on a REST API.","source":"@site/docs/directives/http.md","sourceDirName":"directives","slug":"/http-directive","permalink":"/docs/http-directive","draft":false,"unlisted":false,"editUrl":"https://github.com/tailcallhq/tailcallhq.github.io/tree/develop/docs/directives/http.md","tags":[],"version":"current","lastUpdatedAt":1732818775000,"frontMatter":{"title":"@http","description":"The @http directive indicates a field or node relies on a REST API.","slug":"../http-directive"},"sidebar":"docs","previous":{"title":"@grpc","permalink":"/docs/grpc-directive"},"next":{"title":"@js","permalink":"/docs/js-directive"}}');var r=t(74848),i=t(28453);const l={title:"@http",description:"The @http directive indicates a field or node relies on a REST API.",slug:"../http-directive"},d=void 0,a={},o=[{value:"@http
Directive Definition",id:"http-directive-definition",level:2},{value:"Example: Basic Usage of @http
",id:"example-basic-usage-of-http",level:2},{value:"Directive Arguments",id:"directive-arguments",level:2},{value:"url",id:"url",level:3},{value:"method",id:"method",level:3},{value:"query",id:"query",level:3},{value:"Query Fields:",id:"query-fields",level:4},{value:"body",id:"body",level:3},{value:"headers",id:"headers",level:3},{value:"batchKey",id:"batchkey",level:3},{value:"onRequest",id:"onrequest",level:3},{value:"onResponseBody",id:"onresponsebody",level:3},{value:"select",id:"select",level:3},{value:"dedupe",id:"dedupe",level:3},{value:"Combining Multiple Directives",id:"combining-multiple-directives",level:2}];function c(e){const s={a:"a",admonition:"admonition",code:"code",h2:"h2",h3:"h3",h4:"h4",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)(s.p,{children:["The ",(0,r.jsx)(s.code,{children:"@http"})," directive enables GraphQL fields to be resolved using REST API endpoints, simplifying the integration of external data sources."]}),"\n",(0,r.jsxs)(s.h2,{id:"http-directive-definition",children:[(0,r.jsx)(s.code,{children:"@http"})," Directive Definition"]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-graphql",metastring:'title="Directive Definition" showLineNumbers',children:"directive @http(\n url: String!\n method: Method\n query: [InputKeyValue!]\n body: JSON\n headers: [InputKeyValue!]\n batchKey: [String!]\n onRequest: String\n onResponseBody: String\n select: JSON\n dedupe: Boolean\n) on FIELD_DEFINITION\n"})}),"\n",(0,r.jsxs)(s.h2,{id:"example-basic-usage-of-http",children:["Example: Basic Usage of ",(0,r.jsx)(s.code,{children:"@http"})]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-graphql",metastring:"showLineNumbers",children:'type Query {\n users: [User]\n @http(url: "https://jsonplaceholder.typicode.com/users")\n}\n'})}),"\n",(0,r.jsxs)(s.p,{children:["In this example, adding the ",(0,r.jsx)(s.code,{children:"@http"})," directive to the ",(0,r.jsx)(s.code,{children:"users"})," field of the ",(0,r.jsx)(s.code,{children:"Query"})," type indicates reliance on a REST API for the ",(0,r.jsx)(s.code,{children:"users"})," field. The ",(0,r.jsx)(s.a,{href:"#url",children:"url"})," argument specifies the REST API's url, which is ",(0,r.jsx)(s.code,{children:"https://jsonplaceholder.typicode.com/users"})," in this scenario. Querying the ",(0,r.jsx)(s.code,{children:"users"})," field prompts the GraphQL server to issue a GET request to ",(0,r.jsx)(s.code,{children:"https://jsonplaceholder.typicode.com/users"}),"."]}),"\n",(0,r.jsx)(s.h2,{id:"directive-arguments",children:"Directive Arguments"}),"\n",(0,r.jsx)(s.h3,{id:"url",children:"url"}),"\n",(0,r.jsxs)(s.p,{children:["The ",(0,r.jsx)(s.code,{children:"url"})," parameter defines the API endpoint. It can also contain dynamic segments with Mustache templates for variable substitution:"]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-graphql",metastring:"showLineNumbers",children:'type Query {\n user(id: ID!): User\n @http(\n url: "https://jsonplaceholder.typicode.com/users/{{.args.id}}"\n )\n}\n'})}),"\n",(0,r.jsx)(s.h3,{id:"method",children:"method"}),"\n",(0,r.jsxs)(s.p,{children:["Specifies the HTTP method for the request. Defaults to ",(0,r.jsx)(s.code,{children:"GET"})," if not specified:"]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-graphql",metastring:"showLineNumbers",children:'type Mutation {\n createUser(input: UserInput!): User\n @http(\n method: "POST"\n url: "https://jsonplaceholder.typicode.com/users"\n )\n}\n'})}),"\n",(0,r.jsx)(s.h3,{id:"query",children:"query"}),"\n",(0,r.jsx)(s.p,{children:"Represents the API call's query parameters, either as a static object or with dynamic parameters using Mustache templates. These parameters append to the URL."}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-graphql",metastring:"showLineNumbers",children:'type Query {\n userPosts(id: ID!): [Post]\n @http(\n url: "https://jsonplaceholder.typicode.com/posts"\n query: [\n {\n key: "userId"\n value: "{{.args.id}}"\n skipEmpty: false\n }\n ]\n )\n}\n'})}),"\n",(0,r.jsx)(s.h4,{id:"query-fields",children:"Query Fields:"}),"\n",(0,r.jsxs)(s.ol,{children:["\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.strong,{children:"key"})," : Represents the name of the query parameter."]}),"\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.strong,{children:"value"})," : A string literal or a mustache template representing the value of query parameter."]}),"\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.strong,{children:"skipEmpty"})," : When set to ",(0,r.jsx)(s.code,{children:"true"})," the query parameter is skipped if the value of the parameter is null, defaults to false."]}),"\n"]}),"\n",(0,r.jsx)(s.admonition,{type:"important",children:(0,r.jsxs)(s.p,{children:["When ",(0,r.jsx)(s.code,{children:"batchKey"})," is present, Tailcall considers the first ",(0,r.jsx)(s.code,{children:"query"})," parameter to be the batch query key, so remember to adjust the order of the items accordingly."]})}),"\n",(0,r.jsx)(s.h3,{id:"body",children:"body"}),"\n",(0,r.jsx)(s.p,{children:"Defines the API call's body, necessary for methods like POST or PUT. Pass it as a static object or use Mustache templates for variable substitution from the GraphQL variables."}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-graphql",metastring:"showLineNumbers",children:'type Mutation {\n createUser(input: UserInput!): User\n @http(\n method: "POST"\n url: "https://jsonplaceholder.typicode.com/users"\n body: "{{.args.input}}"\n )\n}\n'})}),"\n",(0,r.jsxs)(s.p,{children:["In the example above, the ",(0,r.jsx)(s.code,{children:"createUser"})," mutation sends a POST request to ",(0,r.jsx)(s.code,{children:"/users"}),", with the input object converted to JSON and included in the request body."]}),"\n",(0,r.jsx)(s.h3,{id:"headers",children:"headers"}),"\n",(0,r.jsxs)(s.p,{children:["Customizes the HTTP request headers made by the ",(0,r.jsx)(s.code,{children:"@http"})," directive. Specify a key-value map of header names and values."]}),"\n",(0,r.jsx)(s.p,{children:"For instance:"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-graphql",metastring:"showLineNumbers",children:'type Mutation {\n createUser(input: UserInput!): User\n @http(\n url: "https://jsonplaceholder.typicode.com/users"\n headers: [{key: "X-Server", value: "Tailcall"}]\n )\n}\n'})}),"\n",(0,r.jsxs)(s.p,{children:["In this example, a request to ",(0,r.jsx)(s.code,{children:"/users"})," will include a HTTP header ",(0,r.jsx)(s.code,{children:"X-Server"})," with the value ",(0,r.jsx)(s.code,{children:"Tailcall"}),"."]}),"\n",(0,r.jsxs)(s.p,{children:["You can make use of mustache templates to provide dynamic values for headers, derived from the arguments or ",(0,r.jsx)(s.a,{href:"/docs/graphql-resolver-context-tailcall",children:"context"})," provided in the request. For example:"]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-graphql",metastring:"showLineNumbers",children:'type Mutation {\n users(name: String): User\n @http(\n url: "https://jsonplaceholder.typicode.com/users"\n headers: [\n {key: "X-Server", value: "Tailcall"}\n {key: "User-Name", value: "{{.args.name}}"}\n ]\n )\n}\n'})}),"\n",(0,r.jsxs)(s.p,{children:["In this scenario, the ",(0,r.jsx)(s.code,{children:"User-Name"})," header's value will dynamically adjust according to the ",(0,r.jsx)(s.code,{children:"name"})," argument passed in the request."]}),"\n",(0,r.jsx)(s.h3,{id:"batchkey",children:"batchKey"}),"\n",(0,r.jsxs)(s.p,{children:["Groups data requests into a single call, enhancing efficiency. Refer to our ",(0,r.jsx)(s.a,{href:"/docs/graphql-n-plus-one-problem-solved-tailcall",children:"n + 1 guide"})," for more details."]}),"\n",(0,r.jsx)(s.admonition,{type:"important",children:(0,r.jsxs)(s.p,{children:["When ",(0,r.jsx)(s.code,{children:"batchKey"})," is present, Tailcall considers the first ",(0,r.jsx)(s.code,{children:"query"})," parameter to be the batch query key, so remember to adjust the order of the items accordingly. Whereas, the last item from ",(0,r.jsx)(s.code,{children:"batchKey"})," is used to instruct which field is the ID of an object. In case that the returned result is a nested property ",(0,r.jsx)(s.code,{children:"batchKey"})," can be used as a path to extract and group the items for the returned result."]})}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-graphql",metastring:"showLineNumbers",children:'type Post {\n id: Int!\n name: String!\n user: User\n @http(\n url: "https://jsonplaceholder.typicode.com/users"\n query: [{key: "user_id", value: "{{.value.userId}}"}]\n batchKey: ["users", "id"]\n )\n}\n'})}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.code,{children:'query: {key: "user_id", value: "{{.value.userId}}"}]'}),": Instructs Tailcall CLI to generate a URL aligning the user id with ",(0,r.jsx)(s.code,{children:"userId"})," from the parent ",(0,r.jsx)(s.code,{children:"Post"}),", compiling a single URL for a batch of posts, such as ",(0,r.jsx)(s.code,{children:"/users?user_id=1&user_id=2&user_id=3...user_id=10"}),", consolidating requests into one."]}),"\n"]}),"\n",(0,r.jsx)(s.h3,{id:"onrequest",children:"onRequest"}),"\n",(0,r.jsxs)(s.p,{children:["The ",(0,r.jsx)(s.code,{children:"onRequest"})," property accepts a string value representing the remote function to be called every time an HTTP request is initiated. Typically the remote function is defined in a linked JavaScript worker file."]}),"\n",(0,r.jsx)(s.admonition,{type:"note",children:(0,r.jsxs)(s.p,{children:["For defining a request middleware globally for all requests, refer to the ",(0,r.jsx)(s.a,{href:"/docs/upstream-directive#onrequest",children:"upstream directive documentation"}),"."]})}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-graphql",metastring:"showLineNumbers",children:'type Query {\n userPosts(id: ID!): [Post]\n @http(\n url: "https://jsonplaceholder.typicode.com/posts"\n query: [{key: "userId", value: "{{.args.id}}"}]\n onRequest: "someFunctionName"\n )\n}\n'})}),"\n",(0,r.jsx)(s.h3,{id:"onresponsebody",children:"onResponseBody"}),"\n",(0,r.jsxs)(s.p,{children:["This hook allows you to intercept and modify the response body from upstream services before it's processed by Tailcall. Like ",(0,r.jsx)(s.a,{href:"#onrequest",children:"onRequest"}),", it accepts a string value representing a middleware function defined in a JavaScript file. This function can be used to transform or validate the response data."]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-graphql",metastring:"showLineNumbers",children:'type Query {\n user(id: Int!): User\n @http(\n url: "https://jsonplaceholder.typicode.com/users/{{.args.id}}"\n onResponseBody: "onResponse"\n )\n}\n'})}),"\n",(0,r.jsx)(s.h3,{id:"select",children:"select"}),"\n",(0,r.jsxs)(s.p,{children:["You can use ",(0,r.jsx)(s.code,{children:"select"})," with mustache syntax to re-construct the directives\nresponse to the desired format. This is useful when data are deeply\nnested or want to keep specific fields only from the response."]}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["EXAMPLE 1: if we have a call that returns ",(0,r.jsx)(s.code,{children:'{ "user": { "items": [...], ... } ... }'})," we can use ",(0,r.jsx)(s.code,{children:'"{{.user.items}}"'}),", to extract the ",(0,r.jsx)(s.code,{children:"items"}),"."]}),"\n",(0,r.jsxs)(s.li,{children:["EXAMPLE 2: if we have a call that returns ",(0,r.jsx)(s.code,{children:'{ "foo": "bar", "fizz": { "buzz": "eggs", ... }, ... }'})," we can use ",(0,r.jsx)(s.code,{children:'{ foo: "{{.foo}}", buzz: "{{.fizz.buzz}}" }'})]}),"\n"]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-graphql",metastring:"showLineNumbers",children:'type Query {\n userCompany(id: Int!): Company\n @http(\n url: "https://jsonplaceholder.typicode.com/users/{{.args.id}}"\n select: "{{.company}}"\n )\n userDetails(id: Int!): UserDetails\n @http(\n url: "https://jsonplaceholder.typicode.com/users/{{.args.id}}"\n select: {\n id: "{{.id}}"\n city: "{{.address.city}}"\n phone: "{{.phone}}"\n }\n )\n}\n'})}),"\n",(0,r.jsx)(s.h3,{id:"dedupe",children:"dedupe"}),"\n",(0,r.jsxs)(s.p,{children:["A boolean flag, if set to ",(0,r.jsx)(s.code,{children:"true"}),", will enable deduplication of IO operations to enhance performance. This flag prevents duplicate IO requests from being executed concurrently, reducing resource load. If not specified, this feature defaults to ",(0,r.jsx)(s.code,{children:"false"}),"."]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-graphql",metastring:"showLineNumbers",children:'@http(\n url: "https://jsonplaceholder.typicode.com/users/"\n dedupe: true\n)\n'})}),"\n",(0,r.jsx)(s.h2,{id:"combining-multiple-directives",children:"Combining Multiple Directives"}),"\n",(0,r.jsxs)(s.p,{children:["The ",(0,r.jsx)(s.code,{children:"@http"})," directive can be used in combination with other ",(0,r.jsx)(s.a,{href:"/docs/tailcall-dsl-graphql-custom-directives#resolvable-directives",children:"resolvable directives"}),", with results merged deeply. This allows for powerful and flexible resolver configurations."]}),"\n",(0,r.jsxs)(s.p,{children:["For more details, see ",(0,r.jsx)(s.a,{href:"/docs/tailcall-dsl-graphql-custom-directives",children:"Directives Documentation"}),"."]})]})}function h(e={}){const{wrapper:s}={...(0,i.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(c,{...e})}):c(e)}},28453:(e,s,t)=>{t.d(s,{R:()=>l,x:()=>d});var n=t(96540);const r={},i=n.createContext(r);function l(e){const s=n.useContext(i);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function d(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:l(e.components),n.createElement(i.Provider,{value:s},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/main.3c2e1038.js b/assets/js/main.eb9a9bb6.js
similarity index 99%
rename from assets/js/main.3c2e1038.js
rename to assets/js/main.eb9a9bb6.js
index a2306ca7d..f34c18f3e 100644
--- a/assets/js/main.3c2e1038.js
+++ b/assets/js/main.eb9a9bb6.js
@@ -1,2 +1,2 @@
-/*! For license information please see main.3c2e1038.js.LICENSE.txt */
-(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[8792],{55600:(e,t,n)=>{"use strict";n.d(t,{Bc:()=>O,E8:()=>Kn,a1:()=>Zn});var r=n(96540);n(40961);function a(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);nYour Docusaurus site did not load properly.
\nA very common reason is a wrong site baseUrl configuration.
\nCurrent configured baseUrl = ${e} ${"/"===e?" (default value)":""}
\nWe suggest trying baseUrl =
\n{const l=t.toLowerCase(),s=((e,t)=>{const[n,r]=(0,o.useState)(U(t,e)),a=(0,o.useRef)(),i=(0,o.useRef)();return(0,o.useEffect)((()=>{t===a.current&&e===i.current||(a.current=t,i.current=e,r(U(t,e)))}),[e,t]),n})(l,r),c=(e=>(0,o.useCallback)((t=>{var n=t,{className:r,style:a,line:o}=n,l=A(n,["className","style","line"]);const s=y(b({},l),{className:(0,i.A)("token-line",r)});return"object"==typeof e&&"plain"in e&&(s.style=e.plain),"object"==typeof a&&(s.style=b(b({},s.style||{}),a)),s}),[e]))(s),u=(e=>{const t=(0,o.useCallback)((({types:t,empty:n})=>{if(null!=e)return 1===t.length&&"plain"===t[0]?null!=n?{display:"inline-block"}:void 0:1===t.length&&null!=n?e[t[0]]:Object.assign(null!=n?{display:"inline-block"}:{},...t.map((t=>e[t])))}),[e]);return(0,o.useCallback)((e=>{var n=e,{token:r,className:a,style:o}=n,l=A(n,["token","className","style"]);const s=y(b({},l),{className:(0,i.A)("token",...r.types,a),children:r.content,style:t(r)});return null!=o&&(s.style=b(b({},s.style||{}),o)),s}),[t])})(s),d=(({prism:e,code:t,grammar:n,language:r})=>{const a=(0,o.useRef)(e);return(0,o.useMemo)((()=>{if(null==n)return H([t]);const e={code:t,grammar:n,language:r,tokens:[]};return a.current.hooks.run("before-tokenize",e),e.tokens=a.current.tokenize(t,n),a.current.hooks.run("after-tokenize",e),H(e.tokens)}),[t,n,r])})({prism:a,language:l,code:n,grammar:a.languages[l]});return e({tokens:d,className:`prism-code language-${l}`,style:null!=s?s.root:{},getLineProps:c,getTokenProps:u})},Q=e=>(0,o.createElement)(Y,y(b({},e),{prism:e.prism||w,theme:e.theme||W,code:e.code,language:e.language}))},54164:(e,t,n)=>{"use strict";n.d(t,{vD:()=>p,lT:()=>A});var r,a={};var o=function(){if(r)return a;r=1,a.parse=function(e,n){if("string"!=typeof e)throw new TypeError("argument str must be a string");var r={},a=e.length;if(a<2)return r;var o=n&&n.decode||u,i=0,l=0,p=0;do{if(-1===(l=e.indexOf("=",i)))break;if(-1===(p=e.indexOf(";",i)))p=a;else if(l>p){i=e.lastIndexOf(";",l-1)+1;continue}var f=s(e,i,l),g=c(e,l,f),h=e.slice(f,g);if(!t.call(r,h)){var m=s(e,l+1,p),v=c(e,p,m);34===e.charCodeAt(m)&&34===e.charCodeAt(v-1)&&(m++,v--);var b=e.slice(m,v);r[h]=d(b,o)}i=p+1}while(in;){var r=e.charCodeAt(--t);if(32!==r&&9!==r)return t+1}return n}function u(e){return-1!==e.indexOf("%")?decodeURIComponent(e):e}function d(e,t){try{return t(e)}catch(n){return e}}return a}();function i(e,t={}){const n=function(e){if(e&&"j"===e[0]&&":"===e[1])return e.substr(2);return e}(e);if(!t.doNotParse)try{return JSON.parse(n)}catch(r){}return e}class l{constructor(e,t={}){this.changeListeners=[],this.HAS_DOCUMENT_COOKIE=!1,this.update=()=>{if(!this.HAS_DOCUMENT_COOKIE)return;const e=this.cookies;this.cookies=o.parse(document.cookie),this._checkChanges(e)};const n="undefined"==typeof document?"":document.cookie;this.cookies=function(e){return"string"==typeof e?o.parse(e):"object"==typeof e&&null!==e?e:{}}(e||n),this.defaultSetOptions=t,this.HAS_DOCUMENT_COOKIE=function(){const e="undefined"==typeof global?void 0:global.TEST_HAS_DOCUMENT_COOKIE;return"boolean"==typeof e?e:"object"==typeof document&&"string"==typeof document.cookie}()}_emitChange(e){for(let t=0;t Your Docusaurus site did not load properly. A very common reason is a wrong site baseUrl configuration. Current configured baseUrl = ${e} ${"/"===e?" (default value)":""} We suggest trying baseUrl = {if(!e)return;const r=t.location.hash;if(r?document.getElementById(r.substring(1)):void 0)return a.current=!0,void n(!1);n(!0)})),{navbarRef:i,isNavbarVisible:t}}(n);return(0,u.jsxs)("nav",{ref:l,"aria-label":(0,s.T)({id:"theme.NavBar.navAriaLabel",message:"Main",description:"The ARIA label for the main navigation"}),className:(0,a.A)("navbar","navbar--fixed-top",n&&[Le.navbarHideable,!d&&Le.navbarHidden],{"navbar--dark":"dark"===o,"navbar--primary":"primary"===o,"navbar-sidebar--show":i.shown}),children:[t,(0,u.jsx)(Ie,{onClick:i.toggle}),(0,u.jsx)(Te,{})]})}var Ne=n(70440);const Re={errorBoundaryError:"errorBoundaryError_a6uf",errorBoundaryFallback:"errorBoundaryFallback_VBag"};function We(e){return(0,u.jsx)("button",{type:"button",...e,children:(0,u.jsx)(s.A,{id:"theme.ErrorPageContent.tryAgain",description:"The label of the button to try again rendering when the React error boundary captures an error",children:"Try again"})})}function Me(e){let{error:t}=e;const n=(0,Ne.rA)(t).map((e=>e.message)).join("\n\nCause:\n");return(0,u.jsx)("p",{className:Re.errorBoundaryError,children:n})}class Be extends r.Component{componentDidCatch(e,t){throw this.props.onError(e,t)}render(){return this.props.children}}function De(e){let{width:t=30,height:n=30,className:r,...a}=e;return(0,u.jsx)("svg",{className:r,width:t,height:n,viewBox:"0 0 30 30","aria-hidden":"true",...a,children:(0,u.jsx)("path",{stroke:"currentColor",strokeLinecap:"round",strokeMiterlimit:"10",strokeWidth:"2",d:"M4 7h22M4 15h22M4 23h22"})})}function ze(){const{toggle:e,shown:t}=(0,P.M)();return(0,u.jsx)("button",{onClick:e,"aria-label":(0,s.T)({id:"theme.docs.sidebar.toggleSidebarButtonAriaLabel",message:"Toggle navigation bar",description:"The ARIA label for hamburger menu button of mobile navigation"}),"aria-expanded":t,className:"navbar__toggle clean-btn",type:"button",children:(0,u.jsx)(De,{})})}n(59550);const Fe="colorModeToggle_x44X";n(22375);const Ue=e=>{let{items:t}=e;return(0,u.jsx)(u.Fragment,{children:t.map(((e,t)=>(0,u.jsx)(Be,{onError:t=>new Error(`A theme navbar item failed to render.\nPlease double-check the following navbar item (themeConfig.navbar.items) of your Docusaurus config:\n${JSON.stringify(e,null,2)}`),children:(0,u.jsx)(Ce,{...e})},t)))})},_e=e=>{let{left:t,right:n}=e;return(0,u.jsxs)("div",{className:"navbar__inner",children:[(0,u.jsx)("div",{className:"navbar__items",children:t}),(0,u.jsx)("div",{className:"navbar__items navbar__items--right",children:n})]})},Ve=()=>{const e=(0,P.M)(),t=(0,A.p)().navbar.items,[n,r]=function(e){function t(e){return"left"===(e.position??"right")}return[e.filter(t),e.filter((e=>!t(e)))]}(t);return(0,u.jsx)(_e,{left:(0,u.jsxs)(u.Fragment,{children:[e.shouldRender&&(0,u.jsx)(ve.A,{}),!e.disabled&&(0,u.jsx)(ze,{}),(0,u.jsx)(Q,{}),(0,u.jsx)(Ue,{items:n})]}),right:(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(Ue,{items:r}),(0,u.jsx)(H,{className:Fe})]})})};function Xe(){return(0,u.jsx)(qe,{children:(0,u.jsx)(Ve,{})})}function He(e){let{item:t}=e;const{to:n,href:r,label:a,prependBaseUrlToHref:o,...i}=t,l=(0,J.Ay)(n),s=(0,J.Ay)(r,{forcePrependBaseUrl:!0});return(0,u.jsxs)(K.A,{className:"footer__link-item",...r?{href:o?s:r}:{to:l},...i,children:[a,r&&!(0,$.A)(r)&&(0,u.jsx)(te.A,{})]})}function Ye(e){let{item:t}=e;return t.html?(0,u.jsx)("li",{className:"footer__item",dangerouslySetInnerHTML:{__html:t.html}}):(0,u.jsx)("li",{className:"footer__item",children:(0,u.jsx)(He,{item:t})},t.href??t.to)}function Qe(e){let{column:t}=e;return(0,u.jsxs)("div",{className:"col footer__col",children:[(0,u.jsx)("div",{className:"footer__title",children:t.title}),(0,u.jsx)("ul",{className:"footer__items clean-list",children:t.items.map(((e,t)=>(0,u.jsx)(Ye,{item:e},t)))})]})}function Ge(e){let{columns:t}=e;return(0,u.jsx)("div",{className:"row footer__links",children:t.map(((e,t)=>(0,u.jsx)(Qe,{column:e},t)))})}function Ze(){return(0,u.jsx)("span",{className:"footer__link-separator",children:"\xb7"})}function Ke(e){let{item:t}=e;return t.html?(0,u.jsx)("span",{className:"footer__link-item",dangerouslySetInnerHTML:{__html:t.html}}):(0,u.jsx)(He,{item:t})}function Je(e){let{links:t}=e;return(0,u.jsx)("div",{className:"footer__links text--center",children:(0,u.jsx)("div",{className:"footer__links",children:t.map(((e,n)=>(0,u.jsxs)(r.Fragment,{children:[(0,u.jsx)(Ke,{item:e}),t.length!==n+1&&(0,u.jsx)(Ze,{})]},n)))})})}function $e(e){let{links:t}=e;return function(e){return"title"in e[0]}(t)?(0,u.jsx)(Ge,{columns:t}):(0,u.jsx)(Je,{links:t})}var et=n(21122);const tt={footerLogoLink:"footerLogoLink_BH7S"};function nt(e){let{logo:t}=e;const{withBaseUrl:n}=(0,J.hH)(),r={light:n(t.src),dark:n(t.srcDark??t.src)};return(0,u.jsx)(et.A,{className:(0,a.A)("footer__logo",t.className),alt:t.alt,sources:r,width:t.width,height:t.height,style:t.style})}function rt(e){let{logo:t}=e;return t.href?(0,u.jsx)(K.A,{href:t.href,className:tt.footerLogoLink,target:t.target,children:(0,u.jsx)(nt,{logo:t})}):(0,u.jsx)(nt,{logo:t})}function at(e){let{copyright:t}=e;return(0,u.jsx)("div",{className:"footer__copyright",dangerouslySetInnerHTML:{__html:t}})}function ot(e){let{style:t,links:n,logo:r,copyright:o}=e;return(0,u.jsx)("footer",{className:(0,a.A)("footer",{"footer--dark":"dark"===t}),children:(0,u.jsxs)("div",{className:"container container-fluid",children:[n,(r||o)&&(0,u.jsxs)("div",{className:"footer__bottom text--center",children:[r&&(0,u.jsx)("div",{className:"margin-bottom--sm",children:r}),o]})]})})}function it(){const{footer:e}=(0,A.p)();if(!e)return null;const{copyright:t,links:n,logo:r,style:a}=e;return(0,u.jsx)(ot,{style:a,links:n&&n.length>0&&(0,u.jsx)($e,{links:n}),logo:r&&(0,u.jsx)(rt,{logo:r}),copyright:t&&(0,u.jsx)(at,{copyright:t})})}const lt=r.memo(it),st=(0,r.createContext)(null),ct={get:e=>"undefined"!=typeof window&&window.__tc_data__?window.__tc_data__[e]:null,set(e,t){"undefined"!=typeof window&&(window.__tc_data__=window.__tc_data__||{},window.__tc_data__[e]=t)}},ut=e=>{let{children:t}=e;const[n,a]=(0,r.useState)(ct.get("githubStars"));return(0,r.useEffect)((()=>{fetch("https://api.github.com/repos/tailcallhq/tailcall").then((e=>e.json())).then((e=>{const t=e.stargazers_count;return a(t),ct.set("githubStars",t),t})).catch((()=>{console.error("Failed to fetch Github stars count")}))}),[]),(0,u.jsx)(st.Provider,{value:n,children:t})};var dt,pt,ft,gt=n(75957);function ht(){return ht=Object.assign?Object.assign.bind():function(e){for(var t=1;t