diff --git a/404.html b/404.html index abe8fe97f..ce13a7fd4 100644 --- a/404.html +++ b/404.html @@ -4,8 +4,8 @@ Page Not Found | smithy4s - - + +
@@ -14,7 +14,7 @@ Profiled with yourkit
- - + + \ No newline at end of file diff --git a/assets/js/04483a11.f02e3a7f.js b/assets/js/04483a11.4f709c87.js similarity index 98% rename from assets/js/04483a11.f02e3a7f.js rename to assets/js/04483a11.4f709c87.js index 496452058..2a1b1453d 100644 --- a/assets/js/04483a11.f02e3a7f.js +++ b/assets/js/04483a11.4f709c87.js @@ -1 +1 @@ -"use strict";(self.webpackChunksmithy4s=self.webpackChunksmithy4s||[]).push([[7054],{3905:(e,n,t)=>{t.d(n,{Zo:()=>s,kt:()=>v});var r=t(7294);function i(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function a(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function o(e){for(var n=1;n=0||(i[t]=e[t]);return i}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var l=r.createContext({}),c=function(e){var n=r.useContext(l),t=n;return e&&(t="function"==typeof e?e(n):o(o({},n),e)),t},s=function(e){var n=c(e.components);return r.createElement(l.Provider,{value:n},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},m=r.forwardRef((function(e,n){var t=e.components,i=e.mdxType,a=e.originalType,l=e.parentName,s=p(e,["components","mdxType","originalType","parentName"]),u=c(t),m=i,v=u["".concat(l,".").concat(m)]||u[m]||d[m]||a;return t?r.createElement(v,o(o({ref:n},s),{},{components:t})):r.createElement(v,o({ref:n},s))}));function v(e,n){var t=arguments,i=n&&n.mdxType;if("string"==typeof e||i){var a=t.length,o=new Array(a);o[0]=m;var p={};for(var l in n)hasOwnProperty.call(n,l)&&(p[l]=n[l]);p.originalType=e,p[u]="string"==typeof e?e:i,o[1]=p;for(var c=2;c{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>d,frontMatter:()=>a,metadata:()=>p,toc:()=>c});var r=t(7462),i=(t(7294),t(3905));const a={sidebar_label:"Service Product",title:"Service Product"},o=void 0,p={unversionedId:"codegen/customisation/service-product",id:"codegen/customisation/service-product",title:"Service Product",description:"As of smithy4s version 0.18.x you can also generate a service interface in",source:"@site/../docs/target/jvm-2.13/mdoc/04-codegen/01-customisation/10-service-product.md",sourceDirName:"04-codegen/01-customisation",slug:"/codegen/customisation/service-product",permalink:"/smithy4s/docs/codegen/customisation/service-product",draft:!1,editUrl:"https://github.com/disneystreaming/smithy4s/edit/main/modules/docs/src/04-codegen/01-customisation/10-service-product.md",tags:[],version:"current",sidebarPosition:10,frontMatter:{sidebar_label:"Service Product",title:"Service Product"},sidebar:"tutorialSidebar",previous:{title:"Typeclass Instances",permalink:"/smithy4s/docs/codegen/customisation/typeclass"},next:{title:"Optics",permalink:"/smithy4s/docs/codegen/customisation/optics"}},l={},c=[{value:"Static description of services",id:"static-description-of-services",level:3},{value:"Non-linear input of operation",id:"non-linear-input-of-operation",level:3},{value:"Fluent service builder",id:"fluent-service-builder",level:3}],s={toc:c},u="wrapper";function d(e){let{components:n,...t}=e;return(0,i.kt)(u,(0,r.Z)({},s,t,{components:n,mdxType:"MDXLayout"}),(0,i.kt)("p",null,"As of smithy4s version ",(0,i.kt)("inlineCode",{parentName:"p"},"0.18.x"),' you can also generate a service interface in\nwhich each method doesn\'t receive an input. Instead, the output of each method\nhas the usual return type, which already includes the input as a type parameter.\nWe call this version a "service product" because it can be seen as the product\nof all the operations of the service.'),(0,i.kt)("p",null,"To generate a service product, annotate the service definition with"),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"@generateServiceProduct"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-kotlin"},'$version: "2"\n\nnamespace smithy4s.example.product\n\nuse smithy4s.meta#generateServiceProduct\n\n@generateServiceProduct\nservice ExampleService {\n operations: [ExampleOperation]\n}\n\noperation ExampleOperation {\n input := {\n @required\n a: String\n }\n output := {\n @required\n b: String\n }\n}\n')),(0,i.kt)("p",null,"This will generate the following interface:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},"trait ExampleServiceProductGen[F[_, _, _, _, _]] {\n def exampleOperation: F[ExampleOperationInput, Nothing, ExampleOperationOutput, Nothing, Nothing]\n}\n")),(0,i.kt)("p",null,"and the following implementation of ",(0,i.kt)("inlineCode",{parentName:"p"},"ServiceProduct"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},"object ExampleServiceProductGen extends ServiceProduct[ExampleServiceProductGen]\n")),(0,i.kt)("p",null,"You will be able to access the service product version of the service like this:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},"import smithy4s.example.product._\n\nExampleServiceGen.serviceProduct\n// res0: smithy4s.ServiceProduct.Aux[ExampleServiceProductGen, ExampleServiceGen] = smithy4s.example.product.ExampleServiceProductGen$@6c8e5da5\n")),(0,i.kt)("p",null,"Or, more generically:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},"import smithy4s.ServiceProduct\n\ndef productOf[Alg[_[_, _, _, _, _]]](mirror: ServiceProduct.Mirror[Alg]) = mirror.serviceProduct\n\n// example\ndef exampleProduct = productOf(ExampleService)\n")),(0,i.kt)("p",null,"With service products, you can call service methods without providing their inputs directly."),(0,i.kt)("p",null,"Here are a couple ways you can use this as a library author:"),(0,i.kt)("h3",{id:"static-description-of-services"},"Static description of services"),(0,i.kt)("details",null,(0,i.kt)("summary",null,"Implementation"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},'import smithy4s.kinds.PolyFunction5\n\ntype Describe[_, _, _, _, _] = String\n\ndef descriptor[Alg[_[_, _, _, _, _]]](mirror: ServiceProduct.Mirror[Alg]): mirror.Prod[Describe] =\n mirror\n .serviceProduct\n .mapK5(\n mirror.serviceProduct.endpointsProduct,\n new PolyFunction5[mirror.serviceProduct.service.Endpoint, Describe] {\n\n override def apply[I, E, O, SI, SO](\n fa: mirror.serviceProduct.service.Endpoint[I, E, O, SI, SO]\n ): Describe[I, E, O, SI, SO] =\n s"def ${fa.name}(input: ${fa.input.shapeId.name}): ${fa.output.shapeId.name}"\n\n },\n )\n'))),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},'// Usage\n\nval desc: String = descriptor(ExampleService).exampleOperation\n// desc: String = "def ExampleOperation(input: ExampleOperationInput): ExampleOperationOutput"\n')),(0,i.kt)("h3",{id:"non-linear-input-of-operation"},"Non-linear input of operation"),(0,i.kt)("details",null,(0,i.kt)("summary",null,"Implementation"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},'import smithy4s.ShapeId\n\ntype Id[A] = A\n\nval impl: ExampleService[Id] =\n new ExampleService[Id] {\n\n override def exampleOperation(input: String): ExampleOperationOutput = ExampleOperationOutput(\n s"Output for $input!"\n )\n\n }\n// impl: ExampleService[Id] = repl.MdocSession$MdocApp$$anon$2@78b0d350\n\ntype ListClient[I, _, O, _, _] = List[I] => List[O]\n\ndef listClient[Alg[_[_, _, _, _, _]], Prod[_[_, _, _, _, _]]](\n impl: smithy4s.kinds.FunctorAlgebra[Alg, Id]\n)(\n implicit sp: ServiceProduct.Aux[Prod, Alg]\n): Prod[ListClient] = sp\n .mapK5(\n sp.endpointsProduct,\n new PolyFunction5[sp.service.Endpoint, ListClient] {\n\n private val interp = sp.service.toPolyFunction(impl)\n\n override def apply[I, E, O, SI, SO](\n fa: sp.service.Endpoint[I, E, O, SI, SO]\n ): List[I] => List[O] = _.map(in => interp(fa.wrap(in)))\n\n },\n )\n'))),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},'listClient(impl)( /* implicit scope problem here - TODO */ ExampleService.serviceProduct)\n .exampleOperation(\n List("a", "b", "c").map(ExampleOperationInput(_))\n )\n// res1: List[ExampleOperationOutput] = List(\n// ExampleOperationOutput(b = "Output for a!"),\n// ExampleOperationOutput(b = "Output for b!"),\n// ExampleOperationOutput(b = "Output for c!")\n// )\n')),(0,i.kt)("h3",{id:"fluent-service-builder"},"Fluent service builder"),(0,i.kt)("details",null,(0,i.kt)("summary",null,"Implementation"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},"type ToList[_, _, O, _, _] = List[O]\n\ntrait EndpointHandlerBuilder[I, E, O, SI, SO] {\n def apply(f: I => O): EndpointHandler\n}\n\nsealed trait EndpointHandler {\n type I_\n type O_\n def id: ShapeId\n def function: I_ => O_\n}\n\ncase class PartialBuilder[Alg[_[_, _, _, _, _]], Prod[_[_, _, _, _, _]]](\n mirror: ServiceProduct.Mirror.Aux[Alg, Prod],\n handlers: List[EndpointHandler],\n) {\n private val sp: ServiceProduct.Aux[Prod, Alg] = mirror.serviceProduct\n\n private val ehbProduct = sp\n .mapK5(\n sp.endpointsProduct,\n new PolyFunction5[sp.service.Endpoint, EndpointHandlerBuilder] {\n\n override def apply[I, E, O, SI, SO](\n fa: sp.service.Endpoint[I, E, O, SI, SO]\n ): EndpointHandlerBuilder[I, E, O, SI, SO] =\n new EndpointHandlerBuilder[I, E, O, SI, SO] {\n\n override def apply(f: I => O): EndpointHandler =\n new EndpointHandler {\n type I_ = I\n type O_ = O\n override val id: ShapeId = fa.id\n override val function: I_ => O_ = f\n }\n\n }\n\n },\n )\n\n def build: Alg[ToList] = sp\n .service\n .algebra(new sp.service.EndpointCompiler[ToList] {\n\n override def apply[I, E, O, SI, SO](\n fa: sp.service.Endpoint[I, E, O, SI, SO]\n ): I => List[O] = {\n\n val matchingHandlers = handlers\n .filter(_.id == fa.id)\n // A bit of type unsafety, to simplify things\n .map(_.function.asInstanceOf[I => O])\n\n i => matchingHandlers.map(_.apply(i))\n\n }\n\n })\n\n def withHandler(\n op: Prod[EndpointHandlerBuilder] => EndpointHandler\n ): PartialBuilder[Alg, Prod] = copy(handlers = handlers :+ op(ehbProduct))\n\n}\n\ndef partialBuilder[Alg[_[_, _, _, _, _]]](\n mirror: ServiceProduct.Mirror[Alg]\n): PartialBuilder[Alg, mirror.Prod] = new PartialBuilder[Alg, mirror.Prod](mirror, handlers = Nil)\n"))),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},'val listService: ExampleServiceGen[ToList] =\n partialBuilder(ExampleService)\n .withHandler(_.exampleOperation { (in: ExampleOperationInput) =>\n ExampleOperationOutput(s"First output for ${in.a}!")\n })\n .withHandler(_.exampleOperation { (in: ExampleOperationInput) =>\n ExampleOperationOutput(s"Another output for ${in.a}!")\n })\n .build\n// listService: ExampleServiceGen[ToList] = smithy4s.example.product.ExampleServiceOperation$Transformed@5ac6743d\n\nlistService.exampleOperation("hello")\n// res2: ToList[ExampleOperationInput, Nothing, ExampleOperationOutput, Nothing, Nothing] = List(\n// ExampleOperationOutput(b = "First output for hello!"),\n// ExampleOperationOutput(b = "Another output for hello!")\n// )\n')))}d.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunksmithy4s=self.webpackChunksmithy4s||[]).push([[7054],{3905:(e,n,t)=>{t.d(n,{Zo:()=>s,kt:()=>v});var r=t(7294);function i(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function a(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function o(e){for(var n=1;n=0||(i[t]=e[t]);return i}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var l=r.createContext({}),c=function(e){var n=r.useContext(l),t=n;return e&&(t="function"==typeof e?e(n):o(o({},n),e)),t},s=function(e){var n=c(e.components);return r.createElement(l.Provider,{value:n},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},m=r.forwardRef((function(e,n){var t=e.components,i=e.mdxType,a=e.originalType,l=e.parentName,s=p(e,["components","mdxType","originalType","parentName"]),u=c(t),m=i,v=u["".concat(l,".").concat(m)]||u[m]||d[m]||a;return t?r.createElement(v,o(o({ref:n},s),{},{components:t})):r.createElement(v,o({ref:n},s))}));function v(e,n){var t=arguments,i=n&&n.mdxType;if("string"==typeof e||i){var a=t.length,o=new Array(a);o[0]=m;var p={};for(var l in n)hasOwnProperty.call(n,l)&&(p[l]=n[l]);p.originalType=e,p[u]="string"==typeof e?e:i,o[1]=p;for(var c=2;c{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>d,frontMatter:()=>a,metadata:()=>p,toc:()=>c});var r=t(7462),i=(t(7294),t(3905));const a={sidebar_label:"Service Product",title:"Service Product"},o=void 0,p={unversionedId:"codegen/customisation/service-product",id:"codegen/customisation/service-product",title:"Service Product",description:"As of smithy4s version 0.18.x you can also generate a service interface in",source:"@site/../docs/target/jvm-2.13/mdoc/04-codegen/01-customisation/10-service-product.md",sourceDirName:"04-codegen/01-customisation",slug:"/codegen/customisation/service-product",permalink:"/smithy4s/docs/codegen/customisation/service-product",draft:!1,editUrl:"https://github.com/disneystreaming/smithy4s/edit/main/modules/docs/src/04-codegen/01-customisation/10-service-product.md",tags:[],version:"current",sidebarPosition:10,frontMatter:{sidebar_label:"Service Product",title:"Service Product"},sidebar:"tutorialSidebar",previous:{title:"Typeclass Instances",permalink:"/smithy4s/docs/codegen/customisation/typeclass"},next:{title:"Optics",permalink:"/smithy4s/docs/codegen/customisation/optics"}},l={},c=[{value:"Static description of services",id:"static-description-of-services",level:3},{value:"Non-linear input of operation",id:"non-linear-input-of-operation",level:3},{value:"Fluent service builder",id:"fluent-service-builder",level:3}],s={toc:c},u="wrapper";function d(e){let{components:n,...t}=e;return(0,i.kt)(u,(0,r.Z)({},s,t,{components:n,mdxType:"MDXLayout"}),(0,i.kt)("p",null,"As of smithy4s version ",(0,i.kt)("inlineCode",{parentName:"p"},"0.18.x"),' you can also generate a service interface in\nwhich each method doesn\'t receive an input. Instead, the output of each method\nhas the usual return type, which already includes the input as a type parameter.\nWe call this version a "service product" because it can be seen as the product\nof all the operations of the service.'),(0,i.kt)("p",null,"To generate a service product, annotate the service definition with"),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"@generateServiceProduct"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-kotlin"},'$version: "2"\n\nnamespace smithy4s.example.product\n\nuse smithy4s.meta#generateServiceProduct\n\n@generateServiceProduct\nservice ExampleService {\n operations: [ExampleOperation]\n}\n\noperation ExampleOperation {\n input := {\n @required\n a: String\n }\n output := {\n @required\n b: String\n }\n}\n')),(0,i.kt)("p",null,"This will generate the following interface:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},"trait ExampleServiceProductGen[F[_, _, _, _, _]] {\n def exampleOperation: F[ExampleOperationInput, Nothing, ExampleOperationOutput, Nothing, Nothing]\n}\n")),(0,i.kt)("p",null,"and the following implementation of ",(0,i.kt)("inlineCode",{parentName:"p"},"ServiceProduct"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},"object ExampleServiceProductGen extends ServiceProduct[ExampleServiceProductGen]\n")),(0,i.kt)("p",null,"You will be able to access the service product version of the service like this:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},"import smithy4s.example.product._\n\nExampleServiceGen.serviceProduct\n// res0: smithy4s.ServiceProduct.Aux[ExampleServiceProductGen, ExampleServiceGen] = smithy4s.example.product.ExampleServiceProductGen$@745f6bee\n")),(0,i.kt)("p",null,"Or, more generically:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},"import smithy4s.ServiceProduct\n\ndef productOf[Alg[_[_, _, _, _, _]]](mirror: ServiceProduct.Mirror[Alg]) = mirror.serviceProduct\n\n// example\ndef exampleProduct = productOf(ExampleService)\n")),(0,i.kt)("p",null,"With service products, you can call service methods without providing their inputs directly."),(0,i.kt)("p",null,"Here are a couple ways you can use this as a library author:"),(0,i.kt)("h3",{id:"static-description-of-services"},"Static description of services"),(0,i.kt)("details",null,(0,i.kt)("summary",null,"Implementation"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},'import smithy4s.kinds.PolyFunction5\n\ntype Describe[_, _, _, _, _] = String\n\ndef descriptor[Alg[_[_, _, _, _, _]]](mirror: ServiceProduct.Mirror[Alg]): mirror.Prod[Describe] =\n mirror\n .serviceProduct\n .mapK5(\n mirror.serviceProduct.endpointsProduct,\n new PolyFunction5[mirror.serviceProduct.service.Endpoint, Describe] {\n\n override def apply[I, E, O, SI, SO](\n fa: mirror.serviceProduct.service.Endpoint[I, E, O, SI, SO]\n ): Describe[I, E, O, SI, SO] =\n s"def ${fa.name}(input: ${fa.input.shapeId.name}): ${fa.output.shapeId.name}"\n\n },\n )\n'))),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},'// Usage\n\nval desc: String = descriptor(ExampleService).exampleOperation\n// desc: String = "def ExampleOperation(input: ExampleOperationInput): ExampleOperationOutput"\n')),(0,i.kt)("h3",{id:"non-linear-input-of-operation"},"Non-linear input of operation"),(0,i.kt)("details",null,(0,i.kt)("summary",null,"Implementation"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},'import smithy4s.ShapeId\n\ntype Id[A] = A\n\nval impl: ExampleService[Id] =\n new ExampleService[Id] {\n\n override def exampleOperation(input: String): ExampleOperationOutput = ExampleOperationOutput(\n s"Output for $input!"\n )\n\n }\n// impl: ExampleService[Id] = repl.MdocSession$MdocApp$$anon$2@71d6ecf5\n\ntype ListClient[I, _, O, _, _] = List[I] => List[O]\n\ndef listClient[Alg[_[_, _, _, _, _]], Prod[_[_, _, _, _, _]]](\n impl: smithy4s.kinds.FunctorAlgebra[Alg, Id]\n)(\n implicit sp: ServiceProduct.Aux[Prod, Alg]\n): Prod[ListClient] = sp\n .mapK5(\n sp.endpointsProduct,\n new PolyFunction5[sp.service.Endpoint, ListClient] {\n\n private val interp = sp.service.toPolyFunction(impl)\n\n override def apply[I, E, O, SI, SO](\n fa: sp.service.Endpoint[I, E, O, SI, SO]\n ): List[I] => List[O] = _.map(in => interp(fa.wrap(in)))\n\n },\n )\n'))),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},'listClient(impl)( /* implicit scope problem here - TODO */ ExampleService.serviceProduct)\n .exampleOperation(\n List("a", "b", "c").map(ExampleOperationInput(_))\n )\n// res1: List[ExampleOperationOutput] = List(\n// ExampleOperationOutput(b = "Output for a!"),\n// ExampleOperationOutput(b = "Output for b!"),\n// ExampleOperationOutput(b = "Output for c!")\n// )\n')),(0,i.kt)("h3",{id:"fluent-service-builder"},"Fluent service builder"),(0,i.kt)("details",null,(0,i.kt)("summary",null,"Implementation"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},"type ToList[_, _, O, _, _] = List[O]\n\ntrait EndpointHandlerBuilder[I, E, O, SI, SO] {\n def apply(f: I => O): EndpointHandler\n}\n\nsealed trait EndpointHandler {\n type I_\n type O_\n def id: ShapeId\n def function: I_ => O_\n}\n\ncase class PartialBuilder[Alg[_[_, _, _, _, _]], Prod[_[_, _, _, _, _]]](\n mirror: ServiceProduct.Mirror.Aux[Alg, Prod],\n handlers: List[EndpointHandler],\n) {\n private val sp: ServiceProduct.Aux[Prod, Alg] = mirror.serviceProduct\n\n private val ehbProduct = sp\n .mapK5(\n sp.endpointsProduct,\n new PolyFunction5[sp.service.Endpoint, EndpointHandlerBuilder] {\n\n override def apply[I, E, O, SI, SO](\n fa: sp.service.Endpoint[I, E, O, SI, SO]\n ): EndpointHandlerBuilder[I, E, O, SI, SO] =\n new EndpointHandlerBuilder[I, E, O, SI, SO] {\n\n override def apply(f: I => O): EndpointHandler =\n new EndpointHandler {\n type I_ = I\n type O_ = O\n override val id: ShapeId = fa.id\n override val function: I_ => O_ = f\n }\n\n }\n\n },\n )\n\n def build: Alg[ToList] = sp\n .service\n .algebra(new sp.service.EndpointCompiler[ToList] {\n\n override def apply[I, E, O, SI, SO](\n fa: sp.service.Endpoint[I, E, O, SI, SO]\n ): I => List[O] = {\n\n val matchingHandlers = handlers\n .filter(_.id == fa.id)\n // A bit of type unsafety, to simplify things\n .map(_.function.asInstanceOf[I => O])\n\n i => matchingHandlers.map(_.apply(i))\n\n }\n\n })\n\n def withHandler(\n op: Prod[EndpointHandlerBuilder] => EndpointHandler\n ): PartialBuilder[Alg, Prod] = copy(handlers = handlers :+ op(ehbProduct))\n\n}\n\ndef partialBuilder[Alg[_[_, _, _, _, _]]](\n mirror: ServiceProduct.Mirror[Alg]\n): PartialBuilder[Alg, mirror.Prod] = new PartialBuilder[Alg, mirror.Prod](mirror, handlers = Nil)\n"))),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},'val listService: ExampleServiceGen[ToList] =\n partialBuilder(ExampleService)\n .withHandler(_.exampleOperation { (in: ExampleOperationInput) =>\n ExampleOperationOutput(s"First output for ${in.a}!")\n })\n .withHandler(_.exampleOperation { (in: ExampleOperationInput) =>\n ExampleOperationOutput(s"Another output for ${in.a}!")\n })\n .build\n// listService: ExampleServiceGen[ToList] = smithy4s.example.product.ExampleServiceOperation$Transformed@7840d9bd\n\nlistService.exampleOperation("hello")\n// res2: ToList[ExampleOperationInput, Nothing, ExampleOperationOutput, Nothing, Nothing] = List(\n// ExampleOperationOutput(b = "First output for hello!"),\n// ExampleOperationOutput(b = "Another output for hello!")\n// )\n')))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/15cc563a.5775364d.js b/assets/js/15cc563a.5775364d.js deleted file mode 100644 index 86df312f3..000000000 --- a/assets/js/15cc563a.5775364d.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunksmithy4s=self.webpackChunksmithy4s||[]).push([[6998],{3905:(e,i,t)=>{t.d(i,{Zo:()=>o,kt:()=>y});var s=t(7294);function a(e,i,t){return i in e?Object.defineProperty(e,i,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[i]=t,e}function l(e,i){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);i&&(s=s.filter((function(i){return Object.getOwnPropertyDescriptor(e,i).enumerable}))),t.push.apply(t,s)}return t}function n(e){for(var i=1;i=0||(a[t]=e[t]);return a}(e,i);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(s=0;s=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(a[t]=e[t])}return a}var r=s.createContext({}),c=function(e){var i=s.useContext(r),t=i;return e&&(t="function"==typeof e?e(i):n(n({},i),e)),t},o=function(e){var i=c(e.components);return s.createElement(r.Provider,{value:i},e.children)},u="mdxType",p={inlineCode:"code",wrapper:function(e){var i=e.children;return s.createElement(s.Fragment,{},i)}},d=s.forwardRef((function(e,i){var t=e.components,a=e.mdxType,l=e.originalType,r=e.parentName,o=m(e,["components","mdxType","originalType","parentName"]),u=c(t),d=a,y=u["".concat(r,".").concat(d)]||u[d]||p[d]||l;return t?s.createElement(y,n(n({ref:i},o),{},{components:t})):s.createElement(y,n({ref:i},o))}));function y(e,i){var t=arguments,a=i&&i.mdxType;if("string"==typeof e||a){var l=t.length,n=new Array(l);n[0]=d;var m={};for(var r in i)hasOwnProperty.call(i,r)&&(m[r]=i[r]);m.originalType=e,m[u]="string"==typeof e?e:a,n[1]=m;for(var c=2;c{t.r(i),t.d(i,{assets:()=>r,contentTitle:()=>n,default:()=>p,frontMatter:()=>l,metadata:()=>m,toc:()=>c});var s=t(7462),a=(t(7294),t(3905));const l={sidebar_label:"AWS"},n=void 0,m={unversionedId:"protocols/aws/aws",id:"protocols/aws/aws",title:"aws",description:"WARNING: READ THE FOLLOWING, AND USE WITH CAUTION",source:"@site/../docs/target/jvm-2.13/mdoc/03-protocols/03-aws/01-aws.md",sourceDirName:"03-protocols/03-aws",slug:"/protocols/aws/aws",permalink:"/smithy4s/docs/protocols/aws/aws",draft:!1,editUrl:"https://github.com/disneystreaming/smithy4s/edit/main/modules/docs/src/03-protocols/03-aws/01-aws.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_label:"AWS"},sidebar:"tutorialSidebar",previous:{title:"What is a Protocol?",permalink:"/smithy4s/docs/protocols/definition"},next:{title:"Localstack",permalink:"/smithy4s/docs/protocols/aws/localstack"}},r={},c=[{value:"What is missing ?",id:"what-is-missing-",level:3},{value:"Note on pre-built artifacts",id:"note-on-pre-built-artifacts",level:3},{value:"Setup",id:"setup",level:2},{value:"SBT",id:"sbt",level:3},{value:"Mill",id:"mill",level:3},{value:"Example usage",id:"example-usage",level:2},{value:"Note on where to find the AWS specifications",id:"note-on-where-to-find-the-aws-specifications",level:2},{value:"Service summary",id:"service-summary",level:2},{value:"\u2705 Supported (at least partially)",id:"-supported-at-least-partially",level:3},{value:"restJson1",id:"restjson1",level:3},{value:"\u2705 accessanalyzer",id:"-accessanalyzer",level:4},{value:"\u2705 account",id:"-account",level:4},{value:"\u2705 amp",id:"-amp",level:4},{value:"\u2705 amplify",id:"-amplify",level:4},{value:"\u2705 amplifybackend",id:"-amplifybackend",level:4},{value:"\u2705 amplifyuibuilder",id:"-amplifyuibuilder",level:4},{value:"\u2705 api-gateway",id:"-api-gateway",level:4},{value:"\u2705 apigatewaymanagementapi",id:"-apigatewaymanagementapi",level:4},{value:"\u2705 apigatewayv2",id:"-apigatewayv2",level:4},{value:"\u2705 app-mesh",id:"-app-mesh",level:4},{value:"\u2705 appconfig",id:"-appconfig",level:4},{value:"\u2705 appconfigdata",id:"-appconfigdata",level:4},{value:"\u2705 appfabric",id:"-appfabric",level:4},{value:"\u2705 appflow",id:"-appflow",level:4},{value:"\u2705 appintegrations",id:"-appintegrations",level:4},{value:"\u2705 applicationcostprofiler",id:"-applicationcostprofiler",level:4},{value:"\u2705 appsync",id:"-appsync",level:4},{value:"\u2705 arc-zonal-shift",id:"-arc-zonal-shift",level:4},{value:"\u2705 auditmanager",id:"-auditmanager",level:4},{value:"\u2705 backup",id:"-backup",level:4},{value:"\u26a0\ufe0f backupstorage",id:"\ufe0f-backupstorage",level:4},{value:"\u2705 batch",id:"-batch",level:4},{value:"\u2705 billingconductor",id:"-billingconductor",level:4},{value:"\u2705 braket",id:"-braket",level:4},{value:"\u2705 chime-sdk-identity",id:"-chime-sdk-identity",level:4},{value:"\u2705 chime-sdk-media-pipelines",id:"-chime-sdk-media-pipelines",level:4},{value:"\u2705 chime-sdk-meetings",id:"-chime-sdk-meetings",level:4},{value:"\u2705 chime-sdk-messaging",id:"-chime-sdk-messaging",level:4},{value:"\u2705 chime-sdk-voice",id:"-chime-sdk-voice",level:4},{value:"\u2705 chime",id:"-chime",level:4},{value:"\u2705 cleanrooms",id:"-cleanrooms",level:4},{value:"\u2705 clouddirectory",id:"-clouddirectory",level:4},{value:"\u26a0\ufe0f cloudsearch-domain",id:"\ufe0f-cloudsearch-domain",level:4},{value:"\u2705 cloudtrail-data",id:"-cloudtrail-data",level:4},{value:"\u26a0\ufe0f codeartifact",id:"\ufe0f-codeartifact",level:4},{value:"\u2705 codecatalyst",id:"-codecatalyst",level:4},{value:"\u2705 codeguru-reviewer",id:"-codeguru-reviewer",level:4},{value:"\u2705 codeguru-security",id:"-codeguru-security",level:4},{value:"\u2705 codeguruprofiler",id:"-codeguruprofiler",level:4},{value:"\u2705 codestar-notifications",id:"-codestar-notifications",level:4},{value:"\u2705 cognito-sync",id:"-cognito-sync",level:4},{value:"\u2705 connect-contact-lens",id:"-connect-contact-lens",level:4},{value:"\u2705 connect",id:"-connect",level:4},{value:"\u2705 connectcampaigns",id:"-connectcampaigns",level:4},{value:"\u2705 connectcases",id:"-connectcases",level:4},{value:"\u2705 connectparticipant",id:"-connectparticipant",level:4},{value:"\u2705 controltower",id:"-controltower",level:4},{value:"\u2705 customer-profiles",id:"-customer-profiles",level:4},{value:"\u2705 databrew",id:"-databrew",level:4},{value:"\u2705 dataexchange",id:"-dataexchange",level:4},{value:"\u2705 detective",id:"-detective",level:4},{value:"\u2705 devops-guru",id:"-devops-guru",level:4},{value:"\u2705 dlm",id:"-dlm",level:4},{value:"\u2705 docdb-elastic",id:"-docdb-elastic",level:4},{value:"\u2705 drs",id:"-drs",level:4},{value:"\u26a0\ufe0f ebs",id:"\ufe0f-ebs",level:4},{value:"\u2705 efs",id:"-efs",level:4},{value:"\u2705 eks",id:"-eks",level:4},{value:"\u2705 elastic-inference",id:"-elastic-inference",level:4},{value:"\u2705 elastic-transcoder",id:"-elastic-transcoder",level:4},{value:"\u2705 elasticsearch-service",id:"-elasticsearch-service",level:4},{value:"\u2705 emr-containers",id:"-emr-containers",level:4},{value:"\u2705 emr-serverless",id:"-emr-serverless",level:4},{value:"\u2705 entityresolution",id:"-entityresolution",level:4},{value:"\u2705 evidently",id:"-evidently",level:4},{value:"\u2705 finspace-data",id:"-finspace-data",level:4},{value:"\u2705 finspace",id:"-finspace",level:4},{value:"\u2705 fis",id:"-fis",level:4},{value:"\u2705 gamesparks",id:"-gamesparks",level:4},{value:"\u26a0\ufe0f glacier",id:"\ufe0f-glacier",level:4},{value:"\u2705 grafana",id:"-grafana",level:4},{value:"\u2705 greengrass",id:"-greengrass",level:4},{value:"\u2705 greengrassv2",id:"-greengrassv2",level:4},{value:"\u2705 groundstation",id:"-groundstation",level:4},{value:"\u2705 guardduty",id:"-guardduty",level:4},{value:"\u2705 honeycode",id:"-honeycode",level:4},{value:"\u2705 imagebuilder",id:"-imagebuilder",level:4},{value:"\u2705 inspector2",id:"-inspector2",level:4},{value:"\u2705 internetmonitor",id:"-internetmonitor",level:4},{value:"\u2705 iot-1click-devices-service",id:"-iot-1click-devices-service",level:4},{value:"\u2705 iot-1click-projects",id:"-iot-1click-projects",level:4},{value:"\u2705 iot-data-plane",id:"-iot-data-plane",level:4},{value:"\u2705 iot-events-data",id:"-iot-events-data",level:4},{value:"\u2705 iot-events",id:"-iot-events",level:4},{value:"\u2705 iot-jobs-data-plane",id:"-iot-jobs-data-plane",level:4},{value:"\u2705 iot-roborunner",id:"-iot-roborunner",level:4},{value:"\u2705 iot-wireless",id:"-iot-wireless",level:4},{value:"\u2705 iot",id:"-iot",level:4},{value:"\u2705 iotanalytics",id:"-iotanalytics",level:4},{value:"\u2705 iotdeviceadvisor",id:"-iotdeviceadvisor",level:4},{value:"\u2705 iotfleethub",id:"-iotfleethub",level:4},{value:"\u2705 iotsitewise",id:"-iotsitewise",level:4},{value:"\u2705 iottwinmaker",id:"-iottwinmaker",level:4},{value:"\u2705 ivs-realtime",id:"-ivs-realtime",level:4},{value:"\u2705 ivs",id:"-ivs",level:4},{value:"\u2705 ivschat",id:"-ivschat",level:4},{value:"\u2705 kafka",id:"-kafka",level:4},{value:"\u2705 kafkaconnect",id:"-kafkaconnect",level:4},{value:"\u26a0\ufe0f kinesis-video-archived-media",id:"\ufe0f-kinesis-video-archived-media",level:4},{value:"\u26a0\ufe0f kinesis-video-media",id:"\ufe0f-kinesis-video-media",level:4},{value:"\u2705 kinesis-video-signaling",id:"-kinesis-video-signaling",level:4},{value:"\u2705 kinesis-video-webrtc-storage",id:"-kinesis-video-webrtc-storage",level:4},{value:"\u2705 kinesis-video",id:"-kinesis-video",level:4},{value:"\u26a0\ufe0f lakeformation",id:"\ufe0f-lakeformation",level:4},{value:"\u26a0\ufe0f lambda",id:"\ufe0f-lambda",level:4},{value:"\u2705 lex-model-building-service",id:"-lex-model-building-service",level:4},{value:"\u2705 lex-models-v2",id:"-lex-models-v2",level:4},{value:"\u26a0\ufe0f lex-runtime-service",id:"\ufe0f-lex-runtime-service",level:4},{value:"\u26a0\ufe0f lex-runtime-v2",id:"\ufe0f-lex-runtime-v2",level:4},{value:"\u2705 license-manager-linux-subscriptions",id:"-license-manager-linux-subscriptions",level:4},{value:"\u2705 license-manager-user-subscriptions",id:"-license-manager-user-subscriptions",level:4},{value:"\u2705 location",id:"-location",level:4},{value:"\u2705 lookoutmetrics",id:"-lookoutmetrics",level:4},{value:"\u26a0\ufe0f lookoutvision",id:"\ufe0f-lookoutvision",level:4},{value:"\u2705 m2",id:"-m2",level:4},{value:"\u2705 macie2",id:"-macie2",level:4},{value:"\u2705 managedblockchain-query",id:"-managedblockchain-query",level:4},{value:"\u2705 managedblockchain",id:"-managedblockchain",level:4},{value:"\u2705 marketplace-catalog",id:"-marketplace-catalog",level:4},{value:"\u2705 mediaconnect",id:"-mediaconnect",level:4},{value:"\u2705 mediaconvert",id:"-mediaconvert",level:4},{value:"\u26a0\ufe0f medialive",id:"\ufe0f-medialive",level:4},{value:"\u2705 mediapackage-vod",id:"-mediapackage-vod",level:4},{value:"\u2705 mediapackage",id:"-mediapackage",level:4},{value:"\u2705 mediapackagev2",id:"-mediapackagev2",level:4},{value:"\u26a0\ufe0f mediastore-data",id:"\ufe0f-mediastore-data",level:4},{value:"\u2705 mediatailor",id:"-mediatailor",level:4},{value:"\u26a0\ufe0f medical-imaging",id:"\ufe0f-medical-imaging",level:4},{value:"\u2705 mgn",id:"-mgn",level:4},{value:"\u2705 migration-hub-refactor-spaces",id:"-migration-hub-refactor-spaces",level:4},{value:"\u2705 migrationhuborchestrator",id:"-migrationhuborchestrator",level:4},{value:"\u2705 migrationhubstrategy",id:"-migrationhubstrategy",level:4},{value:"\u2705 mobile",id:"-mobile",level:4},{value:"\u2705 mq",id:"-mq",level:4},{value:"\u2705 mwaa",id:"-mwaa",level:4},{value:"\u2705 neptunedata",id:"-neptunedata",level:4},{value:"\u2705 networkmanager",id:"-networkmanager",level:4},{value:"\u2705 nimble",id:"-nimble",level:4},{value:"\u2705 oam",id:"-oam",level:4},{value:"\u26a0\ufe0f omics",id:"\ufe0f-omics",level:4},{value:"\u2705 opensearch",id:"-opensearch",level:4},{value:"\u2705 osis",id:"-osis",level:4},{value:"\u2705 outposts",id:"-outposts",level:4},{value:"\u2705 panorama",id:"-panorama",level:4},{value:"\u2705 payment-cryptography-data",id:"-payment-cryptography-data",level:4},{value:"\u2705 pca-connector-ad",id:"-pca-connector-ad",level:4},{value:"\u2705 personalize-events",id:"-personalize-events",level:4},{value:"\u2705 personalize-runtime",id:"-personalize-runtime",level:4},{value:"\u2705 pinpoint-email",id:"-pinpoint-email",level:4},{value:"\u2705 pinpoint-sms-voice",id:"-pinpoint-sms-voice",level:4},{value:"\u2705 pinpoint",id:"-pinpoint",level:4},{value:"\u2705 pipes",id:"-pipes",level:4},{value:"\u26a0\ufe0f polly",id:"\ufe0f-polly",level:4},{value:"\u2705 privatenetworks",id:"-privatenetworks",level:4},{value:"\u2705 qldb",id:"-qldb",level:4},{value:"\u2705 quicksight",id:"-quicksight",level:4},{value:"\u2705 ram",id:"-ram",level:4},{value:"\u2705 rbin",id:"-rbin",level:4},{value:"\u2705 rds-data",id:"-rds-data",level:4},{value:"\u26a0\ufe0f rekognitionstreaming",id:"\ufe0f-rekognitionstreaming",level:4},{value:"\u2705 resiliencehub",id:"-resiliencehub",level:4},{value:"\u2705 resource-explorer-2",id:"-resource-explorer-2",level:4},{value:"\u2705 resource-groups",id:"-resource-groups",level:4},{value:"\u2705 robomaker",id:"-robomaker",level:4},{value:"\u2705 rolesanywhere",id:"-rolesanywhere",level:4},{value:"\u2705 route53-recovery-control-config",id:"-route53-recovery-control-config",level:4},{value:"\u2705 route53-recovery-readiness",id:"-route53-recovery-readiness",level:4},{value:"\u2705 rum",id:"-rum",level:4},{value:"\u2705 s3outposts",id:"-s3outposts",level:4},{value:"\u2705 sagemaker-a2i-runtime",id:"-sagemaker-a2i-runtime",level:4},{value:"\u2705 sagemaker-edge",id:"-sagemaker-edge",level:4},{value:"\u2705 sagemaker-featurestore-runtime",id:"-sagemaker-featurestore-runtime",level:4},{value:"\u26a0\ufe0f sagemaker-geospatial",id:"\ufe0f-sagemaker-geospatial",level:4},{value:"\u2705 sagemaker-metrics",id:"-sagemaker-metrics",level:4},{value:"\u26a0\ufe0f sagemaker-runtime",id:"\ufe0f-sagemaker-runtime",level:4},{value:"\u2705 savingsplans",id:"-savingsplans",level:4},{value:"\u2705 scheduler",id:"-scheduler",level:4},{value:"\u2705 schemas",id:"-schemas",level:4},{value:"\u2705 securityhub",id:"-securityhub",level:4},{value:"\u2705 securitylake",id:"-securitylake",level:4},{value:"\u2705 serverlessapplicationrepository",id:"-serverlessapplicationrepository",level:4},{value:"\u2705 service-catalog-appregistry",id:"-service-catalog-appregistry",level:4},{value:"\u2705 sesv2",id:"-sesv2",level:4},{value:"\u2705 signer",id:"-signer",level:4},{value:"\u2705 simspaceweaver",id:"-simspaceweaver",level:4},{value:"\u2705 snow-device-management",id:"-snow-device-management",level:4},{value:"\u2705 ssm-incidents",id:"-ssm-incidents",level:4},{value:"\u2705 ssm-sap",id:"-ssm-sap",level:4},{value:"\u2705 sso-oidc",id:"-sso-oidc",level:4},{value:"\u2705 sso",id:"-sso",level:4},{value:"\u2705 support-app",id:"-support-app",level:4},{value:"\u2705 synthetics",id:"-synthetics",level:4},{value:"\u2705 tnb",id:"-tnb",level:4},{value:"\u26a0\ufe0f transcribe-streaming",id:"\ufe0f-transcribe-streaming",level:4},{value:"\u2705 vpc-lattice",id:"-vpc-lattice",level:4},{value:"\u2705 wellarchitected",id:"-wellarchitected",level:4},{value:"\u2705 wisdom",id:"-wisdom",level:4},{value:"\u2705 workdocs",id:"-workdocs",level:4},{value:"\u2705 worklink",id:"-worklink",level:4},{value:"\u26a0\ufe0f workmailmessageflow",id:"\ufe0f-workmailmessageflow",level:4},{value:"\u2705 workspaces-web",id:"-workspaces-web",level:4},{value:"\u2705 xray",id:"-xray",level:4},{value:"ec2Query",id:"ec2query",level:3},{value:"\u2705 ec2",id:"-ec2",level:4},{value:"awsQuery",id:"awsquery",level:3},{value:"\u2705 auto-scaling",id:"-auto-scaling",level:4},{value:"\u2705 cloudformation",id:"-cloudformation",level:4},{value:"\u2705 cloudsearch",id:"-cloudsearch",level:4},{value:"\u2705 cloudwatch",id:"-cloudwatch",level:4},{value:"\u2705 docdb",id:"-docdb",level:4},{value:"\u2705 elastic-beanstalk",id:"-elastic-beanstalk",level:4},{value:"\u2705 elastic-load-balancing-v2",id:"-elastic-load-balancing-v2",level:4},{value:"\u2705 elastic-load-balancing",id:"-elastic-load-balancing",level:4},{value:"\u2705 elasticache",id:"-elasticache",level:4},{value:"\u2705 iam",id:"-iam",level:4},{value:"\u2705 neptune",id:"-neptune",level:4},{value:"\u2705 rds",id:"-rds",level:4},{value:"\u2705 redshift",id:"-redshift",level:4},{value:"\u2705 ses",id:"-ses",level:4},{value:"\u2705 sns",id:"-sns",level:4},{value:"\u2705 sqs",id:"-sqs",level:4},{value:"\u2705 sts",id:"-sts",level:4},{value:"awsJson1_0",id:"awsjson1_0",level:3},{value:"\u2705 apprunner",id:"-apprunner",level:4},{value:"\u2705 backup-gateway",id:"-backup-gateway",level:4},{value:"\u2705 cloudcontrol",id:"-cloudcontrol",level:4},{value:"\u2705 codestar-connections",id:"-codestar-connections",level:4},{value:"\u2705 compute-optimizer",id:"-compute-optimizer",level:4},{value:"\u2705 dynamodb-streams",id:"-dynamodb-streams",level:4},{value:"\u2705 dynamodb",id:"-dynamodb",level:4},{value:"\u2705 healthlake",id:"-healthlake",level:4},{value:"\u2705 iotfleetwise",id:"-iotfleetwise",level:4},{value:"\u2705 kendra-ranking",id:"-kendra-ranking",level:4},{value:"\u2705 keyspaces",id:"-keyspaces",level:4},{value:"\u2705 lookoutequipment",id:"-lookoutequipment",level:4},{value:"\u2705 network-firewall",id:"-network-firewall",level:4},{value:"\u2705 opensearchserverless",id:"-opensearchserverless",level:4},{value:"\u2705 payment-cryptography",id:"-payment-cryptography",level:4},{value:"\u2705 pinpoint-sms-voice-v2",id:"-pinpoint-sms-voice-v2",level:4},{value:"\u2705 proton",id:"-proton",level:4},{value:"\u2705 qldb-session",id:"-qldb-session",level:4},{value:"\u2705 route53-recovery-cluster",id:"-route53-recovery-cluster",level:4},{value:"\u2705 sfn",id:"-sfn",level:4},{value:"\u2705 swf",id:"-swf",level:4},{value:"\u2705 timestream-query",id:"-timestream-query",level:4},{value:"\u2705 timestream-write",id:"-timestream-write",level:4},{value:"\u2705 verifiedpermissions",id:"-verifiedpermissions",level:4},{value:"\u2705 voice-id",id:"-voice-id",level:4},{value:"awsJson1_1",id:"awsjson1_1",level:3},{value:"\u2705 acm-pca",id:"-acm-pca",level:4},{value:"\u2705 acm",id:"-acm",level:4},{value:"\u2705 alexa-for-business",id:"-alexa-for-business",level:4},{value:"\u2705 application-auto-scaling",id:"-application-auto-scaling",level:4},{value:"\u2705 application-discovery-service",id:"-application-discovery-service",level:4},{value:"\u2705 application-insights",id:"-application-insights",level:4},{value:"\u2705 appstream",id:"-appstream",level:4},{value:"\u2705 athena",id:"-athena",level:4},{value:"\u2705 auto-scaling-plans",id:"-auto-scaling-plans",level:4},{value:"\u2705 budgets",id:"-budgets",level:4},{value:"\u2705 cloud9",id:"-cloud9",level:4},{value:"\u2705 cloudhsm-v2",id:"-cloudhsm-v2",level:4},{value:"\u2705 cloudhsm",id:"-cloudhsm",level:4},{value:"\u2705 cloudtrail",id:"-cloudtrail",level:4},{value:"\u2705 cloudwatch-events",id:"-cloudwatch-events",level:4},{value:"\u2705 cloudwatch-logs",id:"-cloudwatch-logs",level:4},{value:"\u2705 codebuild",id:"-codebuild",level:4},{value:"\u2705 codecommit",id:"-codecommit",level:4},{value:"\u2705 codedeploy",id:"-codedeploy",level:4},{value:"\u2705 codepipeline",id:"-codepipeline",level:4},{value:"\u2705 codestar",id:"-codestar",level:4},{value:"\u2705 cognito-identity-provider",id:"-cognito-identity-provider",level:4},{value:"\u2705 cognito-identity",id:"-cognito-identity",level:4},{value:"\u2705 comprehend",id:"-comprehend",level:4},{value:"\u2705 comprehendmedical",id:"-comprehendmedical",level:4},{value:"\u2705 config-service",id:"-config-service",level:4},{value:"\u2705 cost-and-usage-report-service",id:"-cost-and-usage-report-service",level:4},{value:"\u2705 cost-explorer",id:"-cost-explorer",level:4},{value:"\u2705 data-pipeline",id:"-data-pipeline",level:4},{value:"\u2705 database-migration-service",id:"-database-migration-service",level:4},{value:"\u2705 datasync",id:"-datasync",level:4},{value:"\u2705 dax",id:"-dax",level:4},{value:"\u2705 device-farm",id:"-device-farm",level:4},{value:"\u2705 direct-connect",id:"-direct-connect",level:4},{value:"\u2705 directory-service",id:"-directory-service",level:4},{value:"\u2705 ec2-instance-connect",id:"-ec2-instance-connect",level:4},{value:"\u2705 ecr-public",id:"-ecr-public",level:4},{value:"\u2705 ecr",id:"-ecr",level:4},{value:"\u2705 ecs",id:"-ecs",level:4},{value:"\u2705 emr",id:"-emr",level:4},{value:"\u2705 eventbridge",id:"-eventbridge",level:4},{value:"\u2705 firehose",id:"-firehose",level:4},{value:"\u2705 fms",id:"-fms",level:4},{value:"\u2705 forecast",id:"-forecast",level:4},{value:"\u2705 forecastquery",id:"-forecastquery",level:4},{value:"\u2705 frauddetector",id:"-frauddetector",level:4},{value:"\u2705 fsx",id:"-fsx",level:4},{value:"\u2705 gamelift",id:"-gamelift",level:4},{value:"\u2705 global-accelerator",id:"-global-accelerator",level:4},{value:"\u2705 glue",id:"-glue",level:4},{value:"\u2705 health",id:"-health",level:4},{value:"\u2705 identitystore",id:"-identitystore",level:4},{value:"\u2705 inspector",id:"-inspector",level:4},{value:"\u2705 iotsecuretunneling",id:"-iotsecuretunneling",level:4},{value:"\u2705 iotthingsgraph",id:"-iotthingsgraph",level:4},{value:"\u2705 kendra",id:"-kendra",level:4},{value:"\u2705 kinesis-analytics-v2",id:"-kinesis-analytics-v2",level:4},{value:"\u2705 kinesis-analytics",id:"-kinesis-analytics",level:4},{value:"\u26a0\ufe0f kinesis",id:"\ufe0f-kinesis",level:4},{value:"\u2705 kms",id:"-kms",level:4},{value:"\u2705 license-manager",id:"-license-manager",level:4},{value:"\u2705 lightsail",id:"-lightsail",level:4},{value:"\u2705 machine-learning",id:"-machine-learning",level:4},{value:"\u2705 macie",id:"-macie",level:4},{value:"\u2705 marketplace-commerce-analytics",id:"-marketplace-commerce-analytics",level:4},{value:"\u2705 marketplace-entitlement-service",id:"-marketplace-entitlement-service",level:4},{value:"\u2705 marketplace-metering",id:"-marketplace-metering",level:4},{value:"\u2705 mediastore",id:"-mediastore",level:4},{value:"\u2705 memorydb",id:"-memorydb",level:4},{value:"\u2705 migration-hub",id:"-migration-hub",level:4},{value:"\u2705 migrationhub-config",id:"-migrationhub-config",level:4},{value:"\u2705 mturk",id:"-mturk",level:4},{value:"\u2705 opsworks",id:"-opsworks",level:4},{value:"\u2705 opsworkscm",id:"-opsworkscm",level:4},{value:"\u2705 organizations",id:"-organizations",level:4},{value:"\u2705 personalize",id:"-personalize",level:4},{value:"\u2705 pi",id:"-pi",level:4},{value:"\u2705 pricing",id:"-pricing",level:4},{value:"\u2705 redshift-data",id:"-redshift-data",level:4},{value:"\u2705 redshift-serverless",id:"-redshift-serverless",level:4},{value:"\u2705 rekognition",id:"-rekognition",level:4},{value:"\u2705 resource-groups-tagging-api",id:"-resource-groups-tagging-api",level:4},{value:"\u2705 route-53-domains",id:"-route-53-domains",level:4},{value:"\u2705 route53resolver",id:"-route53resolver",level:4},{value:"\u2705 sagemaker",id:"-sagemaker",level:4},{value:"\u2705 secrets-manager",id:"-secrets-manager",level:4},{value:"\u2705 service-catalog",id:"-service-catalog",level:4},{value:"\u2705 service-quotas",id:"-service-quotas",level:4},{value:"\u2705 servicediscovery",id:"-servicediscovery",level:4},{value:"\u2705 shield",id:"-shield",level:4},{value:"\u2705 sms",id:"-sms",level:4},{value:"\u2705 snowball",id:"-snowball",level:4},{value:"\u2705 ssm-contacts",id:"-ssm-contacts",level:4},{value:"\u2705 ssm",id:"-ssm",level:4},{value:"\u2705 sso-admin",id:"-sso-admin",level:4},{value:"\u2705 storage-gateway",id:"-storage-gateway",level:4},{value:"\u2705 support",id:"-support",level:4},{value:"\u2705 textract",id:"-textract",level:4},{value:"\u2705 transcribe",id:"-transcribe",level:4},{value:"\u2705 transfer",id:"-transfer",level:4},{value:"\u2705 translate",id:"-translate",level:4},{value:"\u2705 waf-regional",id:"-waf-regional",level:4},{value:"\u2705 waf",id:"-waf",level:4},{value:"\u2705 wafv2",id:"-wafv2",level:4},{value:"\u2705 workmail",id:"-workmail",level:4},{value:"\u2705 workspaces",id:"-workspaces",level:4},{value:"restXml",id:"restxml",level:3},{value:"\u2705 cloudfront",id:"-cloudfront",level:4},{value:"\u2705 route-53",id:"-route-53",level:4},{value:"\u2705 s3-control",id:"-s3-control",level:4},{value:"\u26a0\ufe0f s3",id:"\ufe0f-s3",level:4}],o={toc:c},u="wrapper";function p(e){let{components:i,...t}=e;return(0,a.kt)(u,(0,s.Z)({},o,t,{components:i,mdxType:"MDXLayout"}),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"WARNING: READ THE FOLLOWING, AND USE WITH CAUTION")),(0,a.kt)("p",null,"Smithy4s provides functions to create AWS clients from generated code. As of 0.18, Smithy4s supports (at least partially) all AWS protocols that are publicly documented."),(0,a.kt)("p",null,"Our implementation of the AWS protocols is tested against the official ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/smithy-lang/smithy/tree/main/smithy-aws-protocol-tests/model"},"compliance-tests"),", which gives us a reasonable level of confidence that most of the (de)serialisation logic involved when communicating with AWS is correct. Our implementation of the AWS signature algorithm (which is required for AWS to authenticate requests) is tested against the Java implementation used by the official AWS SDK."),(0,a.kt)("h3",{id:"what-is-missing-"},"What is missing ?"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"streaming operations (such as S3 ",(0,a.kt)("inlineCode",{parentName:"li"},"putObject"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"getObject"),", or Kinesis' ",(0,a.kt)("inlineCode",{parentName:"li"},"subscribeToShard"),") are currently unsupported."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://smithy.io/2.0/aws/customizations/index.html"},"service-specific customisations")," are currently unsupported."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"users should not use smithy4s to get data into/out of AWS S3"))),(0,a.kt)("h3",{id:"note-on-pre-built-artifacts"},"Note on pre-built artifacts"),(0,a.kt)("p",null,"We (the Smithy4s maintainers) ",(0,a.kt)("strong",{parentName:"p"},"do not")," intend to publish pre-generated artifacts containing the AWS clients, there's a lot of nuance there and maintainance burden that we do not have the capacity to assume. In particular, backward binary compatibility of the generated code is impossible to guarantee at this time."),(0,a.kt)("h2",{id:"setup"},"Setup"),(0,a.kt)("h3",{id:"sbt"},"SBT"),(0,a.kt)("p",null,"In ",(0,a.kt)("inlineCode",{parentName:"p"},"build.sbt")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-scala"},'libraryDependencies ++= Seq(\n "com.disneystreaming.smithy4s" %% "smithy4s-aws-http4s" % smithy4sVersion.value\n)\n// The `AWS` object contains a list of references to artifacts that contain specifications to AWS services.\nsmithy4sAwsSpecs ++= Seq(AWS.dynamodb)\n')),(0,a.kt)("p",null,"Alternatively, the following is also valid :"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-scala"},'libraryDependencies ++= Seq(\n // version sourced from the plugin\n "com.disneystreaming.smithy4s" %% "smithy4s-aws-http4s" % smithy4sVersion.value\n "com.disneystreaming.smithy" % "aws-dynamodb-spec" % "2023.09.22" % Smithy4s\n)\n')),(0,a.kt)("h3",{id:"mill"},"Mill"),(0,a.kt)("p",null,"In ",(0,a.kt)("inlineCode",{parentName:"p"},"build.sc")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-scala"},'import $ivy.`com.disneystreaming.smithy4s::smithy4s-mill-codegen-plugin::0.18.9`\nimport smithy4s.codegen.mill._\n\nobject foo extends Smithy4sModule {\n override def scalaVersion = "2.13.10"\n override def ivyDeps = Agg(\n ivy"com.disneystreaming.smithy4s::smithy4s-aws-http4s:${smithy4sVersion()}",\n )\n override def smithy4sAwsSpecs: T[Seq[String]] = T(Seq(AWS.dynamodb))\n}\n')),(0,a.kt)("h2",{id:"example-usage"},"Example usage"),(0,a.kt)("p",null,"In your Scala code:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-scala"},"import cats.effect._\nimport org.http4s.ember.client.EmberClientBuilder\n\nimport smithy4s.aws._ // AWS specific interpreters // AWS specific interpreters\nimport com.amazonaws.dynamodb._ // Generated code from specs. // Generated code from specs.\n\nobject Main extends IOApp.Simple {\n\n def run = resource.use { case (dynamodb) =>\n dynamodb\n .listTables(limit = Some(ListTablesInputLimit(10)))\n .flatMap(IO.println(_))\n }\n\n val resource: Resource[IO, DynamoDB[IO]] =\n for {\n httpClient <- EmberClientBuilder.default[IO].build\n awsEnv <- AwsEnvironment.default(httpClient, AwsRegion.US_EAST_1)\n dynamodb <- AwsClient(DynamoDB, awsEnv)\n } yield dynamodb\n\n}\n")),(0,a.kt)("h2",{id:"note-on-where-to-find-the-aws-specifications"},"Note on where to find the AWS specifications"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"SBT : ",(0,a.kt)("inlineCode",{parentName:"li"},'"com.disneystreaming.smithy" % s"aws-${service_name}-spec" % "2023.09.22"')),(0,a.kt)("li",{parentName:"ul"},"Mill : ",(0,a.kt)("inlineCode",{parentName:"li"},'ivy"com.disneystreaming.smithy:aws-${service_name}-spec:2023.09.22"'))),(0,a.kt)("p",null,"The version corresponds to the latest release in this repo: ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/disneystreaming/aws-sdk-smithy-specs"},"aws-sdk-smithy-specs"),"."),(0,a.kt)("p",null,"AWS does not publishes the specs to their services to Maven. However, The specs in question (that are written in json syntax) can be found in some of the ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/aws/aws-sdk-js-v3/tree/main/codegen/sdk-codegen/aws-models"},"official SDKs")," published by AWS. These ",(0,a.kt)("inlineCode",{parentName:"p"},".json files")," can be understood by smithy4s, just like ",(0,a.kt)("inlineCode",{parentName:"p"},".smithy"),", and can be used to generate code."),(0,a.kt)("p",null,"The ",(0,a.kt)("strong",{parentName:"p"},"aws-sdk-smithy-specs")," project periodically gathers the specs from the Javascript SDK repo and publishes them to maven central to lower the barrier of entry."),(0,a.kt)("h2",{id:"service-summary"},"Service summary"),(0,a.kt)("p",null,"Below you'll find a generated summary of the maven coordinates for the AWS specifications. Note\nthat the version of the spec might not be the latest one. Refer yourself to ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/disneystreaming/aws-sdk-smithy-specs"},"this repo")," to get the latest version of the specs."),(0,a.kt)("h3",{id:"-supported-at-least-partially"},"\u2705 Supported (at least partially)"),(0,a.kt)("h3",{id:"restjson1"},"restJson1"),(0,a.kt)("h4",{id:"-accessanalyzer"},"\u2705 accessanalyzer"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-accessanalyzer-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-accessanalyzer-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-account"},"\u2705 account"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-account-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-account-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-amp"},"\u2705 amp"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-amp-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-amp-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-amplify"},"\u2705 amplify"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-amplify-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-amplify-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-amplifybackend"},"\u2705 amplifybackend"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-amplifybackend-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-amplifybackend-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-amplifyuibuilder"},"\u2705 amplifyuibuilder"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-amplifyuibuilder-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-amplifyuibuilder-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-api-gateway"},"\u2705 api-gateway"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-api-gateway-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-api-gateway-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-apigatewaymanagementapi"},"\u2705 apigatewaymanagementapi"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-apigatewaymanagementapi-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-apigatewaymanagementapi-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-apigatewayv2"},"\u2705 apigatewayv2"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-apigatewayv2-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-apigatewayv2-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-app-mesh"},"\u2705 app-mesh"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-app-mesh-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-app-mesh-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-appconfig"},"\u2705 appconfig"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-appconfig-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-appconfig-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-appconfigdata"},"\u2705 appconfigdata"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-appconfigdata-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-appconfigdata-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-appfabric"},"\u2705 appfabric"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-appfabric-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-appfabric-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-appflow"},"\u2705 appflow"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-appflow-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-appflow-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-appintegrations"},"\u2705 appintegrations"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-appintegrations-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-appintegrations-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-applicationcostprofiler"},"\u2705 applicationcostprofiler"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-applicationcostprofiler-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-applicationcostprofiler-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-appsync"},"\u2705 appsync"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-appsync-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-appsync-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-arc-zonal-shift"},"\u2705 arc-zonal-shift"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-arc-zonal-shift-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-arc-zonal-shift-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-auditmanager"},"\u2705 auditmanager"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-auditmanager-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-auditmanager-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-backup"},"\u2705 backup"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-backup-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-backup-spec:2023.09.22"')),(0,a.kt)("h4",{id:"\ufe0f-backupstorage"},"\u26a0\ufe0f backupstorage"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-backupstorage-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-backupstorage-spec:2023.09.22"')),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Unsupported streaming operations")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"NotifyObjectComplete"),(0,a.kt)("li",{parentName:"ul"},"PutChunk"),(0,a.kt)("li",{parentName:"ul"},"PutObject"),(0,a.kt)("li",{parentName:"ul"},"GetChunk"),(0,a.kt)("li",{parentName:"ul"},"GetObjectMetadata")),(0,a.kt)("h4",{id:"-batch"},"\u2705 batch"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-batch-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-batch-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-billingconductor"},"\u2705 billingconductor"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-billingconductor-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-billingconductor-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-braket"},"\u2705 braket"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-braket-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-braket-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-chime-sdk-identity"},"\u2705 chime-sdk-identity"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-chime-sdk-identity-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-chime-sdk-identity-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-chime-sdk-media-pipelines"},"\u2705 chime-sdk-media-pipelines"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-chime-sdk-media-pipelines-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-chime-sdk-media-pipelines-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-chime-sdk-meetings"},"\u2705 chime-sdk-meetings"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-chime-sdk-meetings-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-chime-sdk-meetings-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-chime-sdk-messaging"},"\u2705 chime-sdk-messaging"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-chime-sdk-messaging-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-chime-sdk-messaging-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-chime-sdk-voice"},"\u2705 chime-sdk-voice"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-chime-sdk-voice-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-chime-sdk-voice-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-chime"},"\u2705 chime"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-chime-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-chime-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-cleanrooms"},"\u2705 cleanrooms"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-cleanrooms-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-cleanrooms-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-clouddirectory"},"\u2705 clouddirectory"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-clouddirectory-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-clouddirectory-spec:2023.09.22"')),(0,a.kt)("h4",{id:"\ufe0f-cloudsearch-domain"},"\u26a0\ufe0f cloudsearch-domain"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-cloudsearch-domain-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-cloudsearch-domain-spec:2023.09.22"')),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Unsupported streaming operations")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"UploadDocuments")),(0,a.kt)("h4",{id:"-cloudtrail-data"},"\u2705 cloudtrail-data"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-cloudtrail-data-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-cloudtrail-data-spec:2023.09.22"')),(0,a.kt)("h4",{id:"\ufe0f-codeartifact"},"\u26a0\ufe0f codeartifact"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-codeartifact-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-codeartifact-spec:2023.09.22"')),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Unsupported streaming operations")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"GetPackageVersionAsset"),(0,a.kt)("li",{parentName:"ul"},"PublishPackageVersion")),(0,a.kt)("h4",{id:"-codecatalyst"},"\u2705 codecatalyst"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-codecatalyst-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-codecatalyst-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-codeguru-reviewer"},"\u2705 codeguru-reviewer"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-codeguru-reviewer-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-codeguru-reviewer-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-codeguru-security"},"\u2705 codeguru-security"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-codeguru-security-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-codeguru-security-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-codeguruprofiler"},"\u2705 codeguruprofiler"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-codeguruprofiler-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-codeguruprofiler-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-codestar-notifications"},"\u2705 codestar-notifications"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-codestar-notifications-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-codestar-notifications-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-cognito-sync"},"\u2705 cognito-sync"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-cognito-sync-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-cognito-sync-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-connect-contact-lens"},"\u2705 connect-contact-lens"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-connect-contact-lens-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-connect-contact-lens-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-connect"},"\u2705 connect"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-connect-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-connect-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-connectcampaigns"},"\u2705 connectcampaigns"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-connectcampaigns-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-connectcampaigns-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-connectcases"},"\u2705 connectcases"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-connectcases-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-connectcases-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-connectparticipant"},"\u2705 connectparticipant"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-connectparticipant-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-connectparticipant-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-controltower"},"\u2705 controltower"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-controltower-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-controltower-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-customer-profiles"},"\u2705 customer-profiles"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-customer-profiles-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-customer-profiles-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-databrew"},"\u2705 databrew"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-databrew-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-databrew-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-dataexchange"},"\u2705 dataexchange"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-dataexchange-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-dataexchange-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-detective"},"\u2705 detective"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-detective-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-detective-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-devops-guru"},"\u2705 devops-guru"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-devops-guru-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-devops-guru-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-dlm"},"\u2705 dlm"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-dlm-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-dlm-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-docdb-elastic"},"\u2705 docdb-elastic"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-docdb-elastic-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-docdb-elastic-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-drs"},"\u2705 drs"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-drs-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-drs-spec:2023.09.22"')),(0,a.kt)("h4",{id:"\ufe0f-ebs"},"\u26a0\ufe0f ebs"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-ebs-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-ebs-spec:2023.09.22"')),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Unsupported streaming operations")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"PutSnapshotBlock"),(0,a.kt)("li",{parentName:"ul"},"GetSnapshotBlock")),(0,a.kt)("h4",{id:"-efs"},"\u2705 efs"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-efs-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-efs-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-eks"},"\u2705 eks"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-eks-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-eks-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-elastic-inference"},"\u2705 elastic-inference"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-elastic-inference-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-elastic-inference-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-elastic-transcoder"},"\u2705 elastic-transcoder"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-elastic-transcoder-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-elastic-transcoder-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-elasticsearch-service"},"\u2705 elasticsearch-service"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-elasticsearch-service-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-elasticsearch-service-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-emr-containers"},"\u2705 emr-containers"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-emr-containers-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-emr-containers-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-emr-serverless"},"\u2705 emr-serverless"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-emr-serverless-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-emr-serverless-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-entityresolution"},"\u2705 entityresolution"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-entityresolution-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-entityresolution-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-evidently"},"\u2705 evidently"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-evidently-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-evidently-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-finspace-data"},"\u2705 finspace-data"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-finspace-data-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-finspace-data-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-finspace"},"\u2705 finspace"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-finspace-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-finspace-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-fis"},"\u2705 fis"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-fis-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-fis-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-gamesparks"},"\u2705 gamesparks"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-gamesparks-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-gamesparks-spec:2023.09.22"')),(0,a.kt)("h4",{id:"\ufe0f-glacier"},"\u26a0\ufe0f glacier"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-glacier-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-glacier-spec:2023.09.22"')),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Unsupported streaming operations")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"GetJobOutput"),(0,a.kt)("li",{parentName:"ul"},"UploadArchive"),(0,a.kt)("li",{parentName:"ul"},"UploadMultipartPart")),(0,a.kt)("h4",{id:"-grafana"},"\u2705 grafana"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-grafana-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-grafana-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-greengrass"},"\u2705 greengrass"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-greengrass-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-greengrass-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-greengrassv2"},"\u2705 greengrassv2"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-greengrassv2-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-greengrassv2-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-groundstation"},"\u2705 groundstation"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-groundstation-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-groundstation-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-guardduty"},"\u2705 guardduty"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-guardduty-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-guardduty-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-honeycode"},"\u2705 honeycode"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-honeycode-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-honeycode-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-imagebuilder"},"\u2705 imagebuilder"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-imagebuilder-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-imagebuilder-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-inspector2"},"\u2705 inspector2"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-inspector2-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-inspector2-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-internetmonitor"},"\u2705 internetmonitor"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-internetmonitor-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-internetmonitor-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-iot-1click-devices-service"},"\u2705 iot-1click-devices-service"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-iot-1click-devices-service-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-iot-1click-devices-service-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-iot-1click-projects"},"\u2705 iot-1click-projects"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-iot-1click-projects-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-iot-1click-projects-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-iot-data-plane"},"\u2705 iot-data-plane"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-iot-data-plane-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-iot-data-plane-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-iot-events-data"},"\u2705 iot-events-data"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-iot-events-data-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-iot-events-data-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-iot-events"},"\u2705 iot-events"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-iot-events-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-iot-events-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-iot-jobs-data-plane"},"\u2705 iot-jobs-data-plane"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-iot-jobs-data-plane-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-iot-jobs-data-plane-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-iot-roborunner"},"\u2705 iot-roborunner"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-iot-roborunner-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-iot-roborunner-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-iot-wireless"},"\u2705 iot-wireless"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-iot-wireless-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-iot-wireless-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-iot"},"\u2705 iot"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-iot-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-iot-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-iotanalytics"},"\u2705 iotanalytics"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-iotanalytics-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-iotanalytics-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-iotdeviceadvisor"},"\u2705 iotdeviceadvisor"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-iotdeviceadvisor-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-iotdeviceadvisor-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-iotfleethub"},"\u2705 iotfleethub"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-iotfleethub-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-iotfleethub-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-iotsitewise"},"\u2705 iotsitewise"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-iotsitewise-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-iotsitewise-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-iottwinmaker"},"\u2705 iottwinmaker"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-iottwinmaker-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-iottwinmaker-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-ivs-realtime"},"\u2705 ivs-realtime"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-ivs-realtime-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-ivs-realtime-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-ivs"},"\u2705 ivs"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-ivs-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-ivs-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-ivschat"},"\u2705 ivschat"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-ivschat-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-ivschat-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-kafka"},"\u2705 kafka"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-kafka-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-kafka-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-kafkaconnect"},"\u2705 kafkaconnect"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-kafkaconnect-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-kafkaconnect-spec:2023.09.22"')),(0,a.kt)("h4",{id:"\ufe0f-kinesis-video-archived-media"},"\u26a0\ufe0f kinesis-video-archived-media"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-kinesis-video-archived-media-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-kinesis-video-archived-media-spec:2023.09.22"')),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Unsupported streaming operations")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"GetClip"),(0,a.kt)("li",{parentName:"ul"},"GetMediaForFragmentList")),(0,a.kt)("h4",{id:"\ufe0f-kinesis-video-media"},"\u26a0\ufe0f kinesis-video-media"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-kinesis-video-media-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-kinesis-video-media-spec:2023.09.22"')),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Unsupported streaming operations")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"GetMedia")),(0,a.kt)("h4",{id:"-kinesis-video-signaling"},"\u2705 kinesis-video-signaling"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-kinesis-video-signaling-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-kinesis-video-signaling-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-kinesis-video-webrtc-storage"},"\u2705 kinesis-video-webrtc-storage"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-kinesis-video-webrtc-storage-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-kinesis-video-webrtc-storage-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-kinesis-video"},"\u2705 kinesis-video"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-kinesis-video-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-kinesis-video-spec:2023.09.22"')),(0,a.kt)("h4",{id:"\ufe0f-lakeformation"},"\u26a0\ufe0f lakeformation"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-lakeformation-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-lakeformation-spec:2023.09.22"')),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Unsupported streaming operations")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"GetWorkUnitResults")),(0,a.kt)("h4",{id:"\ufe0f-lambda"},"\u26a0\ufe0f lambda"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-lambda-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-lambda-spec:2023.09.22"')),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Unsupported streaming operations")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"InvokeWithResponseStream"),(0,a.kt)("li",{parentName:"ul"},"InvokeAsync")),(0,a.kt)("h4",{id:"-lex-model-building-service"},"\u2705 lex-model-building-service"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-lex-model-building-service-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-lex-model-building-service-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-lex-models-v2"},"\u2705 lex-models-v2"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-lex-models-v2-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-lex-models-v2-spec:2023.09.22"')),(0,a.kt)("h4",{id:"\ufe0f-lex-runtime-service"},"\u26a0\ufe0f lex-runtime-service"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-lex-runtime-service-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-lex-runtime-service-spec:2023.09.22"')),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Unsupported streaming operations")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"PostContent"),(0,a.kt)("li",{parentName:"ul"},"PutSession")),(0,a.kt)("h4",{id:"\ufe0f-lex-runtime-v2"},"\u26a0\ufe0f lex-runtime-v2"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-lex-runtime-v2-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-lex-runtime-v2-spec:2023.09.22"')),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Unsupported streaming operations")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"RecognizeUtterance"),(0,a.kt)("li",{parentName:"ul"},"PutSession"),(0,a.kt)("li",{parentName:"ul"},"StartConversation")),(0,a.kt)("h4",{id:"-license-manager-linux-subscriptions"},"\u2705 license-manager-linux-subscriptions"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-license-manager-linux-subscriptions-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-license-manager-linux-subscriptions-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-license-manager-user-subscriptions"},"\u2705 license-manager-user-subscriptions"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-license-manager-user-subscriptions-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-license-manager-user-subscriptions-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-location"},"\u2705 location"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-location-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-location-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-lookoutmetrics"},"\u2705 lookoutmetrics"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-lookoutmetrics-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-lookoutmetrics-spec:2023.09.22"')),(0,a.kt)("h4",{id:"\ufe0f-lookoutvision"},"\u26a0\ufe0f lookoutvision"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-lookoutvision-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-lookoutvision-spec:2023.09.22"')),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Unsupported streaming operations")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"DetectAnomalies")),(0,a.kt)("h4",{id:"-m2"},"\u2705 m2"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-m2-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-m2-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-macie2"},"\u2705 macie2"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-macie2-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-macie2-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-managedblockchain-query"},"\u2705 managedblockchain-query"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-managedblockchain-query-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-managedblockchain-query-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-managedblockchain"},"\u2705 managedblockchain"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-managedblockchain-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-managedblockchain-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-marketplace-catalog"},"\u2705 marketplace-catalog"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-marketplace-catalog-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-marketplace-catalog-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-mediaconnect"},"\u2705 mediaconnect"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-mediaconnect-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-mediaconnect-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-mediaconvert"},"\u2705 mediaconvert"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-mediaconvert-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-mediaconvert-spec:2023.09.22"')),(0,a.kt)("h4",{id:"\ufe0f-medialive"},"\u26a0\ufe0f medialive"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-medialive-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-medialive-spec:2023.09.22"')),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Unsupported streaming operations")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"DescribeInputDeviceThumbnail")),(0,a.kt)("h4",{id:"-mediapackage-vod"},"\u2705 mediapackage-vod"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-mediapackage-vod-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-mediapackage-vod-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-mediapackage"},"\u2705 mediapackage"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-mediapackage-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-mediapackage-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-mediapackagev2"},"\u2705 mediapackagev2"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-mediapackagev2-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-mediapackagev2-spec:2023.09.22"')),(0,a.kt)("h4",{id:"\ufe0f-mediastore-data"},"\u26a0\ufe0f mediastore-data"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-mediastore-data-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-mediastore-data-spec:2023.09.22"')),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Unsupported streaming operations")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"PutObject"),(0,a.kt)("li",{parentName:"ul"},"GetObject")),(0,a.kt)("h4",{id:"-mediatailor"},"\u2705 mediatailor"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-mediatailor-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-mediatailor-spec:2023.09.22"')),(0,a.kt)("h4",{id:"\ufe0f-medical-imaging"},"\u26a0\ufe0f medical-imaging"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-medical-imaging-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-medical-imaging-spec:2023.09.22"')),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Unsupported streaming operations")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"GetImageSetMetadata"),(0,a.kt)("li",{parentName:"ul"},"GetImageFrame")),(0,a.kt)("h4",{id:"-mgn"},"\u2705 mgn"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-mgn-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-mgn-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-migration-hub-refactor-spaces"},"\u2705 migration-hub-refactor-spaces"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-migration-hub-refactor-spaces-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-migration-hub-refactor-spaces-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-migrationhuborchestrator"},"\u2705 migrationhuborchestrator"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-migrationhuborchestrator-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-migrationhuborchestrator-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-migrationhubstrategy"},"\u2705 migrationhubstrategy"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-migrationhubstrategy-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-migrationhubstrategy-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-mobile"},"\u2705 mobile"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-mobile-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-mobile-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-mq"},"\u2705 mq"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-mq-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-mq-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-mwaa"},"\u2705 mwaa"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-mwaa-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-mwaa-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-neptunedata"},"\u2705 neptunedata"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-neptunedata-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-neptunedata-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-networkmanager"},"\u2705 networkmanager"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-networkmanager-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-networkmanager-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-nimble"},"\u2705 nimble"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-nimble-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-nimble-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-oam"},"\u2705 oam"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-oam-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-oam-spec:2023.09.22"')),(0,a.kt)("h4",{id:"\ufe0f-omics"},"\u26a0\ufe0f omics"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-omics-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-omics-spec:2023.09.22"')),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Unsupported streaming operations")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"GetReference"),(0,a.kt)("li",{parentName:"ul"},"GetReadSet"),(0,a.kt)("li",{parentName:"ul"},"UploadReadSetPart")),(0,a.kt)("h4",{id:"-opensearch"},"\u2705 opensearch"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-opensearch-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-opensearch-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-osis"},"\u2705 osis"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-osis-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-osis-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-outposts"},"\u2705 outposts"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-outposts-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-outposts-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-panorama"},"\u2705 panorama"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-panorama-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-panorama-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-payment-cryptography-data"},"\u2705 payment-cryptography-data"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-payment-cryptography-data-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-payment-cryptography-data-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-pca-connector-ad"},"\u2705 pca-connector-ad"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-pca-connector-ad-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-pca-connector-ad-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-personalize-events"},"\u2705 personalize-events"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-personalize-events-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-personalize-events-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-personalize-runtime"},"\u2705 personalize-runtime"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-personalize-runtime-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-personalize-runtime-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-pinpoint-email"},"\u2705 pinpoint-email"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-pinpoint-email-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-pinpoint-email-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-pinpoint-sms-voice"},"\u2705 pinpoint-sms-voice"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-pinpoint-sms-voice-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-pinpoint-sms-voice-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-pinpoint"},"\u2705 pinpoint"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-pinpoint-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-pinpoint-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-pipes"},"\u2705 pipes"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-pipes-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-pipes-spec:2023.09.22"')),(0,a.kt)("h4",{id:"\ufe0f-polly"},"\u26a0\ufe0f polly"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-polly-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-polly-spec:2023.09.22"')),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Unsupported streaming operations")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"SynthesizeSpeech")),(0,a.kt)("h4",{id:"-privatenetworks"},"\u2705 privatenetworks"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-privatenetworks-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-privatenetworks-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-qldb"},"\u2705 qldb"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-qldb-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-qldb-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-quicksight"},"\u2705 quicksight"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-quicksight-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-quicksight-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-ram"},"\u2705 ram"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-ram-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-ram-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-rbin"},"\u2705 rbin"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-rbin-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-rbin-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-rds-data"},"\u2705 rds-data"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-rds-data-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-rds-data-spec:2023.09.22"')),(0,a.kt)("h4",{id:"\ufe0f-rekognitionstreaming"},"\u26a0\ufe0f rekognitionstreaming"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-rekognitionstreaming-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-rekognitionstreaming-spec:2023.09.22"')),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Unsupported streaming operations")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"StartFaceLivenessSession")),(0,a.kt)("h4",{id:"-resiliencehub"},"\u2705 resiliencehub"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-resiliencehub-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-resiliencehub-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-resource-explorer-2"},"\u2705 resource-explorer-2"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-resource-explorer-2-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-resource-explorer-2-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-resource-groups"},"\u2705 resource-groups"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-resource-groups-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-resource-groups-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-robomaker"},"\u2705 robomaker"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-robomaker-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-robomaker-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-rolesanywhere"},"\u2705 rolesanywhere"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-rolesanywhere-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-rolesanywhere-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-route53-recovery-control-config"},"\u2705 route53-recovery-control-config"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-route53-recovery-control-config-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-route53-recovery-control-config-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-route53-recovery-readiness"},"\u2705 route53-recovery-readiness"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-route53-recovery-readiness-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-route53-recovery-readiness-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-rum"},"\u2705 rum"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-rum-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-rum-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-s3outposts"},"\u2705 s3outposts"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-s3outposts-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-s3outposts-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-sagemaker-a2i-runtime"},"\u2705 sagemaker-a2i-runtime"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-sagemaker-a2i-runtime-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-sagemaker-a2i-runtime-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-sagemaker-edge"},"\u2705 sagemaker-edge"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-sagemaker-edge-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-sagemaker-edge-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-sagemaker-featurestore-runtime"},"\u2705 sagemaker-featurestore-runtime"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-sagemaker-featurestore-runtime-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-sagemaker-featurestore-runtime-spec:2023.09.22"')),(0,a.kt)("h4",{id:"\ufe0f-sagemaker-geospatial"},"\u26a0\ufe0f sagemaker-geospatial"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-sagemaker-geospatial-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-sagemaker-geospatial-spec:2023.09.22"')),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Unsupported streaming operations")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"GetTile")),(0,a.kt)("h4",{id:"-sagemaker-metrics"},"\u2705 sagemaker-metrics"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-sagemaker-metrics-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-sagemaker-metrics-spec:2023.09.22"')),(0,a.kt)("h4",{id:"\ufe0f-sagemaker-runtime"},"\u26a0\ufe0f sagemaker-runtime"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-sagemaker-runtime-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-sagemaker-runtime-spec:2023.09.22"')),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Unsupported streaming operations")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"InvokeEndpointWithResponseStream")),(0,a.kt)("h4",{id:"-savingsplans"},"\u2705 savingsplans"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-savingsplans-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-savingsplans-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-scheduler"},"\u2705 scheduler"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-scheduler-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-scheduler-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-schemas"},"\u2705 schemas"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-schemas-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-schemas-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-securityhub"},"\u2705 securityhub"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-securityhub-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-securityhub-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-securitylake"},"\u2705 securitylake"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-securitylake-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-securitylake-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-serverlessapplicationrepository"},"\u2705 serverlessapplicationrepository"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-serverlessapplicationrepository-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-serverlessapplicationrepository-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-service-catalog-appregistry"},"\u2705 service-catalog-appregistry"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-service-catalog-appregistry-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-service-catalog-appregistry-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-sesv2"},"\u2705 sesv2"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-sesv2-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-sesv2-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-signer"},"\u2705 signer"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-signer-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-signer-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-simspaceweaver"},"\u2705 simspaceweaver"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-simspaceweaver-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-simspaceweaver-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-snow-device-management"},"\u2705 snow-device-management"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-snow-device-management-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-snow-device-management-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-ssm-incidents"},"\u2705 ssm-incidents"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-ssm-incidents-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-ssm-incidents-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-ssm-sap"},"\u2705 ssm-sap"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-ssm-sap-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-ssm-sap-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-sso-oidc"},"\u2705 sso-oidc"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-sso-oidc-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-sso-oidc-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-sso"},"\u2705 sso"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-sso-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-sso-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-support-app"},"\u2705 support-app"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-support-app-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-support-app-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-synthetics"},"\u2705 synthetics"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-synthetics-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-synthetics-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-tnb"},"\u2705 tnb"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-tnb-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-tnb-spec:2023.09.22"')),(0,a.kt)("h4",{id:"\ufe0f-transcribe-streaming"},"\u26a0\ufe0f transcribe-streaming"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-transcribe-streaming-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-transcribe-streaming-spec:2023.09.22"')),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Unsupported streaming operations")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"StartMedicalStreamTranscription"),(0,a.kt)("li",{parentName:"ul"},"StartCallAnalyticsStreamTranscription"),(0,a.kt)("li",{parentName:"ul"},"StartStreamTranscription")),(0,a.kt)("h4",{id:"-vpc-lattice"},"\u2705 vpc-lattice"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-vpc-lattice-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-vpc-lattice-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-wellarchitected"},"\u2705 wellarchitected"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-wellarchitected-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-wellarchitected-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-wisdom"},"\u2705 wisdom"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-wisdom-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-wisdom-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-workdocs"},"\u2705 workdocs"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-workdocs-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-workdocs-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-worklink"},"\u2705 worklink"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-worklink-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-worklink-spec:2023.09.22"')),(0,a.kt)("h4",{id:"\ufe0f-workmailmessageflow"},"\u26a0\ufe0f workmailmessageflow"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-workmailmessageflow-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-workmailmessageflow-spec:2023.09.22"')),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Unsupported streaming operations")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"GetRawMessageContent")),(0,a.kt)("h4",{id:"-workspaces-web"},"\u2705 workspaces-web"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-workspaces-web-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-workspaces-web-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-xray"},"\u2705 xray"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-xray-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-xray-spec:2023.09.22"')),(0,a.kt)("h3",{id:"ec2query"},"ec2Query"),(0,a.kt)("h4",{id:"-ec2"},"\u2705 ec2"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-ec2-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-ec2-spec:2023.09.22"')),(0,a.kt)("h3",{id:"awsquery"},"awsQuery"),(0,a.kt)("h4",{id:"-auto-scaling"},"\u2705 auto-scaling"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-auto-scaling-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-auto-scaling-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-cloudformation"},"\u2705 cloudformation"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-cloudformation-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-cloudformation-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-cloudsearch"},"\u2705 cloudsearch"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-cloudsearch-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-cloudsearch-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-cloudwatch"},"\u2705 cloudwatch"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-cloudwatch-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-cloudwatch-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-docdb"},"\u2705 docdb"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-docdb-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-docdb-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-elastic-beanstalk"},"\u2705 elastic-beanstalk"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-elastic-beanstalk-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-elastic-beanstalk-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-elastic-load-balancing-v2"},"\u2705 elastic-load-balancing-v2"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-elastic-load-balancing-v2-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-elastic-load-balancing-v2-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-elastic-load-balancing"},"\u2705 elastic-load-balancing"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-elastic-load-balancing-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-elastic-load-balancing-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-elasticache"},"\u2705 elasticache"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-elasticache-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-elasticache-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-iam"},"\u2705 iam"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-iam-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-iam-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-neptune"},"\u2705 neptune"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-neptune-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-neptune-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-rds"},"\u2705 rds"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-rds-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-rds-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-redshift"},"\u2705 redshift"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-redshift-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-redshift-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-ses"},"\u2705 ses"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-ses-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-ses-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-sns"},"\u2705 sns"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-sns-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-sns-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-sqs"},"\u2705 sqs"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-sqs-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-sqs-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-sts"},"\u2705 sts"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-sts-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-sts-spec:2023.09.22"')),(0,a.kt)("h3",{id:"awsjson1_0"},"awsJson1_0"),(0,a.kt)("h4",{id:"-apprunner"},"\u2705 apprunner"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-apprunner-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-apprunner-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-backup-gateway"},"\u2705 backup-gateway"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-backup-gateway-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-backup-gateway-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-cloudcontrol"},"\u2705 cloudcontrol"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-cloudcontrol-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-cloudcontrol-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-codestar-connections"},"\u2705 codestar-connections"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-codestar-connections-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-codestar-connections-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-compute-optimizer"},"\u2705 compute-optimizer"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-compute-optimizer-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-compute-optimizer-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-dynamodb-streams"},"\u2705 dynamodb-streams"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-dynamodb-streams-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-dynamodb-streams-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-dynamodb"},"\u2705 dynamodb"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-dynamodb-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-dynamodb-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-healthlake"},"\u2705 healthlake"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-healthlake-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-healthlake-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-iotfleetwise"},"\u2705 iotfleetwise"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-iotfleetwise-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-iotfleetwise-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-kendra-ranking"},"\u2705 kendra-ranking"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-kendra-ranking-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-kendra-ranking-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-keyspaces"},"\u2705 keyspaces"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-keyspaces-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-keyspaces-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-lookoutequipment"},"\u2705 lookoutequipment"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-lookoutequipment-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-lookoutequipment-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-network-firewall"},"\u2705 network-firewall"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-network-firewall-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-network-firewall-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-opensearchserverless"},"\u2705 opensearchserverless"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-opensearchserverless-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-opensearchserverless-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-payment-cryptography"},"\u2705 payment-cryptography"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-payment-cryptography-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-payment-cryptography-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-pinpoint-sms-voice-v2"},"\u2705 pinpoint-sms-voice-v2"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-pinpoint-sms-voice-v2-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-pinpoint-sms-voice-v2-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-proton"},"\u2705 proton"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-proton-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-proton-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-qldb-session"},"\u2705 qldb-session"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-qldb-session-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-qldb-session-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-route53-recovery-cluster"},"\u2705 route53-recovery-cluster"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-route53-recovery-cluster-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-route53-recovery-cluster-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-sfn"},"\u2705 sfn"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-sfn-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-sfn-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-swf"},"\u2705 swf"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-swf-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-swf-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-timestream-query"},"\u2705 timestream-query"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-timestream-query-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-timestream-query-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-timestream-write"},"\u2705 timestream-write"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-timestream-write-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-timestream-write-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-verifiedpermissions"},"\u2705 verifiedpermissions"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-verifiedpermissions-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-verifiedpermissions-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-voice-id"},"\u2705 voice-id"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-voice-id-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-voice-id-spec:2023.09.22"')),(0,a.kt)("h3",{id:"awsjson1_1"},"awsJson1_1"),(0,a.kt)("h4",{id:"-acm-pca"},"\u2705 acm-pca"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-acm-pca-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-acm-pca-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-acm"},"\u2705 acm"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-acm-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-acm-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-alexa-for-business"},"\u2705 alexa-for-business"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-alexa-for-business-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-alexa-for-business-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-application-auto-scaling"},"\u2705 application-auto-scaling"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-application-auto-scaling-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-application-auto-scaling-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-application-discovery-service"},"\u2705 application-discovery-service"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-application-discovery-service-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-application-discovery-service-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-application-insights"},"\u2705 application-insights"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-application-insights-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-application-insights-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-appstream"},"\u2705 appstream"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-appstream-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-appstream-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-athena"},"\u2705 athena"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-athena-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-athena-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-auto-scaling-plans"},"\u2705 auto-scaling-plans"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-auto-scaling-plans-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-auto-scaling-plans-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-budgets"},"\u2705 budgets"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-budgets-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-budgets-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-cloud9"},"\u2705 cloud9"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-cloud9-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-cloud9-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-cloudhsm-v2"},"\u2705 cloudhsm-v2"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-cloudhsm-v2-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-cloudhsm-v2-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-cloudhsm"},"\u2705 cloudhsm"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-cloudhsm-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-cloudhsm-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-cloudtrail"},"\u2705 cloudtrail"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-cloudtrail-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-cloudtrail-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-cloudwatch-events"},"\u2705 cloudwatch-events"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-cloudwatch-events-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-cloudwatch-events-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-cloudwatch-logs"},"\u2705 cloudwatch-logs"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-cloudwatch-logs-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-cloudwatch-logs-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-codebuild"},"\u2705 codebuild"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-codebuild-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-codebuild-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-codecommit"},"\u2705 codecommit"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-codecommit-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-codecommit-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-codedeploy"},"\u2705 codedeploy"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-codedeploy-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-codedeploy-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-codepipeline"},"\u2705 codepipeline"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-codepipeline-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-codepipeline-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-codestar"},"\u2705 codestar"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-codestar-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-codestar-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-cognito-identity-provider"},"\u2705 cognito-identity-provider"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-cognito-identity-provider-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-cognito-identity-provider-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-cognito-identity"},"\u2705 cognito-identity"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-cognito-identity-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-cognito-identity-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-comprehend"},"\u2705 comprehend"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-comprehend-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-comprehend-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-comprehendmedical"},"\u2705 comprehendmedical"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-comprehendmedical-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-comprehendmedical-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-config-service"},"\u2705 config-service"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-config-service-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-config-service-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-cost-and-usage-report-service"},"\u2705 cost-and-usage-report-service"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-cost-and-usage-report-service-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-cost-and-usage-report-service-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-cost-explorer"},"\u2705 cost-explorer"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-cost-explorer-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-cost-explorer-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-data-pipeline"},"\u2705 data-pipeline"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-data-pipeline-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-data-pipeline-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-database-migration-service"},"\u2705 database-migration-service"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-database-migration-service-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-database-migration-service-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-datasync"},"\u2705 datasync"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-datasync-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-datasync-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-dax"},"\u2705 dax"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-dax-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-dax-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-device-farm"},"\u2705 device-farm"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-device-farm-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-device-farm-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-direct-connect"},"\u2705 direct-connect"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-direct-connect-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-direct-connect-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-directory-service"},"\u2705 directory-service"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-directory-service-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-directory-service-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-ec2-instance-connect"},"\u2705 ec2-instance-connect"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-ec2-instance-connect-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-ec2-instance-connect-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-ecr-public"},"\u2705 ecr-public"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-ecr-public-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-ecr-public-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-ecr"},"\u2705 ecr"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-ecr-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-ecr-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-ecs"},"\u2705 ecs"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-ecs-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-ecs-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-emr"},"\u2705 emr"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-emr-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-emr-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-eventbridge"},"\u2705 eventbridge"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-eventbridge-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-eventbridge-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-firehose"},"\u2705 firehose"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-firehose-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-firehose-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-fms"},"\u2705 fms"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-fms-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-fms-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-forecast"},"\u2705 forecast"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-forecast-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-forecast-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-forecastquery"},"\u2705 forecastquery"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-forecastquery-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-forecastquery-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-frauddetector"},"\u2705 frauddetector"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-frauddetector-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-frauddetector-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-fsx"},"\u2705 fsx"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-fsx-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-fsx-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-gamelift"},"\u2705 gamelift"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-gamelift-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-gamelift-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-global-accelerator"},"\u2705 global-accelerator"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-global-accelerator-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-global-accelerator-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-glue"},"\u2705 glue"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-glue-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-glue-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-health"},"\u2705 health"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-health-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-health-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-identitystore"},"\u2705 identitystore"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-identitystore-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-identitystore-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-inspector"},"\u2705 inspector"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-inspector-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-inspector-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-iotsecuretunneling"},"\u2705 iotsecuretunneling"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-iotsecuretunneling-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-iotsecuretunneling-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-iotthingsgraph"},"\u2705 iotthingsgraph"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-iotthingsgraph-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-iotthingsgraph-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-kendra"},"\u2705 kendra"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-kendra-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-kendra-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-kinesis-analytics-v2"},"\u2705 kinesis-analytics-v2"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-kinesis-analytics-v2-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-kinesis-analytics-v2-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-kinesis-analytics"},"\u2705 kinesis-analytics"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-kinesis-analytics-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-kinesis-analytics-spec:2023.09.22"')),(0,a.kt)("h4",{id:"\ufe0f-kinesis"},"\u26a0\ufe0f kinesis"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-kinesis-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-kinesis-spec:2023.09.22"')),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Unsupported streaming operations")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"SubscribeToShard")),(0,a.kt)("h4",{id:"-kms"},"\u2705 kms"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-kms-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-kms-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-license-manager"},"\u2705 license-manager"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-license-manager-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-license-manager-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-lightsail"},"\u2705 lightsail"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-lightsail-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-lightsail-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-machine-learning"},"\u2705 machine-learning"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-machine-learning-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-machine-learning-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-macie"},"\u2705 macie"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-macie-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-macie-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-marketplace-commerce-analytics"},"\u2705 marketplace-commerce-analytics"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-marketplace-commerce-analytics-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-marketplace-commerce-analytics-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-marketplace-entitlement-service"},"\u2705 marketplace-entitlement-service"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-marketplace-entitlement-service-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-marketplace-entitlement-service-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-marketplace-metering"},"\u2705 marketplace-metering"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-marketplace-metering-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-marketplace-metering-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-mediastore"},"\u2705 mediastore"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-mediastore-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-mediastore-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-memorydb"},"\u2705 memorydb"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-memorydb-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-memorydb-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-migration-hub"},"\u2705 migration-hub"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-migration-hub-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-migration-hub-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-migrationhub-config"},"\u2705 migrationhub-config"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-migrationhub-config-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-migrationhub-config-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-mturk"},"\u2705 mturk"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-mturk-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-mturk-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-opsworks"},"\u2705 opsworks"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-opsworks-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-opsworks-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-opsworkscm"},"\u2705 opsworkscm"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-opsworkscm-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-opsworkscm-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-organizations"},"\u2705 organizations"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-organizations-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-organizations-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-personalize"},"\u2705 personalize"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-personalize-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-personalize-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-pi"},"\u2705 pi"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-pi-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-pi-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-pricing"},"\u2705 pricing"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-pricing-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-pricing-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-redshift-data"},"\u2705 redshift-data"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-redshift-data-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-redshift-data-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-redshift-serverless"},"\u2705 redshift-serverless"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-redshift-serverless-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-redshift-serverless-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-rekognition"},"\u2705 rekognition"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-rekognition-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-rekognition-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-resource-groups-tagging-api"},"\u2705 resource-groups-tagging-api"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-resource-groups-tagging-api-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-resource-groups-tagging-api-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-route-53-domains"},"\u2705 route-53-domains"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-route-53-domains-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-route-53-domains-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-route53resolver"},"\u2705 route53resolver"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-route53resolver-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-route53resolver-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-sagemaker"},"\u2705 sagemaker"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-sagemaker-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-sagemaker-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-secrets-manager"},"\u2705 secrets-manager"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-secrets-manager-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-secrets-manager-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-service-catalog"},"\u2705 service-catalog"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-service-catalog-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-service-catalog-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-service-quotas"},"\u2705 service-quotas"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-service-quotas-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-service-quotas-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-servicediscovery"},"\u2705 servicediscovery"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-servicediscovery-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-servicediscovery-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-shield"},"\u2705 shield"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-shield-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-shield-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-sms"},"\u2705 sms"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-sms-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-sms-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-snowball"},"\u2705 snowball"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-snowball-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-snowball-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-ssm-contacts"},"\u2705 ssm-contacts"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-ssm-contacts-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-ssm-contacts-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-ssm"},"\u2705 ssm"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-ssm-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-ssm-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-sso-admin"},"\u2705 sso-admin"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-sso-admin-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-sso-admin-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-storage-gateway"},"\u2705 storage-gateway"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-storage-gateway-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-storage-gateway-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-support"},"\u2705 support"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-support-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-support-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-textract"},"\u2705 textract"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-textract-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-textract-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-transcribe"},"\u2705 transcribe"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-transcribe-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-transcribe-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-transfer"},"\u2705 transfer"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-transfer-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-transfer-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-translate"},"\u2705 translate"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-translate-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-translate-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-waf-regional"},"\u2705 waf-regional"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-waf-regional-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-waf-regional-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-waf"},"\u2705 waf"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-waf-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-waf-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-wafv2"},"\u2705 wafv2"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-wafv2-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-wafv2-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-workmail"},"\u2705 workmail"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-workmail-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-workmail-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-workspaces"},"\u2705 workspaces"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-workspaces-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-workspaces-spec:2023.09.22"')),(0,a.kt)("h3",{id:"restxml"},"restXml"),(0,a.kt)("h4",{id:"-cloudfront"},"\u2705 cloudfront"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-cloudfront-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-cloudfront-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-route-53"},"\u2705 route-53"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-route-53-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-route-53-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-s3-control"},"\u2705 s3-control"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-s3-control-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-s3-control-spec:2023.09.22"')),(0,a.kt)("h4",{id:"\ufe0f-s3"},"\u26a0\ufe0f s3"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-s3-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-s3-spec:2023.09.22"')),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Unsupported streaming operations")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"WriteGetObjectResponse"),(0,a.kt)("li",{parentName:"ul"},"UploadPart"),(0,a.kt)("li",{parentName:"ul"},"SelectObjectContent"),(0,a.kt)("li",{parentName:"ul"},"PutObject"),(0,a.kt)("li",{parentName:"ul"},"GetObjectTorrent"),(0,a.kt)("li",{parentName:"ul"},"GetObject")))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/15cc563a.98de1f95.js b/assets/js/15cc563a.98de1f95.js new file mode 100644 index 000000000..e88f45789 --- /dev/null +++ b/assets/js/15cc563a.98de1f95.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunksmithy4s=self.webpackChunksmithy4s||[]).push([[6998],{3905:(e,i,t)=>{t.d(i,{Zo:()=>o,kt:()=>y});var s=t(7294);function a(e,i,t){return i in e?Object.defineProperty(e,i,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[i]=t,e}function l(e,i){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);i&&(s=s.filter((function(i){return Object.getOwnPropertyDescriptor(e,i).enumerable}))),t.push.apply(t,s)}return t}function n(e){for(var i=1;i=0||(a[t]=e[t]);return a}(e,i);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(s=0;s=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(a[t]=e[t])}return a}var r=s.createContext({}),c=function(e){var i=s.useContext(r),t=i;return e&&(t="function"==typeof e?e(i):n(n({},i),e)),t},o=function(e){var i=c(e.components);return s.createElement(r.Provider,{value:i},e.children)},u="mdxType",p={inlineCode:"code",wrapper:function(e){var i=e.children;return s.createElement(s.Fragment,{},i)}},d=s.forwardRef((function(e,i){var t=e.components,a=e.mdxType,l=e.originalType,r=e.parentName,o=m(e,["components","mdxType","originalType","parentName"]),u=c(t),d=a,y=u["".concat(r,".").concat(d)]||u[d]||p[d]||l;return t?s.createElement(y,n(n({ref:i},o),{},{components:t})):s.createElement(y,n({ref:i},o))}));function y(e,i){var t=arguments,a=i&&i.mdxType;if("string"==typeof e||a){var l=t.length,n=new Array(l);n[0]=d;var m={};for(var r in i)hasOwnProperty.call(i,r)&&(m[r]=i[r]);m.originalType=e,m[u]="string"==typeof e?e:a,n[1]=m;for(var c=2;c{t.r(i),t.d(i,{assets:()=>r,contentTitle:()=>n,default:()=>p,frontMatter:()=>l,metadata:()=>m,toc:()=>c});var s=t(7462),a=(t(7294),t(3905));const l={sidebar_label:"AWS"},n=void 0,m={unversionedId:"protocols/aws/aws",id:"protocols/aws/aws",title:"aws",description:"WARNING: READ THE FOLLOWING, AND USE WITH CAUTION",source:"@site/../docs/target/jvm-2.13/mdoc/03-protocols/03-aws/01-aws.md",sourceDirName:"03-protocols/03-aws",slug:"/protocols/aws/aws",permalink:"/smithy4s/docs/protocols/aws/aws",draft:!1,editUrl:"https://github.com/disneystreaming/smithy4s/edit/main/modules/docs/src/03-protocols/03-aws/01-aws.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_label:"AWS"},sidebar:"tutorialSidebar",previous:{title:"What is a Protocol?",permalink:"/smithy4s/docs/protocols/definition"},next:{title:"Localstack",permalink:"/smithy4s/docs/protocols/aws/localstack"}},r={},c=[{value:"What is missing ?",id:"what-is-missing-",level:3},{value:"Note on pre-built artifacts",id:"note-on-pre-built-artifacts",level:3},{value:"Setup",id:"setup",level:2},{value:"SBT",id:"sbt",level:3},{value:"Mill",id:"mill",level:3},{value:"Example usage",id:"example-usage",level:2},{value:"Note on where to find the AWS specifications",id:"note-on-where-to-find-the-aws-specifications",level:2},{value:"Service summary",id:"service-summary",level:2},{value:"\u2705 Supported (at least partially)",id:"-supported-at-least-partially",level:3},{value:"restJson1",id:"restjson1",level:3},{value:"\u2705 accessanalyzer",id:"-accessanalyzer",level:4},{value:"\u2705 account",id:"-account",level:4},{value:"\u2705 amp",id:"-amp",level:4},{value:"\u2705 amplify",id:"-amplify",level:4},{value:"\u2705 amplifybackend",id:"-amplifybackend",level:4},{value:"\u2705 amplifyuibuilder",id:"-amplifyuibuilder",level:4},{value:"\u2705 api-gateway",id:"-api-gateway",level:4},{value:"\u2705 apigatewaymanagementapi",id:"-apigatewaymanagementapi",level:4},{value:"\u2705 apigatewayv2",id:"-apigatewayv2",level:4},{value:"\u2705 app-mesh",id:"-app-mesh",level:4},{value:"\u2705 appconfig",id:"-appconfig",level:4},{value:"\u2705 appconfigdata",id:"-appconfigdata",level:4},{value:"\u2705 appfabric",id:"-appfabric",level:4},{value:"\u2705 appflow",id:"-appflow",level:4},{value:"\u2705 appintegrations",id:"-appintegrations",level:4},{value:"\u2705 applicationcostprofiler",id:"-applicationcostprofiler",level:4},{value:"\u2705 appsync",id:"-appsync",level:4},{value:"\u2705 arc-zonal-shift",id:"-arc-zonal-shift",level:4},{value:"\u2705 auditmanager",id:"-auditmanager",level:4},{value:"\u2705 backup",id:"-backup",level:4},{value:"\u26a0\ufe0f backupstorage",id:"\ufe0f-backupstorage",level:4},{value:"\u2705 batch",id:"-batch",level:4},{value:"\u2705 billingconductor",id:"-billingconductor",level:4},{value:"\u2705 braket",id:"-braket",level:4},{value:"\u2705 chime-sdk-identity",id:"-chime-sdk-identity",level:4},{value:"\u2705 chime-sdk-media-pipelines",id:"-chime-sdk-media-pipelines",level:4},{value:"\u2705 chime-sdk-meetings",id:"-chime-sdk-meetings",level:4},{value:"\u2705 chime-sdk-messaging",id:"-chime-sdk-messaging",level:4},{value:"\u2705 chime-sdk-voice",id:"-chime-sdk-voice",level:4},{value:"\u2705 chime",id:"-chime",level:4},{value:"\u2705 cleanrooms",id:"-cleanrooms",level:4},{value:"\u2705 clouddirectory",id:"-clouddirectory",level:4},{value:"\u26a0\ufe0f cloudsearch-domain",id:"\ufe0f-cloudsearch-domain",level:4},{value:"\u2705 cloudtrail-data",id:"-cloudtrail-data",level:4},{value:"\u26a0\ufe0f codeartifact",id:"\ufe0f-codeartifact",level:4},{value:"\u2705 codecatalyst",id:"-codecatalyst",level:4},{value:"\u2705 codeguru-reviewer",id:"-codeguru-reviewer",level:4},{value:"\u2705 codeguru-security",id:"-codeguru-security",level:4},{value:"\u2705 codeguruprofiler",id:"-codeguruprofiler",level:4},{value:"\u2705 codestar-notifications",id:"-codestar-notifications",level:4},{value:"\u2705 cognito-sync",id:"-cognito-sync",level:4},{value:"\u2705 connect-contact-lens",id:"-connect-contact-lens",level:4},{value:"\u2705 connect",id:"-connect",level:4},{value:"\u2705 connectcampaigns",id:"-connectcampaigns",level:4},{value:"\u2705 connectcases",id:"-connectcases",level:4},{value:"\u2705 connectparticipant",id:"-connectparticipant",level:4},{value:"\u2705 controltower",id:"-controltower",level:4},{value:"\u2705 customer-profiles",id:"-customer-profiles",level:4},{value:"\u2705 databrew",id:"-databrew",level:4},{value:"\u2705 dataexchange",id:"-dataexchange",level:4},{value:"\u2705 detective",id:"-detective",level:4},{value:"\u2705 devops-guru",id:"-devops-guru",level:4},{value:"\u2705 dlm",id:"-dlm",level:4},{value:"\u2705 docdb-elastic",id:"-docdb-elastic",level:4},{value:"\u2705 drs",id:"-drs",level:4},{value:"\u26a0\ufe0f ebs",id:"\ufe0f-ebs",level:4},{value:"\u2705 efs",id:"-efs",level:4},{value:"\u2705 eks",id:"-eks",level:4},{value:"\u2705 elastic-inference",id:"-elastic-inference",level:4},{value:"\u2705 elastic-transcoder",id:"-elastic-transcoder",level:4},{value:"\u2705 elasticsearch-service",id:"-elasticsearch-service",level:4},{value:"\u2705 emr-containers",id:"-emr-containers",level:4},{value:"\u2705 emr-serverless",id:"-emr-serverless",level:4},{value:"\u2705 entityresolution",id:"-entityresolution",level:4},{value:"\u2705 evidently",id:"-evidently",level:4},{value:"\u2705 finspace-data",id:"-finspace-data",level:4},{value:"\u2705 finspace",id:"-finspace",level:4},{value:"\u2705 fis",id:"-fis",level:4},{value:"\u2705 gamesparks",id:"-gamesparks",level:4},{value:"\u26a0\ufe0f glacier",id:"\ufe0f-glacier",level:4},{value:"\u2705 grafana",id:"-grafana",level:4},{value:"\u2705 greengrass",id:"-greengrass",level:4},{value:"\u2705 greengrassv2",id:"-greengrassv2",level:4},{value:"\u2705 groundstation",id:"-groundstation",level:4},{value:"\u2705 guardduty",id:"-guardduty",level:4},{value:"\u2705 honeycode",id:"-honeycode",level:4},{value:"\u2705 imagebuilder",id:"-imagebuilder",level:4},{value:"\u2705 inspector2",id:"-inspector2",level:4},{value:"\u2705 internetmonitor",id:"-internetmonitor",level:4},{value:"\u2705 iot-1click-devices-service",id:"-iot-1click-devices-service",level:4},{value:"\u2705 iot-1click-projects",id:"-iot-1click-projects",level:4},{value:"\u2705 iot-data-plane",id:"-iot-data-plane",level:4},{value:"\u2705 iot-events-data",id:"-iot-events-data",level:4},{value:"\u2705 iot-events",id:"-iot-events",level:4},{value:"\u2705 iot-jobs-data-plane",id:"-iot-jobs-data-plane",level:4},{value:"\u2705 iot-roborunner",id:"-iot-roborunner",level:4},{value:"\u2705 iot-wireless",id:"-iot-wireless",level:4},{value:"\u2705 iot",id:"-iot",level:4},{value:"\u2705 iotanalytics",id:"-iotanalytics",level:4},{value:"\u2705 iotdeviceadvisor",id:"-iotdeviceadvisor",level:4},{value:"\u2705 iotfleethub",id:"-iotfleethub",level:4},{value:"\u2705 iotsitewise",id:"-iotsitewise",level:4},{value:"\u2705 iottwinmaker",id:"-iottwinmaker",level:4},{value:"\u2705 ivs-realtime",id:"-ivs-realtime",level:4},{value:"\u2705 ivs",id:"-ivs",level:4},{value:"\u2705 ivschat",id:"-ivschat",level:4},{value:"\u2705 kafka",id:"-kafka",level:4},{value:"\u2705 kafkaconnect",id:"-kafkaconnect",level:4},{value:"\u26a0\ufe0f kinesis-video-archived-media",id:"\ufe0f-kinesis-video-archived-media",level:4},{value:"\u26a0\ufe0f kinesis-video-media",id:"\ufe0f-kinesis-video-media",level:4},{value:"\u2705 kinesis-video-signaling",id:"-kinesis-video-signaling",level:4},{value:"\u2705 kinesis-video-webrtc-storage",id:"-kinesis-video-webrtc-storage",level:4},{value:"\u2705 kinesis-video",id:"-kinesis-video",level:4},{value:"\u26a0\ufe0f lakeformation",id:"\ufe0f-lakeformation",level:4},{value:"\u26a0\ufe0f lambda",id:"\ufe0f-lambda",level:4},{value:"\u2705 lex-model-building-service",id:"-lex-model-building-service",level:4},{value:"\u2705 lex-models-v2",id:"-lex-models-v2",level:4},{value:"\u26a0\ufe0f lex-runtime-service",id:"\ufe0f-lex-runtime-service",level:4},{value:"\u26a0\ufe0f lex-runtime-v2",id:"\ufe0f-lex-runtime-v2",level:4},{value:"\u2705 license-manager-linux-subscriptions",id:"-license-manager-linux-subscriptions",level:4},{value:"\u2705 license-manager-user-subscriptions",id:"-license-manager-user-subscriptions",level:4},{value:"\u2705 location",id:"-location",level:4},{value:"\u2705 lookoutmetrics",id:"-lookoutmetrics",level:4},{value:"\u26a0\ufe0f lookoutvision",id:"\ufe0f-lookoutvision",level:4},{value:"\u2705 m2",id:"-m2",level:4},{value:"\u2705 macie2",id:"-macie2",level:4},{value:"\u2705 managedblockchain-query",id:"-managedblockchain-query",level:4},{value:"\u2705 managedblockchain",id:"-managedblockchain",level:4},{value:"\u2705 marketplace-catalog",id:"-marketplace-catalog",level:4},{value:"\u2705 mediaconnect",id:"-mediaconnect",level:4},{value:"\u2705 mediaconvert",id:"-mediaconvert",level:4},{value:"\u26a0\ufe0f medialive",id:"\ufe0f-medialive",level:4},{value:"\u2705 mediapackage-vod",id:"-mediapackage-vod",level:4},{value:"\u2705 mediapackage",id:"-mediapackage",level:4},{value:"\u2705 mediapackagev2",id:"-mediapackagev2",level:4},{value:"\u26a0\ufe0f mediastore-data",id:"\ufe0f-mediastore-data",level:4},{value:"\u2705 mediatailor",id:"-mediatailor",level:4},{value:"\u26a0\ufe0f medical-imaging",id:"\ufe0f-medical-imaging",level:4},{value:"\u2705 mgn",id:"-mgn",level:4},{value:"\u2705 migration-hub-refactor-spaces",id:"-migration-hub-refactor-spaces",level:4},{value:"\u2705 migrationhuborchestrator",id:"-migrationhuborchestrator",level:4},{value:"\u2705 migrationhubstrategy",id:"-migrationhubstrategy",level:4},{value:"\u2705 mobile",id:"-mobile",level:4},{value:"\u2705 mq",id:"-mq",level:4},{value:"\u2705 mwaa",id:"-mwaa",level:4},{value:"\u2705 neptunedata",id:"-neptunedata",level:4},{value:"\u2705 networkmanager",id:"-networkmanager",level:4},{value:"\u2705 nimble",id:"-nimble",level:4},{value:"\u2705 oam",id:"-oam",level:4},{value:"\u26a0\ufe0f omics",id:"\ufe0f-omics",level:4},{value:"\u2705 opensearch",id:"-opensearch",level:4},{value:"\u2705 osis",id:"-osis",level:4},{value:"\u2705 outposts",id:"-outposts",level:4},{value:"\u2705 panorama",id:"-panorama",level:4},{value:"\u2705 payment-cryptography-data",id:"-payment-cryptography-data",level:4},{value:"\u2705 pca-connector-ad",id:"-pca-connector-ad",level:4},{value:"\u2705 personalize-events",id:"-personalize-events",level:4},{value:"\u2705 personalize-runtime",id:"-personalize-runtime",level:4},{value:"\u2705 pinpoint-email",id:"-pinpoint-email",level:4},{value:"\u2705 pinpoint-sms-voice",id:"-pinpoint-sms-voice",level:4},{value:"\u2705 pinpoint",id:"-pinpoint",level:4},{value:"\u2705 pipes",id:"-pipes",level:4},{value:"\u26a0\ufe0f polly",id:"\ufe0f-polly",level:4},{value:"\u2705 privatenetworks",id:"-privatenetworks",level:4},{value:"\u2705 qldb",id:"-qldb",level:4},{value:"\u2705 quicksight",id:"-quicksight",level:4},{value:"\u2705 ram",id:"-ram",level:4},{value:"\u2705 rbin",id:"-rbin",level:4},{value:"\u2705 rds-data",id:"-rds-data",level:4},{value:"\u26a0\ufe0f rekognitionstreaming",id:"\ufe0f-rekognitionstreaming",level:4},{value:"\u2705 resiliencehub",id:"-resiliencehub",level:4},{value:"\u2705 resource-explorer-2",id:"-resource-explorer-2",level:4},{value:"\u2705 resource-groups",id:"-resource-groups",level:4},{value:"\u2705 robomaker",id:"-robomaker",level:4},{value:"\u2705 rolesanywhere",id:"-rolesanywhere",level:4},{value:"\u2705 route53-recovery-control-config",id:"-route53-recovery-control-config",level:4},{value:"\u2705 route53-recovery-readiness",id:"-route53-recovery-readiness",level:4},{value:"\u2705 rum",id:"-rum",level:4},{value:"\u2705 s3outposts",id:"-s3outposts",level:4},{value:"\u2705 sagemaker-a2i-runtime",id:"-sagemaker-a2i-runtime",level:4},{value:"\u2705 sagemaker-edge",id:"-sagemaker-edge",level:4},{value:"\u2705 sagemaker-featurestore-runtime",id:"-sagemaker-featurestore-runtime",level:4},{value:"\u26a0\ufe0f sagemaker-geospatial",id:"\ufe0f-sagemaker-geospatial",level:4},{value:"\u2705 sagemaker-metrics",id:"-sagemaker-metrics",level:4},{value:"\u26a0\ufe0f sagemaker-runtime",id:"\ufe0f-sagemaker-runtime",level:4},{value:"\u2705 savingsplans",id:"-savingsplans",level:4},{value:"\u2705 scheduler",id:"-scheduler",level:4},{value:"\u2705 schemas",id:"-schemas",level:4},{value:"\u2705 securityhub",id:"-securityhub",level:4},{value:"\u2705 securitylake",id:"-securitylake",level:4},{value:"\u2705 serverlessapplicationrepository",id:"-serverlessapplicationrepository",level:4},{value:"\u2705 service-catalog-appregistry",id:"-service-catalog-appregistry",level:4},{value:"\u2705 sesv2",id:"-sesv2",level:4},{value:"\u2705 signer",id:"-signer",level:4},{value:"\u2705 simspaceweaver",id:"-simspaceweaver",level:4},{value:"\u2705 snow-device-management",id:"-snow-device-management",level:4},{value:"\u2705 ssm-incidents",id:"-ssm-incidents",level:4},{value:"\u2705 ssm-sap",id:"-ssm-sap",level:4},{value:"\u2705 sso-oidc",id:"-sso-oidc",level:4},{value:"\u2705 sso",id:"-sso",level:4},{value:"\u2705 support-app",id:"-support-app",level:4},{value:"\u2705 synthetics",id:"-synthetics",level:4},{value:"\u2705 tnb",id:"-tnb",level:4},{value:"\u26a0\ufe0f transcribe-streaming",id:"\ufe0f-transcribe-streaming",level:4},{value:"\u2705 vpc-lattice",id:"-vpc-lattice",level:4},{value:"\u2705 wellarchitected",id:"-wellarchitected",level:4},{value:"\u2705 wisdom",id:"-wisdom",level:4},{value:"\u2705 workdocs",id:"-workdocs",level:4},{value:"\u2705 worklink",id:"-worklink",level:4},{value:"\u26a0\ufe0f workmailmessageflow",id:"\ufe0f-workmailmessageflow",level:4},{value:"\u2705 workspaces-web",id:"-workspaces-web",level:4},{value:"\u2705 xray",id:"-xray",level:4},{value:"ec2Query",id:"ec2query",level:3},{value:"\u2705 ec2",id:"-ec2",level:4},{value:"awsQuery",id:"awsquery",level:3},{value:"\u2705 auto-scaling",id:"-auto-scaling",level:4},{value:"\u2705 cloudformation",id:"-cloudformation",level:4},{value:"\u2705 cloudsearch",id:"-cloudsearch",level:4},{value:"\u2705 cloudwatch",id:"-cloudwatch",level:4},{value:"\u2705 docdb",id:"-docdb",level:4},{value:"\u2705 elastic-beanstalk",id:"-elastic-beanstalk",level:4},{value:"\u2705 elastic-load-balancing-v2",id:"-elastic-load-balancing-v2",level:4},{value:"\u2705 elastic-load-balancing",id:"-elastic-load-balancing",level:4},{value:"\u2705 elasticache",id:"-elasticache",level:4},{value:"\u2705 iam",id:"-iam",level:4},{value:"\u2705 neptune",id:"-neptune",level:4},{value:"\u2705 rds",id:"-rds",level:4},{value:"\u2705 redshift",id:"-redshift",level:4},{value:"\u2705 ses",id:"-ses",level:4},{value:"\u2705 sns",id:"-sns",level:4},{value:"\u2705 sqs",id:"-sqs",level:4},{value:"\u2705 sts",id:"-sts",level:4},{value:"awsJson1_0",id:"awsjson1_0",level:3},{value:"\u2705 apprunner",id:"-apprunner",level:4},{value:"\u2705 backup-gateway",id:"-backup-gateway",level:4},{value:"\u2705 cloudcontrol",id:"-cloudcontrol",level:4},{value:"\u2705 codestar-connections",id:"-codestar-connections",level:4},{value:"\u2705 compute-optimizer",id:"-compute-optimizer",level:4},{value:"\u2705 dynamodb-streams",id:"-dynamodb-streams",level:4},{value:"\u2705 dynamodb",id:"-dynamodb",level:4},{value:"\u2705 healthlake",id:"-healthlake",level:4},{value:"\u2705 iotfleetwise",id:"-iotfleetwise",level:4},{value:"\u2705 kendra-ranking",id:"-kendra-ranking",level:4},{value:"\u2705 keyspaces",id:"-keyspaces",level:4},{value:"\u2705 lookoutequipment",id:"-lookoutequipment",level:4},{value:"\u2705 network-firewall",id:"-network-firewall",level:4},{value:"\u2705 opensearchserverless",id:"-opensearchserverless",level:4},{value:"\u2705 payment-cryptography",id:"-payment-cryptography",level:4},{value:"\u2705 pinpoint-sms-voice-v2",id:"-pinpoint-sms-voice-v2",level:4},{value:"\u2705 proton",id:"-proton",level:4},{value:"\u2705 qldb-session",id:"-qldb-session",level:4},{value:"\u2705 route53-recovery-cluster",id:"-route53-recovery-cluster",level:4},{value:"\u2705 sfn",id:"-sfn",level:4},{value:"\u2705 swf",id:"-swf",level:4},{value:"\u2705 timestream-query",id:"-timestream-query",level:4},{value:"\u2705 timestream-write",id:"-timestream-write",level:4},{value:"\u2705 verifiedpermissions",id:"-verifiedpermissions",level:4},{value:"\u2705 voice-id",id:"-voice-id",level:4},{value:"awsJson1_1",id:"awsjson1_1",level:3},{value:"\u2705 acm-pca",id:"-acm-pca",level:4},{value:"\u2705 acm",id:"-acm",level:4},{value:"\u2705 alexa-for-business",id:"-alexa-for-business",level:4},{value:"\u2705 application-auto-scaling",id:"-application-auto-scaling",level:4},{value:"\u2705 application-discovery-service",id:"-application-discovery-service",level:4},{value:"\u2705 application-insights",id:"-application-insights",level:4},{value:"\u2705 appstream",id:"-appstream",level:4},{value:"\u2705 athena",id:"-athena",level:4},{value:"\u2705 auto-scaling-plans",id:"-auto-scaling-plans",level:4},{value:"\u2705 budgets",id:"-budgets",level:4},{value:"\u2705 cloud9",id:"-cloud9",level:4},{value:"\u2705 cloudhsm-v2",id:"-cloudhsm-v2",level:4},{value:"\u2705 cloudhsm",id:"-cloudhsm",level:4},{value:"\u2705 cloudtrail",id:"-cloudtrail",level:4},{value:"\u2705 cloudwatch-events",id:"-cloudwatch-events",level:4},{value:"\u2705 cloudwatch-logs",id:"-cloudwatch-logs",level:4},{value:"\u2705 codebuild",id:"-codebuild",level:4},{value:"\u2705 codecommit",id:"-codecommit",level:4},{value:"\u2705 codedeploy",id:"-codedeploy",level:4},{value:"\u2705 codepipeline",id:"-codepipeline",level:4},{value:"\u2705 codestar",id:"-codestar",level:4},{value:"\u2705 cognito-identity-provider",id:"-cognito-identity-provider",level:4},{value:"\u2705 cognito-identity",id:"-cognito-identity",level:4},{value:"\u2705 comprehend",id:"-comprehend",level:4},{value:"\u2705 comprehendmedical",id:"-comprehendmedical",level:4},{value:"\u2705 config-service",id:"-config-service",level:4},{value:"\u2705 cost-and-usage-report-service",id:"-cost-and-usage-report-service",level:4},{value:"\u2705 cost-explorer",id:"-cost-explorer",level:4},{value:"\u2705 data-pipeline",id:"-data-pipeline",level:4},{value:"\u2705 database-migration-service",id:"-database-migration-service",level:4},{value:"\u2705 datasync",id:"-datasync",level:4},{value:"\u2705 dax",id:"-dax",level:4},{value:"\u2705 device-farm",id:"-device-farm",level:4},{value:"\u2705 direct-connect",id:"-direct-connect",level:4},{value:"\u2705 directory-service",id:"-directory-service",level:4},{value:"\u2705 ec2-instance-connect",id:"-ec2-instance-connect",level:4},{value:"\u2705 ecr-public",id:"-ecr-public",level:4},{value:"\u2705 ecr",id:"-ecr",level:4},{value:"\u2705 ecs",id:"-ecs",level:4},{value:"\u2705 emr",id:"-emr",level:4},{value:"\u2705 eventbridge",id:"-eventbridge",level:4},{value:"\u2705 firehose",id:"-firehose",level:4},{value:"\u2705 fms",id:"-fms",level:4},{value:"\u2705 forecast",id:"-forecast",level:4},{value:"\u2705 forecastquery",id:"-forecastquery",level:4},{value:"\u2705 frauddetector",id:"-frauddetector",level:4},{value:"\u2705 fsx",id:"-fsx",level:4},{value:"\u2705 gamelift",id:"-gamelift",level:4},{value:"\u2705 global-accelerator",id:"-global-accelerator",level:4},{value:"\u2705 glue",id:"-glue",level:4},{value:"\u2705 health",id:"-health",level:4},{value:"\u2705 identitystore",id:"-identitystore",level:4},{value:"\u2705 inspector",id:"-inspector",level:4},{value:"\u2705 iotsecuretunneling",id:"-iotsecuretunneling",level:4},{value:"\u2705 iotthingsgraph",id:"-iotthingsgraph",level:4},{value:"\u2705 kendra",id:"-kendra",level:4},{value:"\u2705 kinesis-analytics-v2",id:"-kinesis-analytics-v2",level:4},{value:"\u2705 kinesis-analytics",id:"-kinesis-analytics",level:4},{value:"\u26a0\ufe0f kinesis",id:"\ufe0f-kinesis",level:4},{value:"\u2705 kms",id:"-kms",level:4},{value:"\u2705 license-manager",id:"-license-manager",level:4},{value:"\u2705 lightsail",id:"-lightsail",level:4},{value:"\u2705 machine-learning",id:"-machine-learning",level:4},{value:"\u2705 macie",id:"-macie",level:4},{value:"\u2705 marketplace-commerce-analytics",id:"-marketplace-commerce-analytics",level:4},{value:"\u2705 marketplace-entitlement-service",id:"-marketplace-entitlement-service",level:4},{value:"\u2705 marketplace-metering",id:"-marketplace-metering",level:4},{value:"\u2705 mediastore",id:"-mediastore",level:4},{value:"\u2705 memorydb",id:"-memorydb",level:4},{value:"\u2705 migration-hub",id:"-migration-hub",level:4},{value:"\u2705 migrationhub-config",id:"-migrationhub-config",level:4},{value:"\u2705 mturk",id:"-mturk",level:4},{value:"\u2705 opsworks",id:"-opsworks",level:4},{value:"\u2705 opsworkscm",id:"-opsworkscm",level:4},{value:"\u2705 organizations",id:"-organizations",level:4},{value:"\u2705 personalize",id:"-personalize",level:4},{value:"\u2705 pi",id:"-pi",level:4},{value:"\u2705 pricing",id:"-pricing",level:4},{value:"\u2705 redshift-data",id:"-redshift-data",level:4},{value:"\u2705 redshift-serverless",id:"-redshift-serverless",level:4},{value:"\u2705 rekognition",id:"-rekognition",level:4},{value:"\u2705 resource-groups-tagging-api",id:"-resource-groups-tagging-api",level:4},{value:"\u2705 route-53-domains",id:"-route-53-domains",level:4},{value:"\u2705 route53resolver",id:"-route53resolver",level:4},{value:"\u2705 sagemaker",id:"-sagemaker",level:4},{value:"\u2705 secrets-manager",id:"-secrets-manager",level:4},{value:"\u2705 service-catalog",id:"-service-catalog",level:4},{value:"\u2705 service-quotas",id:"-service-quotas",level:4},{value:"\u2705 servicediscovery",id:"-servicediscovery",level:4},{value:"\u2705 shield",id:"-shield",level:4},{value:"\u2705 sms",id:"-sms",level:4},{value:"\u2705 snowball",id:"-snowball",level:4},{value:"\u2705 ssm-contacts",id:"-ssm-contacts",level:4},{value:"\u2705 ssm",id:"-ssm",level:4},{value:"\u2705 sso-admin",id:"-sso-admin",level:4},{value:"\u2705 storage-gateway",id:"-storage-gateway",level:4},{value:"\u2705 support",id:"-support",level:4},{value:"\u2705 textract",id:"-textract",level:4},{value:"\u2705 transcribe",id:"-transcribe",level:4},{value:"\u2705 transfer",id:"-transfer",level:4},{value:"\u2705 translate",id:"-translate",level:4},{value:"\u2705 waf-regional",id:"-waf-regional",level:4},{value:"\u2705 waf",id:"-waf",level:4},{value:"\u2705 wafv2",id:"-wafv2",level:4},{value:"\u2705 workmail",id:"-workmail",level:4},{value:"\u2705 workspaces",id:"-workspaces",level:4},{value:"restXml",id:"restxml",level:3},{value:"\u2705 cloudfront",id:"-cloudfront",level:4},{value:"\u2705 route-53",id:"-route-53",level:4},{value:"\u2705 s3-control",id:"-s3-control",level:4},{value:"\u26a0\ufe0f s3",id:"\ufe0f-s3",level:4}],o={toc:c},u="wrapper";function p(e){let{components:i,...t}=e;return(0,a.kt)(u,(0,s.Z)({},o,t,{components:i,mdxType:"MDXLayout"}),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"WARNING: READ THE FOLLOWING, AND USE WITH CAUTION")),(0,a.kt)("p",null,"Smithy4s provides functions to create AWS clients from generated code. As of 0.18, Smithy4s supports (at least partially) all AWS protocols that are publicly documented."),(0,a.kt)("p",null,"Our implementation of the AWS protocols is tested against the official ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/smithy-lang/smithy/tree/main/smithy-aws-protocol-tests/model"},"compliance-tests"),", which gives us a reasonable level of confidence that most of the (de)serialisation logic involved when communicating with AWS is correct. Our implementation of the AWS signature algorithm (which is required for AWS to authenticate requests) is tested against the Java implementation used by the official AWS SDK."),(0,a.kt)("h3",{id:"what-is-missing-"},"What is missing ?"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"streaming operations (such as S3 ",(0,a.kt)("inlineCode",{parentName:"li"},"putObject"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"getObject"),", or Kinesis' ",(0,a.kt)("inlineCode",{parentName:"li"},"subscribeToShard"),") are currently unsupported."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://smithy.io/2.0/aws/customizations/index.html"},"service-specific customisations")," are currently unsupported."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"users should not use smithy4s to get data into/out of AWS S3"))),(0,a.kt)("h3",{id:"note-on-pre-built-artifacts"},"Note on pre-built artifacts"),(0,a.kt)("p",null,"We (the Smithy4s maintainers) ",(0,a.kt)("strong",{parentName:"p"},"do not")," intend to publish pre-generated artifacts containing the AWS clients, there's a lot of nuance there and maintainance burden that we do not have the capacity to assume. In particular, backward binary compatibility of the generated code is impossible to guarantee at this time."),(0,a.kt)("h2",{id:"setup"},"Setup"),(0,a.kt)("h3",{id:"sbt"},"SBT"),(0,a.kt)("p",null,"In ",(0,a.kt)("inlineCode",{parentName:"p"},"build.sbt")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-scala"},'libraryDependencies ++= Seq(\n "com.disneystreaming.smithy4s" %% "smithy4s-aws-http4s" % smithy4sVersion.value\n)\n// The `AWS` object contains a list of references to artifacts that contain specifications to AWS services.\nsmithy4sAwsSpecs ++= Seq(AWS.dynamodb)\n')),(0,a.kt)("p",null,"Alternatively, the following is also valid :"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-scala"},'libraryDependencies ++= Seq(\n // version sourced from the plugin\n "com.disneystreaming.smithy4s" %% "smithy4s-aws-http4s" % smithy4sVersion.value\n "com.disneystreaming.smithy" % "aws-dynamodb-spec" % "2023.09.22" % Smithy4s\n)\n')),(0,a.kt)("h3",{id:"mill"},"Mill"),(0,a.kt)("p",null,"In ",(0,a.kt)("inlineCode",{parentName:"p"},"build.sc")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-scala"},'import $ivy.`com.disneystreaming.smithy4s::smithy4s-mill-codegen-plugin::0.18.10`\nimport smithy4s.codegen.mill._\n\nobject foo extends Smithy4sModule {\n override def scalaVersion = "2.13.10"\n override def ivyDeps = Agg(\n ivy"com.disneystreaming.smithy4s::smithy4s-aws-http4s:${smithy4sVersion()}",\n )\n override def smithy4sAwsSpecs: T[Seq[String]] = T(Seq(AWS.dynamodb))\n}\n')),(0,a.kt)("h2",{id:"example-usage"},"Example usage"),(0,a.kt)("p",null,"In your Scala code:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-scala"},"import cats.effect._\nimport org.http4s.ember.client.EmberClientBuilder\n\nimport smithy4s.aws._ // AWS specific interpreters // AWS specific interpreters\nimport com.amazonaws.dynamodb._ // Generated code from specs. // Generated code from specs.\n\nobject Main extends IOApp.Simple {\n\n def run = resource.use { case (dynamodb) =>\n dynamodb\n .listTables(limit = Some(ListTablesInputLimit(10)))\n .flatMap(IO.println(_))\n }\n\n val resource: Resource[IO, DynamoDB[IO]] =\n for {\n httpClient <- EmberClientBuilder.default[IO].build\n awsEnv <- AwsEnvironment.default(httpClient, AwsRegion.US_EAST_1)\n dynamodb <- AwsClient(DynamoDB, awsEnv)\n } yield dynamodb\n\n}\n")),(0,a.kt)("h2",{id:"note-on-where-to-find-the-aws-specifications"},"Note on where to find the AWS specifications"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"SBT : ",(0,a.kt)("inlineCode",{parentName:"li"},'"com.disneystreaming.smithy" % s"aws-${service_name}-spec" % "2023.09.22"')),(0,a.kt)("li",{parentName:"ul"},"Mill : ",(0,a.kt)("inlineCode",{parentName:"li"},'ivy"com.disneystreaming.smithy:aws-${service_name}-spec:2023.09.22"'))),(0,a.kt)("p",null,"The version corresponds to the latest release in this repo: ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/disneystreaming/aws-sdk-smithy-specs"},"aws-sdk-smithy-specs"),"."),(0,a.kt)("p",null,"AWS does not publishes the specs to their services to Maven. However, The specs in question (that are written in json syntax) can be found in some of the ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/aws/aws-sdk-js-v3/tree/main/codegen/sdk-codegen/aws-models"},"official SDKs")," published by AWS. These ",(0,a.kt)("inlineCode",{parentName:"p"},".json files")," can be understood by smithy4s, just like ",(0,a.kt)("inlineCode",{parentName:"p"},".smithy"),", and can be used to generate code."),(0,a.kt)("p",null,"The ",(0,a.kt)("strong",{parentName:"p"},"aws-sdk-smithy-specs")," project periodically gathers the specs from the Javascript SDK repo and publishes them to maven central to lower the barrier of entry."),(0,a.kt)("h2",{id:"service-summary"},"Service summary"),(0,a.kt)("p",null,"Below you'll find a generated summary of the maven coordinates for the AWS specifications. Note\nthat the version of the spec might not be the latest one. Refer yourself to ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/disneystreaming/aws-sdk-smithy-specs"},"this repo")," to get the latest version of the specs."),(0,a.kt)("h3",{id:"-supported-at-least-partially"},"\u2705 Supported (at least partially)"),(0,a.kt)("h3",{id:"restjson1"},"restJson1"),(0,a.kt)("h4",{id:"-accessanalyzer"},"\u2705 accessanalyzer"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-accessanalyzer-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-accessanalyzer-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-account"},"\u2705 account"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-account-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-account-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-amp"},"\u2705 amp"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-amp-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-amp-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-amplify"},"\u2705 amplify"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-amplify-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-amplify-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-amplifybackend"},"\u2705 amplifybackend"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-amplifybackend-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-amplifybackend-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-amplifyuibuilder"},"\u2705 amplifyuibuilder"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-amplifyuibuilder-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-amplifyuibuilder-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-api-gateway"},"\u2705 api-gateway"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-api-gateway-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-api-gateway-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-apigatewaymanagementapi"},"\u2705 apigatewaymanagementapi"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-apigatewaymanagementapi-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-apigatewaymanagementapi-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-apigatewayv2"},"\u2705 apigatewayv2"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-apigatewayv2-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-apigatewayv2-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-app-mesh"},"\u2705 app-mesh"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-app-mesh-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-app-mesh-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-appconfig"},"\u2705 appconfig"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-appconfig-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-appconfig-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-appconfigdata"},"\u2705 appconfigdata"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-appconfigdata-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-appconfigdata-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-appfabric"},"\u2705 appfabric"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-appfabric-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-appfabric-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-appflow"},"\u2705 appflow"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-appflow-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-appflow-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-appintegrations"},"\u2705 appintegrations"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-appintegrations-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-appintegrations-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-applicationcostprofiler"},"\u2705 applicationcostprofiler"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-applicationcostprofiler-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-applicationcostprofiler-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-appsync"},"\u2705 appsync"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-appsync-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-appsync-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-arc-zonal-shift"},"\u2705 arc-zonal-shift"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-arc-zonal-shift-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-arc-zonal-shift-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-auditmanager"},"\u2705 auditmanager"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-auditmanager-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-auditmanager-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-backup"},"\u2705 backup"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-backup-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-backup-spec:2023.09.22"')),(0,a.kt)("h4",{id:"\ufe0f-backupstorage"},"\u26a0\ufe0f backupstorage"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-backupstorage-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-backupstorage-spec:2023.09.22"')),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Unsupported streaming operations")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"NotifyObjectComplete"),(0,a.kt)("li",{parentName:"ul"},"PutChunk"),(0,a.kt)("li",{parentName:"ul"},"PutObject"),(0,a.kt)("li",{parentName:"ul"},"GetChunk"),(0,a.kt)("li",{parentName:"ul"},"GetObjectMetadata")),(0,a.kt)("h4",{id:"-batch"},"\u2705 batch"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-batch-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-batch-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-billingconductor"},"\u2705 billingconductor"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-billingconductor-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-billingconductor-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-braket"},"\u2705 braket"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-braket-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-braket-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-chime-sdk-identity"},"\u2705 chime-sdk-identity"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-chime-sdk-identity-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-chime-sdk-identity-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-chime-sdk-media-pipelines"},"\u2705 chime-sdk-media-pipelines"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-chime-sdk-media-pipelines-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-chime-sdk-media-pipelines-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-chime-sdk-meetings"},"\u2705 chime-sdk-meetings"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-chime-sdk-meetings-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-chime-sdk-meetings-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-chime-sdk-messaging"},"\u2705 chime-sdk-messaging"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-chime-sdk-messaging-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-chime-sdk-messaging-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-chime-sdk-voice"},"\u2705 chime-sdk-voice"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-chime-sdk-voice-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-chime-sdk-voice-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-chime"},"\u2705 chime"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-chime-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-chime-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-cleanrooms"},"\u2705 cleanrooms"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-cleanrooms-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-cleanrooms-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-clouddirectory"},"\u2705 clouddirectory"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-clouddirectory-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-clouddirectory-spec:2023.09.22"')),(0,a.kt)("h4",{id:"\ufe0f-cloudsearch-domain"},"\u26a0\ufe0f cloudsearch-domain"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-cloudsearch-domain-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-cloudsearch-domain-spec:2023.09.22"')),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Unsupported streaming operations")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"UploadDocuments")),(0,a.kt)("h4",{id:"-cloudtrail-data"},"\u2705 cloudtrail-data"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-cloudtrail-data-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-cloudtrail-data-spec:2023.09.22"')),(0,a.kt)("h4",{id:"\ufe0f-codeartifact"},"\u26a0\ufe0f codeartifact"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-codeartifact-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-codeartifact-spec:2023.09.22"')),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Unsupported streaming operations")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"GetPackageVersionAsset"),(0,a.kt)("li",{parentName:"ul"},"PublishPackageVersion")),(0,a.kt)("h4",{id:"-codecatalyst"},"\u2705 codecatalyst"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-codecatalyst-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-codecatalyst-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-codeguru-reviewer"},"\u2705 codeguru-reviewer"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-codeguru-reviewer-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-codeguru-reviewer-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-codeguru-security"},"\u2705 codeguru-security"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-codeguru-security-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-codeguru-security-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-codeguruprofiler"},"\u2705 codeguruprofiler"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-codeguruprofiler-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-codeguruprofiler-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-codestar-notifications"},"\u2705 codestar-notifications"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-codestar-notifications-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-codestar-notifications-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-cognito-sync"},"\u2705 cognito-sync"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-cognito-sync-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-cognito-sync-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-connect-contact-lens"},"\u2705 connect-contact-lens"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-connect-contact-lens-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-connect-contact-lens-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-connect"},"\u2705 connect"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-connect-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-connect-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-connectcampaigns"},"\u2705 connectcampaigns"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-connectcampaigns-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-connectcampaigns-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-connectcases"},"\u2705 connectcases"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-connectcases-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-connectcases-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-connectparticipant"},"\u2705 connectparticipant"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-connectparticipant-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-connectparticipant-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-controltower"},"\u2705 controltower"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-controltower-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-controltower-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-customer-profiles"},"\u2705 customer-profiles"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-customer-profiles-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-customer-profiles-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-databrew"},"\u2705 databrew"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-databrew-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-databrew-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-dataexchange"},"\u2705 dataexchange"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-dataexchange-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-dataexchange-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-detective"},"\u2705 detective"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-detective-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-detective-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-devops-guru"},"\u2705 devops-guru"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-devops-guru-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-devops-guru-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-dlm"},"\u2705 dlm"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-dlm-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-dlm-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-docdb-elastic"},"\u2705 docdb-elastic"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-docdb-elastic-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-docdb-elastic-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-drs"},"\u2705 drs"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-drs-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-drs-spec:2023.09.22"')),(0,a.kt)("h4",{id:"\ufe0f-ebs"},"\u26a0\ufe0f ebs"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-ebs-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-ebs-spec:2023.09.22"')),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Unsupported streaming operations")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"PutSnapshotBlock"),(0,a.kt)("li",{parentName:"ul"},"GetSnapshotBlock")),(0,a.kt)("h4",{id:"-efs"},"\u2705 efs"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-efs-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-efs-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-eks"},"\u2705 eks"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-eks-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-eks-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-elastic-inference"},"\u2705 elastic-inference"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-elastic-inference-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-elastic-inference-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-elastic-transcoder"},"\u2705 elastic-transcoder"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-elastic-transcoder-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-elastic-transcoder-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-elasticsearch-service"},"\u2705 elasticsearch-service"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-elasticsearch-service-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-elasticsearch-service-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-emr-containers"},"\u2705 emr-containers"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-emr-containers-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-emr-containers-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-emr-serverless"},"\u2705 emr-serverless"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-emr-serverless-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-emr-serverless-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-entityresolution"},"\u2705 entityresolution"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-entityresolution-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-entityresolution-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-evidently"},"\u2705 evidently"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-evidently-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-evidently-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-finspace-data"},"\u2705 finspace-data"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-finspace-data-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-finspace-data-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-finspace"},"\u2705 finspace"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-finspace-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-finspace-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-fis"},"\u2705 fis"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-fis-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-fis-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-gamesparks"},"\u2705 gamesparks"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-gamesparks-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-gamesparks-spec:2023.09.22"')),(0,a.kt)("h4",{id:"\ufe0f-glacier"},"\u26a0\ufe0f glacier"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-glacier-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-glacier-spec:2023.09.22"')),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Unsupported streaming operations")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"GetJobOutput"),(0,a.kt)("li",{parentName:"ul"},"UploadArchive"),(0,a.kt)("li",{parentName:"ul"},"UploadMultipartPart")),(0,a.kt)("h4",{id:"-grafana"},"\u2705 grafana"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-grafana-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-grafana-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-greengrass"},"\u2705 greengrass"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-greengrass-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-greengrass-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-greengrassv2"},"\u2705 greengrassv2"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-greengrassv2-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-greengrassv2-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-groundstation"},"\u2705 groundstation"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-groundstation-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-groundstation-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-guardduty"},"\u2705 guardduty"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-guardduty-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-guardduty-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-honeycode"},"\u2705 honeycode"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-honeycode-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-honeycode-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-imagebuilder"},"\u2705 imagebuilder"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-imagebuilder-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-imagebuilder-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-inspector2"},"\u2705 inspector2"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-inspector2-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-inspector2-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-internetmonitor"},"\u2705 internetmonitor"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-internetmonitor-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-internetmonitor-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-iot-1click-devices-service"},"\u2705 iot-1click-devices-service"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-iot-1click-devices-service-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-iot-1click-devices-service-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-iot-1click-projects"},"\u2705 iot-1click-projects"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-iot-1click-projects-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-iot-1click-projects-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-iot-data-plane"},"\u2705 iot-data-plane"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-iot-data-plane-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-iot-data-plane-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-iot-events-data"},"\u2705 iot-events-data"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-iot-events-data-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-iot-events-data-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-iot-events"},"\u2705 iot-events"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-iot-events-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-iot-events-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-iot-jobs-data-plane"},"\u2705 iot-jobs-data-plane"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-iot-jobs-data-plane-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-iot-jobs-data-plane-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-iot-roborunner"},"\u2705 iot-roborunner"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-iot-roborunner-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-iot-roborunner-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-iot-wireless"},"\u2705 iot-wireless"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-iot-wireless-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-iot-wireless-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-iot"},"\u2705 iot"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-iot-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-iot-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-iotanalytics"},"\u2705 iotanalytics"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-iotanalytics-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-iotanalytics-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-iotdeviceadvisor"},"\u2705 iotdeviceadvisor"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-iotdeviceadvisor-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-iotdeviceadvisor-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-iotfleethub"},"\u2705 iotfleethub"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-iotfleethub-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-iotfleethub-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-iotsitewise"},"\u2705 iotsitewise"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-iotsitewise-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-iotsitewise-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-iottwinmaker"},"\u2705 iottwinmaker"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-iottwinmaker-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-iottwinmaker-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-ivs-realtime"},"\u2705 ivs-realtime"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-ivs-realtime-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-ivs-realtime-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-ivs"},"\u2705 ivs"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-ivs-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-ivs-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-ivschat"},"\u2705 ivschat"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-ivschat-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-ivschat-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-kafka"},"\u2705 kafka"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-kafka-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-kafka-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-kafkaconnect"},"\u2705 kafkaconnect"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-kafkaconnect-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-kafkaconnect-spec:2023.09.22"')),(0,a.kt)("h4",{id:"\ufe0f-kinesis-video-archived-media"},"\u26a0\ufe0f kinesis-video-archived-media"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-kinesis-video-archived-media-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-kinesis-video-archived-media-spec:2023.09.22"')),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Unsupported streaming operations")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"GetClip"),(0,a.kt)("li",{parentName:"ul"},"GetMediaForFragmentList")),(0,a.kt)("h4",{id:"\ufe0f-kinesis-video-media"},"\u26a0\ufe0f kinesis-video-media"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-kinesis-video-media-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-kinesis-video-media-spec:2023.09.22"')),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Unsupported streaming operations")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"GetMedia")),(0,a.kt)("h4",{id:"-kinesis-video-signaling"},"\u2705 kinesis-video-signaling"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-kinesis-video-signaling-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-kinesis-video-signaling-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-kinesis-video-webrtc-storage"},"\u2705 kinesis-video-webrtc-storage"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-kinesis-video-webrtc-storage-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-kinesis-video-webrtc-storage-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-kinesis-video"},"\u2705 kinesis-video"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-kinesis-video-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-kinesis-video-spec:2023.09.22"')),(0,a.kt)("h4",{id:"\ufe0f-lakeformation"},"\u26a0\ufe0f lakeformation"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-lakeformation-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-lakeformation-spec:2023.09.22"')),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Unsupported streaming operations")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"GetWorkUnitResults")),(0,a.kt)("h4",{id:"\ufe0f-lambda"},"\u26a0\ufe0f lambda"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-lambda-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-lambda-spec:2023.09.22"')),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Unsupported streaming operations")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"InvokeWithResponseStream"),(0,a.kt)("li",{parentName:"ul"},"InvokeAsync")),(0,a.kt)("h4",{id:"-lex-model-building-service"},"\u2705 lex-model-building-service"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-lex-model-building-service-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-lex-model-building-service-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-lex-models-v2"},"\u2705 lex-models-v2"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-lex-models-v2-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-lex-models-v2-spec:2023.09.22"')),(0,a.kt)("h4",{id:"\ufe0f-lex-runtime-service"},"\u26a0\ufe0f lex-runtime-service"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-lex-runtime-service-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-lex-runtime-service-spec:2023.09.22"')),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Unsupported streaming operations")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"PostContent"),(0,a.kt)("li",{parentName:"ul"},"PutSession")),(0,a.kt)("h4",{id:"\ufe0f-lex-runtime-v2"},"\u26a0\ufe0f lex-runtime-v2"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-lex-runtime-v2-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-lex-runtime-v2-spec:2023.09.22"')),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Unsupported streaming operations")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"RecognizeUtterance"),(0,a.kt)("li",{parentName:"ul"},"PutSession"),(0,a.kt)("li",{parentName:"ul"},"StartConversation")),(0,a.kt)("h4",{id:"-license-manager-linux-subscriptions"},"\u2705 license-manager-linux-subscriptions"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-license-manager-linux-subscriptions-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-license-manager-linux-subscriptions-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-license-manager-user-subscriptions"},"\u2705 license-manager-user-subscriptions"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-license-manager-user-subscriptions-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-license-manager-user-subscriptions-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-location"},"\u2705 location"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-location-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-location-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-lookoutmetrics"},"\u2705 lookoutmetrics"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-lookoutmetrics-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-lookoutmetrics-spec:2023.09.22"')),(0,a.kt)("h4",{id:"\ufe0f-lookoutvision"},"\u26a0\ufe0f lookoutvision"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-lookoutvision-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-lookoutvision-spec:2023.09.22"')),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Unsupported streaming operations")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"DetectAnomalies")),(0,a.kt)("h4",{id:"-m2"},"\u2705 m2"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-m2-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-m2-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-macie2"},"\u2705 macie2"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-macie2-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-macie2-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-managedblockchain-query"},"\u2705 managedblockchain-query"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-managedblockchain-query-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-managedblockchain-query-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-managedblockchain"},"\u2705 managedblockchain"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-managedblockchain-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-managedblockchain-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-marketplace-catalog"},"\u2705 marketplace-catalog"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-marketplace-catalog-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-marketplace-catalog-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-mediaconnect"},"\u2705 mediaconnect"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-mediaconnect-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-mediaconnect-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-mediaconvert"},"\u2705 mediaconvert"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-mediaconvert-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-mediaconvert-spec:2023.09.22"')),(0,a.kt)("h4",{id:"\ufe0f-medialive"},"\u26a0\ufe0f medialive"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-medialive-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-medialive-spec:2023.09.22"')),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Unsupported streaming operations")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"DescribeInputDeviceThumbnail")),(0,a.kt)("h4",{id:"-mediapackage-vod"},"\u2705 mediapackage-vod"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-mediapackage-vod-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-mediapackage-vod-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-mediapackage"},"\u2705 mediapackage"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-mediapackage-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-mediapackage-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-mediapackagev2"},"\u2705 mediapackagev2"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-mediapackagev2-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-mediapackagev2-spec:2023.09.22"')),(0,a.kt)("h4",{id:"\ufe0f-mediastore-data"},"\u26a0\ufe0f mediastore-data"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-mediastore-data-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-mediastore-data-spec:2023.09.22"')),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Unsupported streaming operations")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"PutObject"),(0,a.kt)("li",{parentName:"ul"},"GetObject")),(0,a.kt)("h4",{id:"-mediatailor"},"\u2705 mediatailor"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-mediatailor-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-mediatailor-spec:2023.09.22"')),(0,a.kt)("h4",{id:"\ufe0f-medical-imaging"},"\u26a0\ufe0f medical-imaging"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-medical-imaging-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-medical-imaging-spec:2023.09.22"')),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Unsupported streaming operations")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"GetImageSetMetadata"),(0,a.kt)("li",{parentName:"ul"},"GetImageFrame")),(0,a.kt)("h4",{id:"-mgn"},"\u2705 mgn"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-mgn-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-mgn-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-migration-hub-refactor-spaces"},"\u2705 migration-hub-refactor-spaces"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-migration-hub-refactor-spaces-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-migration-hub-refactor-spaces-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-migrationhuborchestrator"},"\u2705 migrationhuborchestrator"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-migrationhuborchestrator-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-migrationhuborchestrator-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-migrationhubstrategy"},"\u2705 migrationhubstrategy"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-migrationhubstrategy-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-migrationhubstrategy-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-mobile"},"\u2705 mobile"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-mobile-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-mobile-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-mq"},"\u2705 mq"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-mq-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-mq-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-mwaa"},"\u2705 mwaa"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-mwaa-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-mwaa-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-neptunedata"},"\u2705 neptunedata"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-neptunedata-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-neptunedata-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-networkmanager"},"\u2705 networkmanager"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-networkmanager-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-networkmanager-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-nimble"},"\u2705 nimble"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-nimble-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-nimble-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-oam"},"\u2705 oam"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-oam-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-oam-spec:2023.09.22"')),(0,a.kt)("h4",{id:"\ufe0f-omics"},"\u26a0\ufe0f omics"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-omics-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-omics-spec:2023.09.22"')),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Unsupported streaming operations")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"GetReference"),(0,a.kt)("li",{parentName:"ul"},"GetReadSet"),(0,a.kt)("li",{parentName:"ul"},"UploadReadSetPart")),(0,a.kt)("h4",{id:"-opensearch"},"\u2705 opensearch"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-opensearch-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-opensearch-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-osis"},"\u2705 osis"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-osis-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-osis-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-outposts"},"\u2705 outposts"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-outposts-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-outposts-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-panorama"},"\u2705 panorama"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-panorama-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-panorama-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-payment-cryptography-data"},"\u2705 payment-cryptography-data"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-payment-cryptography-data-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-payment-cryptography-data-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-pca-connector-ad"},"\u2705 pca-connector-ad"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-pca-connector-ad-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-pca-connector-ad-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-personalize-events"},"\u2705 personalize-events"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-personalize-events-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-personalize-events-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-personalize-runtime"},"\u2705 personalize-runtime"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-personalize-runtime-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-personalize-runtime-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-pinpoint-email"},"\u2705 pinpoint-email"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-pinpoint-email-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-pinpoint-email-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-pinpoint-sms-voice"},"\u2705 pinpoint-sms-voice"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-pinpoint-sms-voice-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-pinpoint-sms-voice-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-pinpoint"},"\u2705 pinpoint"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-pinpoint-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-pinpoint-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-pipes"},"\u2705 pipes"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-pipes-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-pipes-spec:2023.09.22"')),(0,a.kt)("h4",{id:"\ufe0f-polly"},"\u26a0\ufe0f polly"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-polly-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-polly-spec:2023.09.22"')),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Unsupported streaming operations")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"SynthesizeSpeech")),(0,a.kt)("h4",{id:"-privatenetworks"},"\u2705 privatenetworks"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-privatenetworks-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-privatenetworks-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-qldb"},"\u2705 qldb"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-qldb-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-qldb-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-quicksight"},"\u2705 quicksight"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-quicksight-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-quicksight-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-ram"},"\u2705 ram"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-ram-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-ram-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-rbin"},"\u2705 rbin"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-rbin-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-rbin-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-rds-data"},"\u2705 rds-data"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-rds-data-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-rds-data-spec:2023.09.22"')),(0,a.kt)("h4",{id:"\ufe0f-rekognitionstreaming"},"\u26a0\ufe0f rekognitionstreaming"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-rekognitionstreaming-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-rekognitionstreaming-spec:2023.09.22"')),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Unsupported streaming operations")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"StartFaceLivenessSession")),(0,a.kt)("h4",{id:"-resiliencehub"},"\u2705 resiliencehub"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-resiliencehub-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-resiliencehub-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-resource-explorer-2"},"\u2705 resource-explorer-2"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-resource-explorer-2-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-resource-explorer-2-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-resource-groups"},"\u2705 resource-groups"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-resource-groups-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-resource-groups-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-robomaker"},"\u2705 robomaker"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-robomaker-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-robomaker-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-rolesanywhere"},"\u2705 rolesanywhere"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-rolesanywhere-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-rolesanywhere-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-route53-recovery-control-config"},"\u2705 route53-recovery-control-config"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-route53-recovery-control-config-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-route53-recovery-control-config-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-route53-recovery-readiness"},"\u2705 route53-recovery-readiness"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-route53-recovery-readiness-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-route53-recovery-readiness-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-rum"},"\u2705 rum"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-rum-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-rum-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-s3outposts"},"\u2705 s3outposts"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-s3outposts-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-s3outposts-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-sagemaker-a2i-runtime"},"\u2705 sagemaker-a2i-runtime"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-sagemaker-a2i-runtime-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-sagemaker-a2i-runtime-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-sagemaker-edge"},"\u2705 sagemaker-edge"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-sagemaker-edge-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-sagemaker-edge-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-sagemaker-featurestore-runtime"},"\u2705 sagemaker-featurestore-runtime"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-sagemaker-featurestore-runtime-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-sagemaker-featurestore-runtime-spec:2023.09.22"')),(0,a.kt)("h4",{id:"\ufe0f-sagemaker-geospatial"},"\u26a0\ufe0f sagemaker-geospatial"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-sagemaker-geospatial-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-sagemaker-geospatial-spec:2023.09.22"')),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Unsupported streaming operations")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"GetTile")),(0,a.kt)("h4",{id:"-sagemaker-metrics"},"\u2705 sagemaker-metrics"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-sagemaker-metrics-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-sagemaker-metrics-spec:2023.09.22"')),(0,a.kt)("h4",{id:"\ufe0f-sagemaker-runtime"},"\u26a0\ufe0f sagemaker-runtime"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-sagemaker-runtime-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-sagemaker-runtime-spec:2023.09.22"')),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Unsupported streaming operations")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"InvokeEndpointWithResponseStream")),(0,a.kt)("h4",{id:"-savingsplans"},"\u2705 savingsplans"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-savingsplans-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-savingsplans-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-scheduler"},"\u2705 scheduler"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-scheduler-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-scheduler-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-schemas"},"\u2705 schemas"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-schemas-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-schemas-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-securityhub"},"\u2705 securityhub"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-securityhub-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-securityhub-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-securitylake"},"\u2705 securitylake"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-securitylake-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-securitylake-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-serverlessapplicationrepository"},"\u2705 serverlessapplicationrepository"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-serverlessapplicationrepository-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-serverlessapplicationrepository-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-service-catalog-appregistry"},"\u2705 service-catalog-appregistry"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-service-catalog-appregistry-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-service-catalog-appregistry-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-sesv2"},"\u2705 sesv2"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-sesv2-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-sesv2-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-signer"},"\u2705 signer"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-signer-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-signer-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-simspaceweaver"},"\u2705 simspaceweaver"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-simspaceweaver-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-simspaceweaver-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-snow-device-management"},"\u2705 snow-device-management"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-snow-device-management-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-snow-device-management-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-ssm-incidents"},"\u2705 ssm-incidents"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-ssm-incidents-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-ssm-incidents-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-ssm-sap"},"\u2705 ssm-sap"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-ssm-sap-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-ssm-sap-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-sso-oidc"},"\u2705 sso-oidc"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-sso-oidc-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-sso-oidc-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-sso"},"\u2705 sso"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-sso-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-sso-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-support-app"},"\u2705 support-app"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-support-app-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-support-app-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-synthetics"},"\u2705 synthetics"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-synthetics-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-synthetics-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-tnb"},"\u2705 tnb"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-tnb-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-tnb-spec:2023.09.22"')),(0,a.kt)("h4",{id:"\ufe0f-transcribe-streaming"},"\u26a0\ufe0f transcribe-streaming"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-transcribe-streaming-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-transcribe-streaming-spec:2023.09.22"')),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Unsupported streaming operations")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"StartMedicalStreamTranscription"),(0,a.kt)("li",{parentName:"ul"},"StartCallAnalyticsStreamTranscription"),(0,a.kt)("li",{parentName:"ul"},"StartStreamTranscription")),(0,a.kt)("h4",{id:"-vpc-lattice"},"\u2705 vpc-lattice"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-vpc-lattice-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-vpc-lattice-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-wellarchitected"},"\u2705 wellarchitected"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-wellarchitected-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-wellarchitected-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-wisdom"},"\u2705 wisdom"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-wisdom-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-wisdom-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-workdocs"},"\u2705 workdocs"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-workdocs-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-workdocs-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-worklink"},"\u2705 worklink"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-worklink-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-worklink-spec:2023.09.22"')),(0,a.kt)("h4",{id:"\ufe0f-workmailmessageflow"},"\u26a0\ufe0f workmailmessageflow"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-workmailmessageflow-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-workmailmessageflow-spec:2023.09.22"')),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Unsupported streaming operations")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"GetRawMessageContent")),(0,a.kt)("h4",{id:"-workspaces-web"},"\u2705 workspaces-web"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-workspaces-web-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-workspaces-web-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-xray"},"\u2705 xray"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-xray-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-xray-spec:2023.09.22"')),(0,a.kt)("h3",{id:"ec2query"},"ec2Query"),(0,a.kt)("h4",{id:"-ec2"},"\u2705 ec2"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-ec2-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-ec2-spec:2023.09.22"')),(0,a.kt)("h3",{id:"awsquery"},"awsQuery"),(0,a.kt)("h4",{id:"-auto-scaling"},"\u2705 auto-scaling"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-auto-scaling-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-auto-scaling-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-cloudformation"},"\u2705 cloudformation"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-cloudformation-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-cloudformation-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-cloudsearch"},"\u2705 cloudsearch"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-cloudsearch-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-cloudsearch-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-cloudwatch"},"\u2705 cloudwatch"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-cloudwatch-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-cloudwatch-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-docdb"},"\u2705 docdb"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-docdb-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-docdb-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-elastic-beanstalk"},"\u2705 elastic-beanstalk"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-elastic-beanstalk-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-elastic-beanstalk-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-elastic-load-balancing-v2"},"\u2705 elastic-load-balancing-v2"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-elastic-load-balancing-v2-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-elastic-load-balancing-v2-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-elastic-load-balancing"},"\u2705 elastic-load-balancing"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-elastic-load-balancing-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-elastic-load-balancing-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-elasticache"},"\u2705 elasticache"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-elasticache-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-elasticache-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-iam"},"\u2705 iam"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-iam-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-iam-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-neptune"},"\u2705 neptune"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-neptune-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-neptune-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-rds"},"\u2705 rds"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-rds-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-rds-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-redshift"},"\u2705 redshift"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-redshift-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-redshift-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-ses"},"\u2705 ses"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-ses-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-ses-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-sns"},"\u2705 sns"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-sns-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-sns-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-sqs"},"\u2705 sqs"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-sqs-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-sqs-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-sts"},"\u2705 sts"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-sts-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-sts-spec:2023.09.22"')),(0,a.kt)("h3",{id:"awsjson1_0"},"awsJson1_0"),(0,a.kt)("h4",{id:"-apprunner"},"\u2705 apprunner"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-apprunner-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-apprunner-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-backup-gateway"},"\u2705 backup-gateway"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-backup-gateway-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-backup-gateway-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-cloudcontrol"},"\u2705 cloudcontrol"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-cloudcontrol-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-cloudcontrol-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-codestar-connections"},"\u2705 codestar-connections"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-codestar-connections-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-codestar-connections-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-compute-optimizer"},"\u2705 compute-optimizer"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-compute-optimizer-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-compute-optimizer-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-dynamodb-streams"},"\u2705 dynamodb-streams"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-dynamodb-streams-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-dynamodb-streams-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-dynamodb"},"\u2705 dynamodb"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-dynamodb-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-dynamodb-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-healthlake"},"\u2705 healthlake"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-healthlake-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-healthlake-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-iotfleetwise"},"\u2705 iotfleetwise"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-iotfleetwise-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-iotfleetwise-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-kendra-ranking"},"\u2705 kendra-ranking"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-kendra-ranking-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-kendra-ranking-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-keyspaces"},"\u2705 keyspaces"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-keyspaces-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-keyspaces-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-lookoutequipment"},"\u2705 lookoutequipment"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-lookoutequipment-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-lookoutequipment-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-network-firewall"},"\u2705 network-firewall"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-network-firewall-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-network-firewall-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-opensearchserverless"},"\u2705 opensearchserverless"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-opensearchserverless-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-opensearchserverless-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-payment-cryptography"},"\u2705 payment-cryptography"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-payment-cryptography-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-payment-cryptography-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-pinpoint-sms-voice-v2"},"\u2705 pinpoint-sms-voice-v2"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-pinpoint-sms-voice-v2-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-pinpoint-sms-voice-v2-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-proton"},"\u2705 proton"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-proton-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-proton-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-qldb-session"},"\u2705 qldb-session"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-qldb-session-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-qldb-session-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-route53-recovery-cluster"},"\u2705 route53-recovery-cluster"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-route53-recovery-cluster-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-route53-recovery-cluster-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-sfn"},"\u2705 sfn"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-sfn-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-sfn-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-swf"},"\u2705 swf"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-swf-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-swf-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-timestream-query"},"\u2705 timestream-query"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-timestream-query-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-timestream-query-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-timestream-write"},"\u2705 timestream-write"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-timestream-write-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-timestream-write-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-verifiedpermissions"},"\u2705 verifiedpermissions"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-verifiedpermissions-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-verifiedpermissions-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-voice-id"},"\u2705 voice-id"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-voice-id-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-voice-id-spec:2023.09.22"')),(0,a.kt)("h3",{id:"awsjson1_1"},"awsJson1_1"),(0,a.kt)("h4",{id:"-acm-pca"},"\u2705 acm-pca"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-acm-pca-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-acm-pca-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-acm"},"\u2705 acm"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-acm-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-acm-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-alexa-for-business"},"\u2705 alexa-for-business"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-alexa-for-business-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-alexa-for-business-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-application-auto-scaling"},"\u2705 application-auto-scaling"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-application-auto-scaling-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-application-auto-scaling-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-application-discovery-service"},"\u2705 application-discovery-service"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-application-discovery-service-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-application-discovery-service-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-application-insights"},"\u2705 application-insights"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-application-insights-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-application-insights-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-appstream"},"\u2705 appstream"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-appstream-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-appstream-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-athena"},"\u2705 athena"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-athena-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-athena-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-auto-scaling-plans"},"\u2705 auto-scaling-plans"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-auto-scaling-plans-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-auto-scaling-plans-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-budgets"},"\u2705 budgets"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-budgets-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-budgets-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-cloud9"},"\u2705 cloud9"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-cloud9-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-cloud9-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-cloudhsm-v2"},"\u2705 cloudhsm-v2"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-cloudhsm-v2-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-cloudhsm-v2-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-cloudhsm"},"\u2705 cloudhsm"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-cloudhsm-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-cloudhsm-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-cloudtrail"},"\u2705 cloudtrail"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-cloudtrail-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-cloudtrail-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-cloudwatch-events"},"\u2705 cloudwatch-events"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-cloudwatch-events-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-cloudwatch-events-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-cloudwatch-logs"},"\u2705 cloudwatch-logs"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-cloudwatch-logs-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-cloudwatch-logs-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-codebuild"},"\u2705 codebuild"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-codebuild-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-codebuild-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-codecommit"},"\u2705 codecommit"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-codecommit-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-codecommit-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-codedeploy"},"\u2705 codedeploy"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-codedeploy-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-codedeploy-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-codepipeline"},"\u2705 codepipeline"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-codepipeline-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-codepipeline-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-codestar"},"\u2705 codestar"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-codestar-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-codestar-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-cognito-identity-provider"},"\u2705 cognito-identity-provider"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-cognito-identity-provider-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-cognito-identity-provider-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-cognito-identity"},"\u2705 cognito-identity"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-cognito-identity-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-cognito-identity-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-comprehend"},"\u2705 comprehend"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-comprehend-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-comprehend-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-comprehendmedical"},"\u2705 comprehendmedical"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-comprehendmedical-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-comprehendmedical-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-config-service"},"\u2705 config-service"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-config-service-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-config-service-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-cost-and-usage-report-service"},"\u2705 cost-and-usage-report-service"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-cost-and-usage-report-service-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-cost-and-usage-report-service-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-cost-explorer"},"\u2705 cost-explorer"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-cost-explorer-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-cost-explorer-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-data-pipeline"},"\u2705 data-pipeline"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-data-pipeline-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-data-pipeline-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-database-migration-service"},"\u2705 database-migration-service"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-database-migration-service-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-database-migration-service-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-datasync"},"\u2705 datasync"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-datasync-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-datasync-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-dax"},"\u2705 dax"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-dax-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-dax-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-device-farm"},"\u2705 device-farm"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-device-farm-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-device-farm-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-direct-connect"},"\u2705 direct-connect"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-direct-connect-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-direct-connect-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-directory-service"},"\u2705 directory-service"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-directory-service-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-directory-service-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-ec2-instance-connect"},"\u2705 ec2-instance-connect"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-ec2-instance-connect-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-ec2-instance-connect-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-ecr-public"},"\u2705 ecr-public"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-ecr-public-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-ecr-public-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-ecr"},"\u2705 ecr"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-ecr-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-ecr-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-ecs"},"\u2705 ecs"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-ecs-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-ecs-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-emr"},"\u2705 emr"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-emr-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-emr-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-eventbridge"},"\u2705 eventbridge"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-eventbridge-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-eventbridge-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-firehose"},"\u2705 firehose"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-firehose-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-firehose-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-fms"},"\u2705 fms"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-fms-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-fms-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-forecast"},"\u2705 forecast"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-forecast-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-forecast-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-forecastquery"},"\u2705 forecastquery"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-forecastquery-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-forecastquery-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-frauddetector"},"\u2705 frauddetector"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-frauddetector-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-frauddetector-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-fsx"},"\u2705 fsx"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-fsx-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-fsx-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-gamelift"},"\u2705 gamelift"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-gamelift-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-gamelift-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-global-accelerator"},"\u2705 global-accelerator"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-global-accelerator-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-global-accelerator-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-glue"},"\u2705 glue"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-glue-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-glue-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-health"},"\u2705 health"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-health-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-health-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-identitystore"},"\u2705 identitystore"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-identitystore-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-identitystore-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-inspector"},"\u2705 inspector"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-inspector-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-inspector-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-iotsecuretunneling"},"\u2705 iotsecuretunneling"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-iotsecuretunneling-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-iotsecuretunneling-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-iotthingsgraph"},"\u2705 iotthingsgraph"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-iotthingsgraph-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-iotthingsgraph-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-kendra"},"\u2705 kendra"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-kendra-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-kendra-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-kinesis-analytics-v2"},"\u2705 kinesis-analytics-v2"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-kinesis-analytics-v2-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-kinesis-analytics-v2-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-kinesis-analytics"},"\u2705 kinesis-analytics"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-kinesis-analytics-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-kinesis-analytics-spec:2023.09.22"')),(0,a.kt)("h4",{id:"\ufe0f-kinesis"},"\u26a0\ufe0f kinesis"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-kinesis-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-kinesis-spec:2023.09.22"')),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Unsupported streaming operations")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"SubscribeToShard")),(0,a.kt)("h4",{id:"-kms"},"\u2705 kms"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-kms-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-kms-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-license-manager"},"\u2705 license-manager"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-license-manager-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-license-manager-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-lightsail"},"\u2705 lightsail"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-lightsail-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-lightsail-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-machine-learning"},"\u2705 machine-learning"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-machine-learning-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-machine-learning-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-macie"},"\u2705 macie"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-macie-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-macie-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-marketplace-commerce-analytics"},"\u2705 marketplace-commerce-analytics"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-marketplace-commerce-analytics-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-marketplace-commerce-analytics-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-marketplace-entitlement-service"},"\u2705 marketplace-entitlement-service"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-marketplace-entitlement-service-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-marketplace-entitlement-service-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-marketplace-metering"},"\u2705 marketplace-metering"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-marketplace-metering-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-marketplace-metering-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-mediastore"},"\u2705 mediastore"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-mediastore-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-mediastore-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-memorydb"},"\u2705 memorydb"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-memorydb-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-memorydb-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-migration-hub"},"\u2705 migration-hub"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-migration-hub-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-migration-hub-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-migrationhub-config"},"\u2705 migrationhub-config"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-migrationhub-config-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-migrationhub-config-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-mturk"},"\u2705 mturk"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-mturk-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-mturk-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-opsworks"},"\u2705 opsworks"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-opsworks-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-opsworks-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-opsworkscm"},"\u2705 opsworkscm"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-opsworkscm-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-opsworkscm-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-organizations"},"\u2705 organizations"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-organizations-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-organizations-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-personalize"},"\u2705 personalize"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-personalize-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-personalize-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-pi"},"\u2705 pi"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-pi-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-pi-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-pricing"},"\u2705 pricing"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-pricing-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-pricing-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-redshift-data"},"\u2705 redshift-data"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-redshift-data-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-redshift-data-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-redshift-serverless"},"\u2705 redshift-serverless"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-redshift-serverless-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-redshift-serverless-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-rekognition"},"\u2705 rekognition"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-rekognition-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-rekognition-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-resource-groups-tagging-api"},"\u2705 resource-groups-tagging-api"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-resource-groups-tagging-api-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-resource-groups-tagging-api-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-route-53-domains"},"\u2705 route-53-domains"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-route-53-domains-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-route-53-domains-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-route53resolver"},"\u2705 route53resolver"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-route53resolver-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-route53resolver-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-sagemaker"},"\u2705 sagemaker"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-sagemaker-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-sagemaker-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-secrets-manager"},"\u2705 secrets-manager"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-secrets-manager-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-secrets-manager-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-service-catalog"},"\u2705 service-catalog"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-service-catalog-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-service-catalog-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-service-quotas"},"\u2705 service-quotas"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-service-quotas-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-service-quotas-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-servicediscovery"},"\u2705 servicediscovery"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-servicediscovery-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-servicediscovery-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-shield"},"\u2705 shield"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-shield-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-shield-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-sms"},"\u2705 sms"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-sms-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-sms-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-snowball"},"\u2705 snowball"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-snowball-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-snowball-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-ssm-contacts"},"\u2705 ssm-contacts"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-ssm-contacts-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-ssm-contacts-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-ssm"},"\u2705 ssm"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-ssm-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-ssm-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-sso-admin"},"\u2705 sso-admin"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-sso-admin-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-sso-admin-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-storage-gateway"},"\u2705 storage-gateway"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-storage-gateway-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-storage-gateway-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-support"},"\u2705 support"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-support-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-support-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-textract"},"\u2705 textract"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-textract-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-textract-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-transcribe"},"\u2705 transcribe"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-transcribe-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-transcribe-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-transfer"},"\u2705 transfer"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-transfer-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-transfer-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-translate"},"\u2705 translate"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-translate-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-translate-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-waf-regional"},"\u2705 waf-regional"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-waf-regional-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-waf-regional-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-waf"},"\u2705 waf"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-waf-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-waf-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-wafv2"},"\u2705 wafv2"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-wafv2-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-wafv2-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-workmail"},"\u2705 workmail"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-workmail-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-workmail-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-workspaces"},"\u2705 workspaces"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-workspaces-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-workspaces-spec:2023.09.22"')),(0,a.kt)("h3",{id:"restxml"},"restXml"),(0,a.kt)("h4",{id:"-cloudfront"},"\u2705 cloudfront"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-cloudfront-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-cloudfront-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-route-53"},"\u2705 route-53"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-route-53-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-route-53-spec:2023.09.22"')),(0,a.kt)("h4",{id:"-s3-control"},"\u2705 s3-control"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-s3-control-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-s3-control-spec:2023.09.22"')),(0,a.kt)("h4",{id:"\ufe0f-s3"},"\u26a0\ufe0f s3"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},'sbt: "com.disneystreaming.smithy" % "aws-s3-spec" % "2023.09.22"'),(0,a.kt)("li",{parentName:"ul"},'mill: ivy"com.disneystreaming.smithy:aws-s3-spec:2023.09.22"')),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Unsupported streaming operations")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"WriteGetObjectResponse"),(0,a.kt)("li",{parentName:"ul"},"UploadPart"),(0,a.kt)("li",{parentName:"ul"},"SelectObjectContent"),(0,a.kt)("li",{parentName:"ul"},"PutObject"),(0,a.kt)("li",{parentName:"ul"},"GetObjectTorrent"),(0,a.kt)("li",{parentName:"ul"},"GetObject")))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/46a2298c.7c05dbb0.js b/assets/js/46a2298c.3d96141e.js similarity index 98% rename from assets/js/46a2298c.7c05dbb0.js rename to assets/js/46a2298c.3d96141e.js index 2cad293c2..2d31885e3 100644 --- a/assets/js/46a2298c.7c05dbb0.js +++ b/assets/js/46a2298c.3d96141e.js @@ -1 +1 @@ -"use strict";(self.webpackChunksmithy4s=self.webpackChunksmithy4s||[]).push([[7176],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var i=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function o(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=i.createContext({}),d=function(e){var t=i.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},p=function(e){var t=d(e.components);return i.createElement(s.Provider,{value:t},e.children)},h="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},c=i.forwardRef((function(e,t){var n=e.components,a=e.mdxType,r=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),h=d(n),c=a,m=h["".concat(s,".").concat(c)]||h[c]||u[c]||r;return n?i.createElement(m,o(o({ref:t},p),{},{components:n})):i.createElement(m,o({ref:t},p))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var r=n.length,o=new Array(r);o[0]=c;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[h]="string"==typeof e?e:a,o[1]=l;for(var d=2;d{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>u,frontMatter:()=>r,metadata:()=>l,toc:()=>d});var i=n(7462),a=(n(7294),n(3905));const r={sidebar_label:"Endpoint Specific Middleware",title:"Endpoint Specific Middleware"},o=void 0,l={unversionedId:"guides/endpoint-middleware",id:"guides/endpoint-middleware",title:"Endpoint Specific Middleware",description:"It used to be the case that any middleware implemented for smithy4s services would have to operate at the http4s level, without any knowledge of smithy4s or access to the constructs to utilizes.",source:"@site/../docs/target/jvm-2.13/mdoc/06-guides/endpoint-middleware.md",sourceDirName:"06-guides",slug:"/guides/endpoint-middleware",permalink:"/smithy4s/docs/guides/endpoint-middleware",draft:!1,editUrl:"https://github.com/disneystreaming/smithy4s/edit/main/modules/docs/src/06-guides/endpoint-middleware.md",tags:[],version:"current",frontMatter:{sidebar_label:"Endpoint Specific Middleware",title:"Endpoint Specific Middleware"},sidebar:"tutorialSidebar",previous:{title:"Dynamic module",permalink:"/smithy4s/docs/guides/dynamic"},next:{title:"Extracting Request Info",permalink:"/smithy4s/docs/guides/extract-request-info"}},s={},d=[{value:"ServerEndpointMiddleware / ClientEndpointMiddleware",id:"serverendpointmiddleware--clientendpointmiddleware",level:2},{value:"Smithy Spec",id:"smithy-spec",level:2},{value:"Server-side Middleware",id:"server-side-middleware",level:2},{value:"AuthChecker",id:"authchecker",level:4},{value:"The Inner Middleware Implementation",id:"the-inner-middleware-implementation",level:4},{value:"ServerEndpointMiddleware.Simple",id:"serverendpointmiddlewaresimple",level:4},{value:"Using the Middleware",id:"using-the-middleware",level:4},{value:"Client-side Middleware",id:"client-side-middleware",level:2},{value:"ClientEndpointMiddleware.Simple",id:"clientendpointmiddlewaresimple",level:4},{value:"SimpleRestJsonBuilder",id:"simplerestjsonbuilder",level:4},{value:"Conclusion",id:"conclusion",level:2}],p={toc:d},h="wrapper";function u(e){let{components:t,...n}=e;return(0,a.kt)(h,(0,i.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"It used to be the case that any middleware implemented for smithy4s services would have to operate at the http4s level, without any knowledge of smithy4s or access to the constructs to utilizes."),(0,a.kt)("p",null,"As of version ",(0,a.kt)("inlineCode",{parentName:"p"},"0.17.x")," of smithy4s, we have changed this by providing a new mechanism to build and provide middleware. This mechanism is aware of the smithy4s service and endpoints that are derived from your smithy specifications. As such, this unlocks the possibility to build middleware that utilizes and is compliant to the traits and shapes of your smithy specification."),(0,a.kt)("p",null,"In this guide, we will show how you can implement a smithy4s middleware that is aware of the authentication traits in your specification and is able to implement authenticate on an endpoint-by-endpoint basis. This is useful if you have different or no authentication on one or more endpoints."),(0,a.kt)("h2",{id:"serverendpointmiddleware--clientendpointmiddleware"},"ServerEndpointMiddleware / ClientEndpointMiddleware"),(0,a.kt)("p",null,(0,a.kt)("inlineCode",{parentName:"p"},"ServerEndpointMiddleware")," is the interface that we have provided for implementing service middleware. For some use cases, you will need to use the full interface. However, for this guide and for many use cases, you will be able to rely on the simpler interface called ",(0,a.kt)("inlineCode",{parentName:"p"},"ServerEndpointMiddleware.Simple"),". This interface requires a single method which looks as follows:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-scala"},"def prepareWithHints(\n serviceHints: Hints,\n endpointHints: Hints\n ): HttpApp[F] => HttpApp[F]\n")),(0,a.kt)("p",null,"This means that given the hints for the service and a specific endpoint, our implementation will provide a transformation of an ",(0,a.kt)("inlineCode",{parentName:"p"},"HttpApp"),". If you are not familiar with ",(0,a.kt)("inlineCode",{parentName:"p"},"Hints"),", they are the smithy4s construct that represents Smithy Traits. They are called hints to avoid naming conflicts and confusion with Scala ",(0,a.kt)("inlineCode",{parentName:"p"},"trait"),"s."),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"ClientEndpointMiddleware")," interface is essentially the same as the one for ",(0,a.kt)("inlineCode",{parentName:"p"},"ServerEndpointMiddleware")," with the exception that we are returning a transformation on ",(0,a.kt)("inlineCode",{parentName:"p"},"Client[F]")," instead of ",(0,a.kt)("inlineCode",{parentName:"p"},"HttpApp[F]"),". This looks like:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-scala"},"def prepareWithHints(\n serviceHints: Hints,\n endpointHints: Hints\n ): Client[F] => Client[F]\n")),(0,a.kt)("h2",{id:"smithy-spec"},"Smithy Spec"),(0,a.kt)("p",null,"Let's look at the smithy specification that we will use for this guide. First, let's define the service."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-kotlin"},'$version: "2"\n\nnamespace smithy4s.example.guides.auth\n\nuse alloy#simpleRestJson\n\n@simpleRestJson\n@httpBearerAuth\nservice HelloWorldAuthService {\n version: "1.0.0",\n operations: [SayWorld, HealthCheck]\n errors: [NotAuthorizedError]\n}\n')),(0,a.kt)("p",null,"Here we defined a service that has two operations, ",(0,a.kt)("inlineCode",{parentName:"p"},"SayWorld")," and ",(0,a.kt)("inlineCode",{parentName:"p"},"HealthCheck"),". We defined it such that any of these operations may return an ",(0,a.kt)("inlineCode",{parentName:"p"},"NotAuthorizedError"),". Finally, we annotated the service with the ",(0,a.kt)("inlineCode",{parentName:"p"},"@httpBearerAuth")," ",(0,a.kt)("a",{parentName:"p",href:"https://smithy.io/2.0/spec/authentication-traits.html#httpbearerauth-trait"},"trait")," to indicate that the service supports authentication via a bearer token. If you are using a different authentication scheme, you can still follow this guide and adapt it for your needs. You can find a full list of smithy-provided schemes ",(0,a.kt)("a",{parentName:"p",href:"https://smithy.io/2.0/spec/authentication-traits.html"},"here"),". If none of the provided traits suit your use case, you can always create a custom trait too."),(0,a.kt)("p",null,"Next, let's define our first operation, ",(0,a.kt)("inlineCode",{parentName:"p"},"SayWorld"),":"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-kotlin"},'@readonly\n@http(method: "GET", uri: "/hello", code: 200)\noperation SayWorld {\n output: World\n}\n\nstructure World {\n message: String = "World !"\n}\n')),(0,a.kt)("p",null,"There is nothing authentication-specific defined with this operation, this means that the operation inherits the service-defined authentication scheme (",(0,a.kt)("inlineCode",{parentName:"p"},"httpBearerAuth")," in this case). Let's contrast this with the ",(0,a.kt)("inlineCode",{parentName:"p"},"HealthCheck")," operation:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-kotlin"},'@readonly\n@http(method: "GET", uri: "/health", code: 200)\n@auth([])\noperation HealthCheck {\n output := {\n @required\n message: String\n }\n}\n')),(0,a.kt)("p",null,"Notice that on this operation we have added the ",(0,a.kt)("inlineCode",{parentName:"p"},"@auth([])")," trait with an empty array. This means that there is no authentication required for this endpoint. In other words, although the service defines an authentication scheme of ",(0,a.kt)("inlineCode",{parentName:"p"},"httpBearerAuth"),", that scheme will not apply to this endpoint."),(0,a.kt)("p",null,"Finally, let's define the ",(0,a.kt)("inlineCode",{parentName:"p"},"NotAuthorizedError")," that will be returned when an authentication token is missing or invalid."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-kotlin"},'@error("client")\n@httpError(401)\nstructure NotAuthorizedError {\n @required\n message: String\n}\n')),(0,a.kt)("p",null,"There is nothing authentication specific about this error, this is a standard smithy http error that will have a 401 status code when returned."),(0,a.kt)("p",null,"If you want to see the full smithy model we defined above, you can do so ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/disneystreaming/smithy4s/blob/9f2dbcbd29b4dbd35792fa40e423a6395ae3f9e6/modules/guides/smithy/auth.smithy"},"here"),"."),(0,a.kt)("h2",{id:"server-side-middleware"},"Server-side Middleware"),(0,a.kt)("p",null,"To see the ",(0,a.kt)("strong",{parentName:"p"},"full code")," example of what we walk through below, go ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/disneystreaming/smithy4s/blob/9f2dbcbd29b4dbd35792fa40e423a6395ae3f9e6/modules/guides/src/smithy4s/guides/Auth.scala"},"here"),"."),(0,a.kt)("p",null,"We will create a server-side middleware that implements the authentication as defined in the smithy spec above. Let's start by creating a few classes that we will use in our middleware."),(0,a.kt)("h4",{id:"authchecker"},"AuthChecker"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-scala"},"case class ApiToken(value: String)\n\ntrait AuthChecker {\n def isAuthorized(token: ApiToken): IO[Boolean]\n}\n\nobject AuthChecker extends AuthChecker {\n def isAuthorized(token: ApiToken): IO[Boolean] = {\n IO.pure(\n token.value.nonEmpty\n ) // put your logic here, currently just makes sure the token is not empty\n }\n}\n")),(0,a.kt)("p",null,"This is a simple class that we will use to check the validity of a given token. This will be more complex in your own service, but we are keeping it simple here since it is out of the scope of this article and implementations will vary widely depending on your specific application."),(0,a.kt)("h4",{id:"the-inner-middleware-implementation"},"The Inner Middleware Implementation"),(0,a.kt)("p",null,"This function is what is called once we have made sure that the middleware is applicable for a given endpoint. We will show in the next step how to tell if the middleware is applicable or not. For now though, we will just focus on what the middleware does once we know that it needs to be applied to a given endpoint."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-scala"},'def middleware(\n authChecker: AuthChecker // 1\n): HttpApp[IO] => HttpApp[IO] = { inputApp => // 2\n HttpApp[IO] { request => // 3\n val maybeKey = request.headers // 4\n .get[`Authorization`]\n .collect {\n case Authorization(\n Credentials.Token(AuthScheme.Bearer, value)\n ) =>\n value\n }\n .map { ApiToken.apply }\n\n val isAuthorized = maybeKey\n .map { key =>\n authChecker.isAuthorized(key) // 5\n }\n .getOrElse(IO.pure(false))\n\n isAuthorized.ifM(\n ifTrue = inputApp(request), // 6\n ifFalse = IO.raiseError(new NotAuthorizedError("Not authorized!")) // 7\n )\n }\n}\n')),(0,a.kt)("p",null,"Let's break down what we did above step by step. The step numbers below correspond to the comment numbers above."),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Pass an instance of ",(0,a.kt)("inlineCode",{parentName:"li"},"AuthChecker")," that we can use to verify auth tokens are valid in this middleware"),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"inputApp")," is the ",(0,a.kt)("inlineCode",{parentName:"li"},"HttpApp[IO]")," that we are transforming in this middleware."),(0,a.kt)("li",{parentName:"ol"},"Here we create a new HttpApp, the one that we will be returning from this function we are creating."),(0,a.kt)("li",{parentName:"ol"},"Here we extract the value of the ",(0,a.kt)("inlineCode",{parentName:"li"},"Authorization")," header, if it is present."),(0,a.kt)("li",{parentName:"ol"},"If the header had a value, we now send that value into the ",(0,a.kt)("inlineCode",{parentName:"li"},"AuthChecker")," to see if it is valid."),(0,a.kt)("li",{parentName:"ol"},"If the token was found to be valid, we pass the request into the ",(0,a.kt)("inlineCode",{parentName:"li"},"inputApp")," from step 2 in order to get a response."),(0,a.kt)("li",{parentName:"ol"},"If the header was found to be invalid, we return the ",(0,a.kt)("inlineCode",{parentName:"li"},"NotAuthorizedError")," that we defined in our smithy file above.")),(0,a.kt)("h4",{id:"serverendpointmiddlewaresimple"},"ServerEndpointMiddleware.Simple"),(0,a.kt)("p",null,"Next, let's create our middleware by implementing the ",(0,a.kt)("inlineCode",{parentName:"p"},"ServerEndpointMiddleware.Simple")," interface we discussed above."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-scala"},"object AuthMiddleware {\n def apply(\n authChecker: AuthChecker // 1\n ): ServerEndpointMiddleware[IO] =\n new ServerEndpointMiddleware.Simple[IO] {\n private val mid: HttpApp[IO] => HttpApp[IO] = middleware(authChecker) // 2\n def prepareWithHints(\n serviceHints: Hints,\n endpointHints: Hints\n ): HttpApp[IO] => HttpApp[IO] = {\n serviceHints.get[smithy.api.HttpBearerAuth] match { // 3\n case Some(_) =>\n endpointHints.get[smithy.api.Auth] match { // 4\n case Some(auths) if auths.value.isEmpty => identity // 5\n case _ => mid // 6\n }\n case None => identity\n }\n }\n }\n}\n")),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Pass in an instance of ",(0,a.kt)("inlineCode",{parentName:"li"},"AuthChecker")," for the middleware to use. This is how the middleware will know if a given token is valid or not."),(0,a.kt)("li",{parentName:"ol"},"This is the function that we defined in the step above."),(0,a.kt)("li",{parentName:"ol"},"Check and see if the service at hand does in fact have the ",(0,a.kt)("inlineCode",{parentName:"li"},"httpBearerAuth")," trait on it. If it doesn't, then we will not do our auth checks. If it does, then we will proceed."),(0,a.kt)("li",{parentName:"ol"},"Here we are getting the ",(0,a.kt)("inlineCode",{parentName:"li"},"@auth")," trait from the operation (endpoint in smithy4s lingo). We need to check for this trait because of step 5."),(0,a.kt)("li",{parentName:"ol"},"Here we are checking that IF the auth trait is on this endpoint AND the auth trait contains an empty array THEN we are performing NO authentication checks. This is how we handle the ",(0,a.kt)("inlineCode",{parentName:"li"},"@auth([])")," trait that is present on the ",(0,a.kt)("inlineCode",{parentName:"li"},"HealthCheck")," operation we defined above."),(0,a.kt)("li",{parentName:"ol"},"IF the auth trait is NOT present on the operation, OR it is present AND it contains one or more authentication schemes, we apply the middleware.")),(0,a.kt)("h4",{id:"using-the-middleware"},"Using the Middleware"),(0,a.kt)("p",null,"From here, we can pass our middleware into our ",(0,a.kt)("inlineCode",{parentName:"p"},"SimpleRestJsonBuilder")," as follows:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-scala"},'object HelloWorldAuthImpl extends HelloWorldAuthService[IO] {\n def sayWorld(): IO[World] = World().pure[IO]\n def healthCheck(): IO[HealthCheckOutput] = HealthCheckOutput("Okay!").pure[IO]\n}\n\nval routes = SimpleRestJsonBuilder\n .routes(HelloWorldAuthImpl)\n .middleware(AuthMiddleware(AuthChecker))\n .resource\n')),(0,a.kt)("p",null,"And that's it. Now we have a middleware that will apply an authentication check on incoming requests whenever relevant, as defined in our smithy file."),(0,a.kt)("h2",{id:"client-side-middleware"},"Client-side Middleware"),(0,a.kt)("p",null,"To see the ",(0,a.kt)("strong",{parentName:"p"},"full code")," example of what we walk through below, go ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/disneystreaming/smithy4s/blob/9f2dbcbd29b4dbd35792fa40e423a6395ae3f9e6/modules/guides/src/smithy4s/guides/AuthClient.scala"},"here"),"."),(0,a.kt)("p",null,"It is possible that you have a client where you want to apply a similar type of middleware that alters some part of a request depending on the endpoint being targeted. In this part of the guide, we will show how you can do this for a client using the same smithy specification we defined above. We will make it so our authentication token is only sent if we are targeting an endpoint which requires it."),(0,a.kt)("h4",{id:"clientendpointmiddlewaresimple"},"ClientEndpointMiddleware.Simple"),(0,a.kt)("p",null,"The interface that we define for this middleware is going to look very similar to the one we defined above. This makes sense because this middleware is effectively the dual of the middleware above."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-scala"},"object Middleware {\n\n private def middleware(bearerToken: String): Client[IO] => Client[IO] = { // 1\n inputClient =>\n Client[IO] { request =>\n val newRequest = request.putHeaders( // 2\n Authorization(Credentials.Token(AuthScheme.Bearer, bearerToken))\n )\n\n inputClient.run(newRequest)\n }\n }\n\n def apply(bearerToken: String): ClientEndpointMiddleware[IO] = // 3\n new ClientEndpointMiddleware.Simple[IO] {\n private val mid = middleware(bearerToken)\n def prepareWithHints(\n serviceHints: Hints,\n endpointHints: Hints\n ): Client[IO] => Client[IO] = {\n serviceHints.get[smithy.api.HttpBearerAuth] match {\n case Some(_) =>\n endpointHints.get[smithy.api.Auth] match {\n case Some(auths) if auths.value.isEmpty => identity\n case _ => mid\n }\n case None => identity\n }\n }\n }\n\n}\n")),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Here we are creating an inner middleware function, just like we did above. The only differences are that this time we are adding a value to the request instead of extracting one from it and we are operating on ",(0,a.kt)("inlineCode",{parentName:"li"},"Client")," instead of ",(0,a.kt)("inlineCode",{parentName:"li"},"HttpApp"),"."),(0,a.kt)("li",{parentName:"ol"},"Add the ",(0,a.kt)("inlineCode",{parentName:"li"},"Authorization")," header to the request and pass it to the ",(0,a.kt)("inlineCode",{parentName:"li"},"inputClient")," that we are transforming in this middleware."),(0,a.kt)("li",{parentName:"ol"},"This function is actually the ",(0,a.kt)("em",{parentName:"li"},"exact same")," as the function for the middleware we implemented above. The only differences are that this apply method accepts a ",(0,a.kt)("inlineCode",{parentName:"li"},"bearerToken")," as a parameter and returns a function on ",(0,a.kt)("inlineCode",{parentName:"li"},"Client")," instead of ",(0,a.kt)("inlineCode",{parentName:"li"},"HttpApp"),". The provided ",(0,a.kt)("inlineCode",{parentName:"li"},"bearerToken")," is what we will add into the ",(0,a.kt)("inlineCode",{parentName:"li"},"Authorization")," header when applicable.")),(0,a.kt)("h4",{id:"simplerestjsonbuilder"},"SimpleRestJsonBuilder"),(0,a.kt)("p",null,"As above, we now just need to wire our middleware into our actual implementation. Here we are constructing a client and specifying the middleware we just defined."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-scala"},'def apply(http4sClient: Client[IO]): Resource[IO, HelloWorldAuthService[IO]] =\n SimpleRestJsonBuilder(HelloWorldAuthService)\n .client(http4sClient)\n .uri(Uri.unsafeFromString("http://localhost:9000"))\n .middleware(Middleware("my-token")) // creating our middleware here\n .resource\n')),(0,a.kt)("h2",{id:"conclusion"},"Conclusion"),(0,a.kt)("p",null,"Once again, if you want to see the ",(0,a.kt)("strong",{parentName:"p"},"full code")," examples of the above, you can find them ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/disneystreaming/smithy4s/blob/9f2dbcbd29b4dbd35792fa40e423a6395ae3f9e6/modules/guides/src/smithy4s/guides/"},"here"),"."),(0,a.kt)("p",null,"Hopefully this guide gives you a good idea of how you can create a middleware that takes your smithy specification into account. This guide shows a very simple use case of what is possible with a middleware like this. If you have a more advanced use case, you can use this guide as a reference and as always you can reach out to us for insight or help."))}u.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunksmithy4s=self.webpackChunksmithy4s||[]).push([[7176],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var i=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function o(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=i.createContext({}),d=function(e){var t=i.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},p=function(e){var t=d(e.components);return i.createElement(s.Provider,{value:t},e.children)},h="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},c=i.forwardRef((function(e,t){var n=e.components,a=e.mdxType,r=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),h=d(n),c=a,m=h["".concat(s,".").concat(c)]||h[c]||u[c]||r;return n?i.createElement(m,o(o({ref:t},p),{},{components:n})):i.createElement(m,o({ref:t},p))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var r=n.length,o=new Array(r);o[0]=c;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[h]="string"==typeof e?e:a,o[1]=l;for(var d=2;d{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>u,frontMatter:()=>r,metadata:()=>l,toc:()=>d});var i=n(7462),a=(n(7294),n(3905));const r={sidebar_label:"Endpoint Specific Middleware",title:"Endpoint Specific Middleware"},o=void 0,l={unversionedId:"guides/endpoint-middleware",id:"guides/endpoint-middleware",title:"Endpoint Specific Middleware",description:"It used to be the case that any middleware implemented for smithy4s services would have to operate at the http4s level, without any knowledge of smithy4s or access to the constructs to utilizes.",source:"@site/../docs/target/jvm-2.13/mdoc/06-guides/endpoint-middleware.md",sourceDirName:"06-guides",slug:"/guides/endpoint-middleware",permalink:"/smithy4s/docs/guides/endpoint-middleware",draft:!1,editUrl:"https://github.com/disneystreaming/smithy4s/edit/main/modules/docs/src/06-guides/endpoint-middleware.md",tags:[],version:"current",frontMatter:{sidebar_label:"Endpoint Specific Middleware",title:"Endpoint Specific Middleware"},sidebar:"tutorialSidebar",previous:{title:"Dynamic module",permalink:"/smithy4s/docs/guides/dynamic"},next:{title:"Extracting Request Info",permalink:"/smithy4s/docs/guides/extract-request-info"}},s={},d=[{value:"ServerEndpointMiddleware / ClientEndpointMiddleware",id:"serverendpointmiddleware--clientendpointmiddleware",level:2},{value:"Smithy Spec",id:"smithy-spec",level:2},{value:"Server-side Middleware",id:"server-side-middleware",level:2},{value:"AuthChecker",id:"authchecker",level:4},{value:"The Inner Middleware Implementation",id:"the-inner-middleware-implementation",level:4},{value:"ServerEndpointMiddleware.Simple",id:"serverendpointmiddlewaresimple",level:4},{value:"Using the Middleware",id:"using-the-middleware",level:4},{value:"Client-side Middleware",id:"client-side-middleware",level:2},{value:"ClientEndpointMiddleware.Simple",id:"clientendpointmiddlewaresimple",level:4},{value:"SimpleRestJsonBuilder",id:"simplerestjsonbuilder",level:4},{value:"Conclusion",id:"conclusion",level:2}],p={toc:d},h="wrapper";function u(e){let{components:t,...n}=e;return(0,a.kt)(h,(0,i.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"It used to be the case that any middleware implemented for smithy4s services would have to operate at the http4s level, without any knowledge of smithy4s or access to the constructs to utilizes."),(0,a.kt)("p",null,"As of version ",(0,a.kt)("inlineCode",{parentName:"p"},"0.17.x")," of smithy4s, we have changed this by providing a new mechanism to build and provide middleware. This mechanism is aware of the smithy4s service and endpoints that are derived from your smithy specifications. As such, this unlocks the possibility to build middleware that utilizes and is compliant to the traits and shapes of your smithy specification."),(0,a.kt)("p",null,"In this guide, we will show how you can implement a smithy4s middleware that is aware of the authentication traits in your specification and is able to implement authenticate on an endpoint-by-endpoint basis. This is useful if you have different or no authentication on one or more endpoints."),(0,a.kt)("h2",{id:"serverendpointmiddleware--clientendpointmiddleware"},"ServerEndpointMiddleware / ClientEndpointMiddleware"),(0,a.kt)("p",null,(0,a.kt)("inlineCode",{parentName:"p"},"ServerEndpointMiddleware")," is the interface that we have provided for implementing service middleware. For some use cases, you will need to use the full interface. However, for this guide and for many use cases, you will be able to rely on the simpler interface called ",(0,a.kt)("inlineCode",{parentName:"p"},"ServerEndpointMiddleware.Simple"),". This interface requires a single method which looks as follows:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-scala"},"def prepareWithHints(\n serviceHints: Hints,\n endpointHints: Hints\n ): HttpApp[F] => HttpApp[F]\n")),(0,a.kt)("p",null,"This means that given the hints for the service and a specific endpoint, our implementation will provide a transformation of an ",(0,a.kt)("inlineCode",{parentName:"p"},"HttpApp"),". If you are not familiar with ",(0,a.kt)("inlineCode",{parentName:"p"},"Hints"),", they are the smithy4s construct that represents Smithy Traits. They are called hints to avoid naming conflicts and confusion with Scala ",(0,a.kt)("inlineCode",{parentName:"p"},"trait"),"s."),(0,a.kt)("p",null,"The ",(0,a.kt)("inlineCode",{parentName:"p"},"ClientEndpointMiddleware")," interface is essentially the same as the one for ",(0,a.kt)("inlineCode",{parentName:"p"},"ServerEndpointMiddleware")," with the exception that we are returning a transformation on ",(0,a.kt)("inlineCode",{parentName:"p"},"Client[F]")," instead of ",(0,a.kt)("inlineCode",{parentName:"p"},"HttpApp[F]"),". This looks like:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-scala"},"def prepareWithHints(\n serviceHints: Hints,\n endpointHints: Hints\n ): Client[F] => Client[F]\n")),(0,a.kt)("h2",{id:"smithy-spec"},"Smithy Spec"),(0,a.kt)("p",null,"Let's look at the smithy specification that we will use for this guide. First, let's define the service."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-kotlin"},'$version: "2"\n\nnamespace smithy4s.example.guides.auth\n\nuse alloy#simpleRestJson\n\n@simpleRestJson\n@httpBearerAuth\nservice HelloWorldAuthService {\n version: "1.0.0",\n operations: [SayWorld, HealthCheck]\n errors: [NotAuthorizedError]\n}\n')),(0,a.kt)("p",null,"Here we defined a service that has two operations, ",(0,a.kt)("inlineCode",{parentName:"p"},"SayWorld")," and ",(0,a.kt)("inlineCode",{parentName:"p"},"HealthCheck"),". We defined it such that any of these operations may return an ",(0,a.kt)("inlineCode",{parentName:"p"},"NotAuthorizedError"),". Finally, we annotated the service with the ",(0,a.kt)("inlineCode",{parentName:"p"},"@httpBearerAuth")," ",(0,a.kt)("a",{parentName:"p",href:"https://smithy.io/2.0/spec/authentication-traits.html#httpbearerauth-trait"},"trait")," to indicate that the service supports authentication via a bearer token. If you are using a different authentication scheme, you can still follow this guide and adapt it for your needs. You can find a full list of smithy-provided schemes ",(0,a.kt)("a",{parentName:"p",href:"https://smithy.io/2.0/spec/authentication-traits.html"},"here"),". If none of the provided traits suit your use case, you can always create a custom trait too."),(0,a.kt)("p",null,"Next, let's define our first operation, ",(0,a.kt)("inlineCode",{parentName:"p"},"SayWorld"),":"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-kotlin"},'@readonly\n@http(method: "GET", uri: "/hello", code: 200)\noperation SayWorld {\n output: World\n}\n\nstructure World {\n message: String = "World !"\n}\n')),(0,a.kt)("p",null,"There is nothing authentication-specific defined with this operation, this means that the operation inherits the service-defined authentication scheme (",(0,a.kt)("inlineCode",{parentName:"p"},"httpBearerAuth")," in this case). Let's contrast this with the ",(0,a.kt)("inlineCode",{parentName:"p"},"HealthCheck")," operation:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-kotlin"},'@readonly\n@http(method: "GET", uri: "/health", code: 200)\n@auth([])\noperation HealthCheck {\n output := {\n @required\n message: String\n }\n}\n')),(0,a.kt)("p",null,"Notice that on this operation we have added the ",(0,a.kt)("inlineCode",{parentName:"p"},"@auth([])")," trait with an empty array. This means that there is no authentication required for this endpoint. In other words, although the service defines an authentication scheme of ",(0,a.kt)("inlineCode",{parentName:"p"},"httpBearerAuth"),", that scheme will not apply to this endpoint."),(0,a.kt)("p",null,"Finally, let's define the ",(0,a.kt)("inlineCode",{parentName:"p"},"NotAuthorizedError")," that will be returned when an authentication token is missing or invalid."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-kotlin"},'@error("client")\n@httpError(401)\nstructure NotAuthorizedError {\n @required\n message: String\n}\n')),(0,a.kt)("p",null,"There is nothing authentication specific about this error, this is a standard smithy http error that will have a 401 status code when returned."),(0,a.kt)("p",null,"If you want to see the full smithy model we defined above, you can do so ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/disneystreaming/smithy4s/blob/8cb01fd92d65f6e4ec515fccb3677cffe6a1093b/modules/guides/smithy/auth.smithy"},"here"),"."),(0,a.kt)("h2",{id:"server-side-middleware"},"Server-side Middleware"),(0,a.kt)("p",null,"To see the ",(0,a.kt)("strong",{parentName:"p"},"full code")," example of what we walk through below, go ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/disneystreaming/smithy4s/blob/8cb01fd92d65f6e4ec515fccb3677cffe6a1093b/modules/guides/src/smithy4s/guides/Auth.scala"},"here"),"."),(0,a.kt)("p",null,"We will create a server-side middleware that implements the authentication as defined in the smithy spec above. Let's start by creating a few classes that we will use in our middleware."),(0,a.kt)("h4",{id:"authchecker"},"AuthChecker"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-scala"},"case class ApiToken(value: String)\n\ntrait AuthChecker {\n def isAuthorized(token: ApiToken): IO[Boolean]\n}\n\nobject AuthChecker extends AuthChecker {\n def isAuthorized(token: ApiToken): IO[Boolean] = {\n IO.pure(\n token.value.nonEmpty\n ) // put your logic here, currently just makes sure the token is not empty\n }\n}\n")),(0,a.kt)("p",null,"This is a simple class that we will use to check the validity of a given token. This will be more complex in your own service, but we are keeping it simple here since it is out of the scope of this article and implementations will vary widely depending on your specific application."),(0,a.kt)("h4",{id:"the-inner-middleware-implementation"},"The Inner Middleware Implementation"),(0,a.kt)("p",null,"This function is what is called once we have made sure that the middleware is applicable for a given endpoint. We will show in the next step how to tell if the middleware is applicable or not. For now though, we will just focus on what the middleware does once we know that it needs to be applied to a given endpoint."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-scala"},'def middleware(\n authChecker: AuthChecker // 1\n): HttpApp[IO] => HttpApp[IO] = { inputApp => // 2\n HttpApp[IO] { request => // 3\n val maybeKey = request.headers // 4\n .get[`Authorization`]\n .collect {\n case Authorization(\n Credentials.Token(AuthScheme.Bearer, value)\n ) =>\n value\n }\n .map { ApiToken.apply }\n\n val isAuthorized = maybeKey\n .map { key =>\n authChecker.isAuthorized(key) // 5\n }\n .getOrElse(IO.pure(false))\n\n isAuthorized.ifM(\n ifTrue = inputApp(request), // 6\n ifFalse = IO.raiseError(new NotAuthorizedError("Not authorized!")) // 7\n )\n }\n}\n')),(0,a.kt)("p",null,"Let's break down what we did above step by step. The step numbers below correspond to the comment numbers above."),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Pass an instance of ",(0,a.kt)("inlineCode",{parentName:"li"},"AuthChecker")," that we can use to verify auth tokens are valid in this middleware"),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"inputApp")," is the ",(0,a.kt)("inlineCode",{parentName:"li"},"HttpApp[IO]")," that we are transforming in this middleware."),(0,a.kt)("li",{parentName:"ol"},"Here we create a new HttpApp, the one that we will be returning from this function we are creating."),(0,a.kt)("li",{parentName:"ol"},"Here we extract the value of the ",(0,a.kt)("inlineCode",{parentName:"li"},"Authorization")," header, if it is present."),(0,a.kt)("li",{parentName:"ol"},"If the header had a value, we now send that value into the ",(0,a.kt)("inlineCode",{parentName:"li"},"AuthChecker")," to see if it is valid."),(0,a.kt)("li",{parentName:"ol"},"If the token was found to be valid, we pass the request into the ",(0,a.kt)("inlineCode",{parentName:"li"},"inputApp")," from step 2 in order to get a response."),(0,a.kt)("li",{parentName:"ol"},"If the header was found to be invalid, we return the ",(0,a.kt)("inlineCode",{parentName:"li"},"NotAuthorizedError")," that we defined in our smithy file above.")),(0,a.kt)("h4",{id:"serverendpointmiddlewaresimple"},"ServerEndpointMiddleware.Simple"),(0,a.kt)("p",null,"Next, let's create our middleware by implementing the ",(0,a.kt)("inlineCode",{parentName:"p"},"ServerEndpointMiddleware.Simple")," interface we discussed above."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-scala"},"object AuthMiddleware {\n def apply(\n authChecker: AuthChecker // 1\n ): ServerEndpointMiddleware[IO] =\n new ServerEndpointMiddleware.Simple[IO] {\n private val mid: HttpApp[IO] => HttpApp[IO] = middleware(authChecker) // 2\n def prepareWithHints(\n serviceHints: Hints,\n endpointHints: Hints\n ): HttpApp[IO] => HttpApp[IO] = {\n serviceHints.get[smithy.api.HttpBearerAuth] match { // 3\n case Some(_) =>\n endpointHints.get[smithy.api.Auth] match { // 4\n case Some(auths) if auths.value.isEmpty => identity // 5\n case _ => mid // 6\n }\n case None => identity\n }\n }\n }\n}\n")),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Pass in an instance of ",(0,a.kt)("inlineCode",{parentName:"li"},"AuthChecker")," for the middleware to use. This is how the middleware will know if a given token is valid or not."),(0,a.kt)("li",{parentName:"ol"},"This is the function that we defined in the step above."),(0,a.kt)("li",{parentName:"ol"},"Check and see if the service at hand does in fact have the ",(0,a.kt)("inlineCode",{parentName:"li"},"httpBearerAuth")," trait on it. If it doesn't, then we will not do our auth checks. If it does, then we will proceed."),(0,a.kt)("li",{parentName:"ol"},"Here we are getting the ",(0,a.kt)("inlineCode",{parentName:"li"},"@auth")," trait from the operation (endpoint in smithy4s lingo). We need to check for this trait because of step 5."),(0,a.kt)("li",{parentName:"ol"},"Here we are checking that IF the auth trait is on this endpoint AND the auth trait contains an empty array THEN we are performing NO authentication checks. This is how we handle the ",(0,a.kt)("inlineCode",{parentName:"li"},"@auth([])")," trait that is present on the ",(0,a.kt)("inlineCode",{parentName:"li"},"HealthCheck")," operation we defined above."),(0,a.kt)("li",{parentName:"ol"},"IF the auth trait is NOT present on the operation, OR it is present AND it contains one or more authentication schemes, we apply the middleware.")),(0,a.kt)("h4",{id:"using-the-middleware"},"Using the Middleware"),(0,a.kt)("p",null,"From here, we can pass our middleware into our ",(0,a.kt)("inlineCode",{parentName:"p"},"SimpleRestJsonBuilder")," as follows:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-scala"},'object HelloWorldAuthImpl extends HelloWorldAuthService[IO] {\n def sayWorld(): IO[World] = World().pure[IO]\n def healthCheck(): IO[HealthCheckOutput] = HealthCheckOutput("Okay!").pure[IO]\n}\n\nval routes = SimpleRestJsonBuilder\n .routes(HelloWorldAuthImpl)\n .middleware(AuthMiddleware(AuthChecker))\n .resource\n')),(0,a.kt)("p",null,"And that's it. Now we have a middleware that will apply an authentication check on incoming requests whenever relevant, as defined in our smithy file."),(0,a.kt)("h2",{id:"client-side-middleware"},"Client-side Middleware"),(0,a.kt)("p",null,"To see the ",(0,a.kt)("strong",{parentName:"p"},"full code")," example of what we walk through below, go ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/disneystreaming/smithy4s/blob/8cb01fd92d65f6e4ec515fccb3677cffe6a1093b/modules/guides/src/smithy4s/guides/AuthClient.scala"},"here"),"."),(0,a.kt)("p",null,"It is possible that you have a client where you want to apply a similar type of middleware that alters some part of a request depending on the endpoint being targeted. In this part of the guide, we will show how you can do this for a client using the same smithy specification we defined above. We will make it so our authentication token is only sent if we are targeting an endpoint which requires it."),(0,a.kt)("h4",{id:"clientendpointmiddlewaresimple"},"ClientEndpointMiddleware.Simple"),(0,a.kt)("p",null,"The interface that we define for this middleware is going to look very similar to the one we defined above. This makes sense because this middleware is effectively the dual of the middleware above."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-scala"},"object Middleware {\n\n private def middleware(bearerToken: String): Client[IO] => Client[IO] = { // 1\n inputClient =>\n Client[IO] { request =>\n val newRequest = request.putHeaders( // 2\n Authorization(Credentials.Token(AuthScheme.Bearer, bearerToken))\n )\n\n inputClient.run(newRequest)\n }\n }\n\n def apply(bearerToken: String): ClientEndpointMiddleware[IO] = // 3\n new ClientEndpointMiddleware.Simple[IO] {\n private val mid = middleware(bearerToken)\n def prepareWithHints(\n serviceHints: Hints,\n endpointHints: Hints\n ): Client[IO] => Client[IO] = {\n serviceHints.get[smithy.api.HttpBearerAuth] match {\n case Some(_) =>\n endpointHints.get[smithy.api.Auth] match {\n case Some(auths) if auths.value.isEmpty => identity\n case _ => mid\n }\n case None => identity\n }\n }\n }\n\n}\n")),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Here we are creating an inner middleware function, just like we did above. The only differences are that this time we are adding a value to the request instead of extracting one from it and we are operating on ",(0,a.kt)("inlineCode",{parentName:"li"},"Client")," instead of ",(0,a.kt)("inlineCode",{parentName:"li"},"HttpApp"),"."),(0,a.kt)("li",{parentName:"ol"},"Add the ",(0,a.kt)("inlineCode",{parentName:"li"},"Authorization")," header to the request and pass it to the ",(0,a.kt)("inlineCode",{parentName:"li"},"inputClient")," that we are transforming in this middleware."),(0,a.kt)("li",{parentName:"ol"},"This function is actually the ",(0,a.kt)("em",{parentName:"li"},"exact same")," as the function for the middleware we implemented above. The only differences are that this apply method accepts a ",(0,a.kt)("inlineCode",{parentName:"li"},"bearerToken")," as a parameter and returns a function on ",(0,a.kt)("inlineCode",{parentName:"li"},"Client")," instead of ",(0,a.kt)("inlineCode",{parentName:"li"},"HttpApp"),". The provided ",(0,a.kt)("inlineCode",{parentName:"li"},"bearerToken")," is what we will add into the ",(0,a.kt)("inlineCode",{parentName:"li"},"Authorization")," header when applicable.")),(0,a.kt)("h4",{id:"simplerestjsonbuilder"},"SimpleRestJsonBuilder"),(0,a.kt)("p",null,"As above, we now just need to wire our middleware into our actual implementation. Here we are constructing a client and specifying the middleware we just defined."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-scala"},'def apply(http4sClient: Client[IO]): Resource[IO, HelloWorldAuthService[IO]] =\n SimpleRestJsonBuilder(HelloWorldAuthService)\n .client(http4sClient)\n .uri(Uri.unsafeFromString("http://localhost:9000"))\n .middleware(Middleware("my-token")) // creating our middleware here\n .resource\n')),(0,a.kt)("h2",{id:"conclusion"},"Conclusion"),(0,a.kt)("p",null,"Once again, if you want to see the ",(0,a.kt)("strong",{parentName:"p"},"full code")," examples of the above, you can find them ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/disneystreaming/smithy4s/blob/8cb01fd92d65f6e4ec515fccb3677cffe6a1093b/modules/guides/src/smithy4s/guides/"},"here"),"."),(0,a.kt)("p",null,"Hopefully this guide gives you a good idea of how you can create a middleware that takes your smithy specification into account. This guide shows a very simple use case of what is possible with a middleware like this. If you have a more advanced use case, you can use this guide as a reference and as always you can reach out to us for insight or help."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/49bfe7c0.81f5549d.js b/assets/js/49bfe7c0.3ece230e.js similarity index 99% rename from assets/js/49bfe7c0.81f5549d.js rename to assets/js/49bfe7c0.3ece230e.js index 260f777ff..e14e06417 100644 --- a/assets/js/49bfe7c0.81f5549d.js +++ b/assets/js/49bfe7c0.3ece230e.js @@ -1 +1 @@ -"use strict";(self.webpackChunksmithy4s=self.webpackChunksmithy4s||[]).push([[2298],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>h});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var l=r.createContext({}),p=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},c=function(e){var t=p(e.components);return r.createElement(l.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),u=p(n),d=a,h=u["".concat(l,".").concat(d)]||u[d]||m[d]||o;return n?r.createElement(h,i(i({ref:t},c),{},{components:n})):r.createElement(h,i({ref:t},c))}));function h(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,i=new Array(o);i[0]=d;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[u]="string"==typeof e?e:a,i[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>m,frontMatter:()=>o,metadata:()=>s,toc:()=>p});var r=n(7462),a=(n(7294),n(3905));const o={sidebar_label:"Extracting Request Info",title:"Extracting Request Information"},i=void 0,s={unversionedId:"guides/extract-request-info",id:"guides/extract-request-info",title:"Extracting Request Information",description:"There are times where the implementation of your route handlers may require more information from the underlying http4s request.",source:"@site/../docs/target/jvm-2.13/mdoc/06-guides/extract-request-info.md",sourceDirName:"06-guides",slug:"/guides/extract-request-info",permalink:"/smithy4s/docs/guides/extract-request-info",draft:!1,editUrl:"https://github.com/disneystreaming/smithy4s/edit/main/modules/docs/src/06-guides/extract-request-info.md",tags:[],version:"current",frontMatter:{sidebar_label:"Extracting Request Info",title:"Extracting Request Information"},sidebar:"tutorialSidebar",previous:{title:"Endpoint Specific Middleware",permalink:"/smithy4s/docs/guides/endpoint-middleware"},next:{title:"Model preprocessing",permalink:"/smithy4s/docs/guides/model-preprocessing"}},l={},p=[{value:"What is IOLocal?",id:"what-is-iolocal",level:2},{value:"Example Implementation",id:"example-implementation",level:2},{value:"Smithy Spec",id:"smithy-spec",level:3},{value:"Service Implementation",id:"service-implementation",level:3},{value:"Middleware",id:"middleware",level:3},{value:"Wiring it Together",id:"wiring-it-together",level:3},{value:"Testing it out",id:"testing-it-out",level:3},{value:"Alternative Methods",id:"alternative-methods",level:2}],c={toc:p},u="wrapper";function m(e){let{components:t,...o}=e;return(0,a.kt)(u,(0,r.Z)({},c,o,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"There are times where the implementation of your route handlers may require more information from the underlying http4s request.\nYou may want to store the raw request, check the request body against an HMAC value, pass along header values for tracing spans, etc."),(0,a.kt)("p",null,"When possible, the implementation of things like this should be isolated to middleware and not passed into the route handlers themselves.\nHowever, there are times where this isn't possible. This guide shows you how to implement a middleware that uses ",(0,a.kt)("inlineCode",{parentName:"p"},"IOLocal")," to pass the value\nof several headers from the request into the smithy4s route handlers."),(0,a.kt)("h2",{id:"what-is-iolocal"},"What is IOLocal?"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://github.com/typelevel/cats-effect/blob/series/3.x/core/shared/src/main/scala/cats/effect/IOLocal.scala"},"IOLocal"),"\nis a construct that allows for sharing context across the scope of a ",(0,a.kt)("inlineCode",{parentName:"p"},"Fiber"),". This means it allows you to get and set some value ",(0,a.kt)("inlineCode",{parentName:"p"},"A")," in the ",(0,a.kt)("inlineCode",{parentName:"p"},"IOLocal"),".\nThis value will be accessible across the current ",(0,a.kt)("inlineCode",{parentName:"p"},"Fiber"),". As a ",(0,a.kt)("inlineCode",{parentName:"p"},"Fiber")," is forked into new fibers, the value of ",(0,a.kt)("inlineCode",{parentName:"p"},"A")," is carried over to the new ",(0,a.kt)("inlineCode",{parentName:"p"},"Fiber"),".\nHowever, the new ",(0,a.kt)("inlineCode",{parentName:"p"},"Fiber")," will not be able to update the value kept on its parent or sibling fibers."),(0,a.kt)("p",null,"This diagram, adapted from the ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/typelevel/cats-effect/blob/series/3.x/core/shared/src/main/scala/cats/effect/IOLocal.scala"},"IOLocal docs"),", illustrates this well:"),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"IOLocal flow chart",src:n(4386).Z,width:"515",height:"320"})),(0,a.kt)("h2",{id:"example-implementation"},"Example Implementation"),(0,a.kt)("h3",{id:"smithy-spec"},"Smithy Spec"),(0,a.kt)("p",null,"For this example, we are going to be working with the following smithy specification (taken from ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/disneystreaming/smithy4s/blob/9f2dbcbd29b4dbd35792fa40e423a6395ae3f9e6/sampleSpecs/hello.smithy"},"smithy4s repo"),"):"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-kotlin"},'$version: "2"\n\nnamespace smithy4s.example.hello\n\nuse alloy#simpleRestJson\n\n@simpleRestJson\n@tags(["testServiceTag"])\nservice HelloWorldService {\n version: "1.0.0",\n // Indicates that all operations in `HelloWorldService`,\n // here limited to Hello, can return `GenericServerError`.\n errors: [GenericServerError, SpecificServerError],\n operations: [Hello]\n}\n\n@error("server")\n@httpError(500)\nstructure GenericServerError {\n message: String\n}\n\n@error("server")\n@httpError(599)\nstructure SpecificServerError {\n message: String\n}\n\n@http(method: "POST", uri: "/{name}", code: 200)\n@tags(["testOperationTag"])\noperation Hello {\n input: Person,\n output: Greeting\n}\n\n\nstructure Person {\n @httpLabel\n @required\n name: String,\n\n @httpQuery("town")\n town: String\n}\n\nstructure Greeting {\n @required\n message: String\n}\n')),(0,a.kt)("p",null,"See our ",(0,a.kt)("a",{parentName:"p",href:"/smithy4s/docs/overview/intro"},"getting started documentation")," for instructions on how to use this specification to generate scala code."),(0,a.kt)("h3",{id:"service-implementation"},"Service Implementation"),(0,a.kt)("p",null,"Let's start by creating a case class that we will use to hold the value of some headers from our request."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-scala"},"case class RequestInfo(contentType: String, userAgent: String)\n")),(0,a.kt)("p",null,"This class will give us a spot to place the ",(0,a.kt)("inlineCode",{parentName:"p"},"Content-Type")," and ",(0,a.kt)("inlineCode",{parentName:"p"},"User-Agent")," headers, respectively. These are just shown\nas an example. We could instead pass any other header or part of the request."),(0,a.kt)("p",null,"From here, we can implement the ",(0,a.kt)("inlineCode",{parentName:"p"},"HelloWorldService")," interface that smithy4s generated from the specification above."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-scala"},'import smithy4s.example.hello._\nimport cats.effect.IO\nimport cats.effect.IOLocal\n\nfinal class HelloWorldServiceImpl(requestInfo: IO[RequestInfo]) extends HelloWorldService[IO] {\n def hello(name: String, town: Option[String]): IO[Greeting] =\n requestInfo.flatMap { reqInfo: RequestInfo =>\n IO.println("REQUEST_INFO: " + reqInfo)\n .as(Greeting(s"Hello, $name"))\n }\n}\n')),(0,a.kt)("p",null,"This is a basic implementation that, in addition to returning a ",(0,a.kt)("inlineCode",{parentName:"p"},"Greeting"),", prints the ",(0,a.kt)("inlineCode",{parentName:"p"},"RequestInfo")," out to the console.\nNote that it is getting the ",(0,a.kt)("inlineCode",{parentName:"p"},"RequestInfo")," from the ",(0,a.kt)("inlineCode",{parentName:"p"},"IO[RequestInfo]")," that is being passed in as a constructor parameter. This ",(0,a.kt)("inlineCode",{parentName:"p"},"IO"),"\nwill be created using the same ",(0,a.kt)("inlineCode",{parentName:"p"},"IOLocal")," instance is passed to our middleware implementation.\nThat way, the middleware can set the ",(0,a.kt)("inlineCode",{parentName:"p"},"RequestInfo")," value that we are reading here."),(0,a.kt)("h3",{id:"middleware"},"Middleware"),(0,a.kt)("p",null,"Below is the middleware implementation. It extracts the ",(0,a.kt)("inlineCode",{parentName:"p"},"Content-Type")," and ",(0,a.kt)("inlineCode",{parentName:"p"},"User-Agent")," headers and passes them along in the ",(0,a.kt)("inlineCode",{parentName:"p"},"IOLocal"),"\ninstance it is provided."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-scala"},'import cats.data._\nimport org.http4s.HttpRoutes\nimport cats.syntax.all._\nimport org.http4s.headers.{`Content-Type`, `User-Agent`}\n\nobject Middleware {\n\n def withRequestInfo(\n routes: HttpRoutes[IO],\n local: IOLocal[Option[RequestInfo]]\n ): HttpRoutes[IO] =\n HttpRoutes[IO] { request =>\n val requestInfo = for {\n contentType <- request.headers.get[`Content-Type`].map(ct => s"${ct.mediaType.mainType}/${ct.mediaType.subType}")\n userAgent <- request.headers.get[`User-Agent`].map(_.product.toString)\n } yield RequestInfo(\n contentType,\n userAgent\n )\n OptionT.liftF(local.set(requestInfo)) *> routes(request)\n }\n\n}\n')),(0,a.kt)("h3",{id:"wiring-it-together"},"Wiring it Together"),(0,a.kt)("p",null,"Now that we have our service implementation and our middleware, we need to combine them to create our application."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-scala"},'import cats.effect.kernel.Resource\n\nobject Routes {\n private val docs =\n smithy4s.http4s.swagger.docs[IO](smithy4s.example.hello.HelloWorldService)\n def getAll(local: IOLocal[Option[RequestInfo]]): Resource[IO, HttpRoutes[IO]] = {\n val getRequestInfo: IO[RequestInfo] = local.get.flatMap {\n case Some(value) => IO.pure(value)\n case None => IO.raiseError(new IllegalAccessException("Tried to access the value outside of the lifecycle of an http request"))\n }\n smithy4s.http4s.SimpleRestJsonBuilder\n .routes(new HelloWorldServiceImpl(getRequestInfo))\n .resource\n .map { routes =>\n Middleware.withRequestInfo(routes <+> docs, local)\n }\n }\n}\n')),(0,a.kt)("p",null,"Here we are creating our routes (with swagger docs) and passing them to our middleware. The result of applying the Middleware\nis our final routes."),(0,a.kt)("p",null,"We also turn our ",(0,a.kt)("inlineCode",{parentName:"p"},"IOLocal")," into an ",(0,a.kt)("inlineCode",{parentName:"p"},"IO[RequestInfo]")," for the ",(0,a.kt)("inlineCode",{parentName:"p"},"HelloWorldServiceImpl"),". We do this because the service implementation\ndoes not need to know that the value is coming from an ",(0,a.kt)("inlineCode",{parentName:"p"},"IOLocal")," or that the value is optional (since it will always be populated by\nour middleware). Doing it this way allows us to reduce the complexity in the service implementation."),(0,a.kt)("p",null,"Finally, we create our main class and construct the http4s server."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-scala"},'import cats.effect.IOApp\nimport com.comcast.ip4s._\nimport org.http4s.ember.server.EmberServerBuilder\n\nobject Main extends IOApp.Simple {\n def run: IO[Unit] = IOLocal(Option.empty[RequestInfo]).flatMap { local =>\n Routes\n .getAll(local)\n .flatMap { routes =>\n EmberServerBuilder\n .default[IO]\n .withHost(host"localhost")\n .withPort(port"9000")\n .withHttpApp(routes.orNotFound)\n .build\n }\n .useForever\n }\n}\n')),(0,a.kt)("p",null,"Notice that we create the ",(0,a.kt)("inlineCode",{parentName:"p"},"IOLocal")," with ",(0,a.kt)("inlineCode",{parentName:"p"},"Option.empty[RequestInfo]"),". This is because ",(0,a.kt)("inlineCode",{parentName:"p"},"IOLocal")," requires a value\nto be constructed. However, this value will never be used in practice. This is because we are setting the value in\nthe middleware on every request prior to the request being handled by our ",(0,a.kt)("inlineCode",{parentName:"p"},"HelloWorldService")," implementation."),(0,a.kt)("h3",{id:"testing-it-out"},"Testing it out"),(0,a.kt)("p",null,"With the above in place, we can run our application and test it out."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"curl -X 'POST' \\\n 'http://localhost:9000/Test' \\\n -H 'User-Agent: Chrome/103.0.0.0' \\\n -H 'Content-Type: application/json'\n")),(0,a.kt)("p",null,"Running this ",(0,a.kt)("inlineCode",{parentName:"p"},"curl")," will cause the following to print out to the console:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"REQUEST_INFO: RequestInfo(Some(application/json),Some(Chrome/103.0.0.0))\n")),(0,a.kt)("h2",{id:"alternative-methods"},"Alternative Methods"),(0,a.kt)("p",null,"If you are working with a tagless ",(0,a.kt)("inlineCode",{parentName:"p"},"F[_]")," rather than ",(0,a.kt)("inlineCode",{parentName:"p"},"IO")," directly, you may want to check out Chris Davenport's ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/davenverse/fiberlocal/"},"implementation\nof FiberLocal"),"."),(0,a.kt)("p",null,"You can also use ",(0,a.kt)("inlineCode",{parentName:"p"},"Kleisli")," to accomplish the same things we showed in this tutorial and you are welcome to do so if you prefer that.\nWe opted to show an example with ",(0,a.kt)("inlineCode",{parentName:"p"},"IOLocal")," since it allows users to use ",(0,a.kt)("inlineCode",{parentName:"p"},"IO")," directly, without monad transformers, which many\nusers will be more comfortable with. Similarly, you could use ",(0,a.kt)("inlineCode",{parentName:"p"},"Local")," from cats-mtl or probably a variety of other approaches.\nWe recommend you use whatever fits the best with your current application design."))}m.isMDXComponent=!0},4386:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/ioLocalDiagram-8b535a4e121c2cb02f518e0f0eccaac3.svg"}}]); \ No newline at end of file +"use strict";(self.webpackChunksmithy4s=self.webpackChunksmithy4s||[]).push([[2298],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>h});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var l=r.createContext({}),p=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},c=function(e){var t=p(e.components);return r.createElement(l.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),u=p(n),d=a,h=u["".concat(l,".").concat(d)]||u[d]||m[d]||o;return n?r.createElement(h,i(i({ref:t},c),{},{components:n})):r.createElement(h,i({ref:t},c))}));function h(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,i=new Array(o);i[0]=d;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[u]="string"==typeof e?e:a,i[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>m,frontMatter:()=>o,metadata:()=>s,toc:()=>p});var r=n(7462),a=(n(7294),n(3905));const o={sidebar_label:"Extracting Request Info",title:"Extracting Request Information"},i=void 0,s={unversionedId:"guides/extract-request-info",id:"guides/extract-request-info",title:"Extracting Request Information",description:"There are times where the implementation of your route handlers may require more information from the underlying http4s request.",source:"@site/../docs/target/jvm-2.13/mdoc/06-guides/extract-request-info.md",sourceDirName:"06-guides",slug:"/guides/extract-request-info",permalink:"/smithy4s/docs/guides/extract-request-info",draft:!1,editUrl:"https://github.com/disneystreaming/smithy4s/edit/main/modules/docs/src/06-guides/extract-request-info.md",tags:[],version:"current",frontMatter:{sidebar_label:"Extracting Request Info",title:"Extracting Request Information"},sidebar:"tutorialSidebar",previous:{title:"Endpoint Specific Middleware",permalink:"/smithy4s/docs/guides/endpoint-middleware"},next:{title:"Model preprocessing",permalink:"/smithy4s/docs/guides/model-preprocessing"}},l={},p=[{value:"What is IOLocal?",id:"what-is-iolocal",level:2},{value:"Example Implementation",id:"example-implementation",level:2},{value:"Smithy Spec",id:"smithy-spec",level:3},{value:"Service Implementation",id:"service-implementation",level:3},{value:"Middleware",id:"middleware",level:3},{value:"Wiring it Together",id:"wiring-it-together",level:3},{value:"Testing it out",id:"testing-it-out",level:3},{value:"Alternative Methods",id:"alternative-methods",level:2}],c={toc:p},u="wrapper";function m(e){let{components:t,...o}=e;return(0,a.kt)(u,(0,r.Z)({},c,o,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"There are times where the implementation of your route handlers may require more information from the underlying http4s request.\nYou may want to store the raw request, check the request body against an HMAC value, pass along header values for tracing spans, etc."),(0,a.kt)("p",null,"When possible, the implementation of things like this should be isolated to middleware and not passed into the route handlers themselves.\nHowever, there are times where this isn't possible. This guide shows you how to implement a middleware that uses ",(0,a.kt)("inlineCode",{parentName:"p"},"IOLocal")," to pass the value\nof several headers from the request into the smithy4s route handlers."),(0,a.kt)("h2",{id:"what-is-iolocal"},"What is IOLocal?"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://github.com/typelevel/cats-effect/blob/series/3.x/core/shared/src/main/scala/cats/effect/IOLocal.scala"},"IOLocal"),"\nis a construct that allows for sharing context across the scope of a ",(0,a.kt)("inlineCode",{parentName:"p"},"Fiber"),". This means it allows you to get and set some value ",(0,a.kt)("inlineCode",{parentName:"p"},"A")," in the ",(0,a.kt)("inlineCode",{parentName:"p"},"IOLocal"),".\nThis value will be accessible across the current ",(0,a.kt)("inlineCode",{parentName:"p"},"Fiber"),". As a ",(0,a.kt)("inlineCode",{parentName:"p"},"Fiber")," is forked into new fibers, the value of ",(0,a.kt)("inlineCode",{parentName:"p"},"A")," is carried over to the new ",(0,a.kt)("inlineCode",{parentName:"p"},"Fiber"),".\nHowever, the new ",(0,a.kt)("inlineCode",{parentName:"p"},"Fiber")," will not be able to update the value kept on its parent or sibling fibers."),(0,a.kt)("p",null,"This diagram, adapted from the ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/typelevel/cats-effect/blob/series/3.x/core/shared/src/main/scala/cats/effect/IOLocal.scala"},"IOLocal docs"),", illustrates this well:"),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"IOLocal flow chart",src:n(4386).Z,width:"515",height:"320"})),(0,a.kt)("h2",{id:"example-implementation"},"Example Implementation"),(0,a.kt)("h3",{id:"smithy-spec"},"Smithy Spec"),(0,a.kt)("p",null,"For this example, we are going to be working with the following smithy specification (taken from ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/disneystreaming/smithy4s/blob/8cb01fd92d65f6e4ec515fccb3677cffe6a1093b/sampleSpecs/hello.smithy"},"smithy4s repo"),"):"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-kotlin"},'$version: "2"\n\nnamespace smithy4s.example.hello\n\nuse alloy#simpleRestJson\n\n@simpleRestJson\n@tags(["testServiceTag"])\nservice HelloWorldService {\n version: "1.0.0",\n // Indicates that all operations in `HelloWorldService`,\n // here limited to Hello, can return `GenericServerError`.\n errors: [GenericServerError, SpecificServerError],\n operations: [Hello]\n}\n\n@error("server")\n@httpError(500)\nstructure GenericServerError {\n message: String\n}\n\n@error("server")\n@httpError(599)\nstructure SpecificServerError {\n message: String\n}\n\n@http(method: "POST", uri: "/{name}", code: 200)\n@tags(["testOperationTag"])\noperation Hello {\n input: Person,\n output: Greeting\n}\n\n\nstructure Person {\n @httpLabel\n @required\n name: String,\n\n @httpQuery("town")\n town: String\n}\n\nstructure Greeting {\n @required\n message: String\n}\n')),(0,a.kt)("p",null,"See our ",(0,a.kt)("a",{parentName:"p",href:"/smithy4s/docs/overview/intro"},"getting started documentation")," for instructions on how to use this specification to generate scala code."),(0,a.kt)("h3",{id:"service-implementation"},"Service Implementation"),(0,a.kt)("p",null,"Let's start by creating a case class that we will use to hold the value of some headers from our request."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-scala"},"case class RequestInfo(contentType: String, userAgent: String)\n")),(0,a.kt)("p",null,"This class will give us a spot to place the ",(0,a.kt)("inlineCode",{parentName:"p"},"Content-Type")," and ",(0,a.kt)("inlineCode",{parentName:"p"},"User-Agent")," headers, respectively. These are just shown\nas an example. We could instead pass any other header or part of the request."),(0,a.kt)("p",null,"From here, we can implement the ",(0,a.kt)("inlineCode",{parentName:"p"},"HelloWorldService")," interface that smithy4s generated from the specification above."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-scala"},'import smithy4s.example.hello._\nimport cats.effect.IO\nimport cats.effect.IOLocal\n\nfinal class HelloWorldServiceImpl(requestInfo: IO[RequestInfo]) extends HelloWorldService[IO] {\n def hello(name: String, town: Option[String]): IO[Greeting] =\n requestInfo.flatMap { reqInfo: RequestInfo =>\n IO.println("REQUEST_INFO: " + reqInfo)\n .as(Greeting(s"Hello, $name"))\n }\n}\n')),(0,a.kt)("p",null,"This is a basic implementation that, in addition to returning a ",(0,a.kt)("inlineCode",{parentName:"p"},"Greeting"),", prints the ",(0,a.kt)("inlineCode",{parentName:"p"},"RequestInfo")," out to the console.\nNote that it is getting the ",(0,a.kt)("inlineCode",{parentName:"p"},"RequestInfo")," from the ",(0,a.kt)("inlineCode",{parentName:"p"},"IO[RequestInfo]")," that is being passed in as a constructor parameter. This ",(0,a.kt)("inlineCode",{parentName:"p"},"IO"),"\nwill be created using the same ",(0,a.kt)("inlineCode",{parentName:"p"},"IOLocal")," instance is passed to our middleware implementation.\nThat way, the middleware can set the ",(0,a.kt)("inlineCode",{parentName:"p"},"RequestInfo")," value that we are reading here."),(0,a.kt)("h3",{id:"middleware"},"Middleware"),(0,a.kt)("p",null,"Below is the middleware implementation. It extracts the ",(0,a.kt)("inlineCode",{parentName:"p"},"Content-Type")," and ",(0,a.kt)("inlineCode",{parentName:"p"},"User-Agent")," headers and passes them along in the ",(0,a.kt)("inlineCode",{parentName:"p"},"IOLocal"),"\ninstance it is provided."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-scala"},'import cats.data._\nimport org.http4s.HttpRoutes\nimport cats.syntax.all._\nimport org.http4s.headers.{`Content-Type`, `User-Agent`}\n\nobject Middleware {\n\n def withRequestInfo(\n routes: HttpRoutes[IO],\n local: IOLocal[Option[RequestInfo]]\n ): HttpRoutes[IO] =\n HttpRoutes[IO] { request =>\n val requestInfo = for {\n contentType <- request.headers.get[`Content-Type`].map(ct => s"${ct.mediaType.mainType}/${ct.mediaType.subType}")\n userAgent <- request.headers.get[`User-Agent`].map(_.product.toString)\n } yield RequestInfo(\n contentType,\n userAgent\n )\n OptionT.liftF(local.set(requestInfo)) *> routes(request)\n }\n\n}\n')),(0,a.kt)("h3",{id:"wiring-it-together"},"Wiring it Together"),(0,a.kt)("p",null,"Now that we have our service implementation and our middleware, we need to combine them to create our application."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-scala"},'import cats.effect.kernel.Resource\n\nobject Routes {\n private val docs =\n smithy4s.http4s.swagger.docs[IO](smithy4s.example.hello.HelloWorldService)\n def getAll(local: IOLocal[Option[RequestInfo]]): Resource[IO, HttpRoutes[IO]] = {\n val getRequestInfo: IO[RequestInfo] = local.get.flatMap {\n case Some(value) => IO.pure(value)\n case None => IO.raiseError(new IllegalAccessException("Tried to access the value outside of the lifecycle of an http request"))\n }\n smithy4s.http4s.SimpleRestJsonBuilder\n .routes(new HelloWorldServiceImpl(getRequestInfo))\n .resource\n .map { routes =>\n Middleware.withRequestInfo(routes <+> docs, local)\n }\n }\n}\n')),(0,a.kt)("p",null,"Here we are creating our routes (with swagger docs) and passing them to our middleware. The result of applying the Middleware\nis our final routes."),(0,a.kt)("p",null,"We also turn our ",(0,a.kt)("inlineCode",{parentName:"p"},"IOLocal")," into an ",(0,a.kt)("inlineCode",{parentName:"p"},"IO[RequestInfo]")," for the ",(0,a.kt)("inlineCode",{parentName:"p"},"HelloWorldServiceImpl"),". We do this because the service implementation\ndoes not need to know that the value is coming from an ",(0,a.kt)("inlineCode",{parentName:"p"},"IOLocal")," or that the value is optional (since it will always be populated by\nour middleware). Doing it this way allows us to reduce the complexity in the service implementation."),(0,a.kt)("p",null,"Finally, we create our main class and construct the http4s server."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-scala"},'import cats.effect.IOApp\nimport com.comcast.ip4s._\nimport org.http4s.ember.server.EmberServerBuilder\n\nobject Main extends IOApp.Simple {\n def run: IO[Unit] = IOLocal(Option.empty[RequestInfo]).flatMap { local =>\n Routes\n .getAll(local)\n .flatMap { routes =>\n EmberServerBuilder\n .default[IO]\n .withHost(host"localhost")\n .withPort(port"9000")\n .withHttpApp(routes.orNotFound)\n .build\n }\n .useForever\n }\n}\n')),(0,a.kt)("p",null,"Notice that we create the ",(0,a.kt)("inlineCode",{parentName:"p"},"IOLocal")," with ",(0,a.kt)("inlineCode",{parentName:"p"},"Option.empty[RequestInfo]"),". This is because ",(0,a.kt)("inlineCode",{parentName:"p"},"IOLocal")," requires a value\nto be constructed. However, this value will never be used in practice. This is because we are setting the value in\nthe middleware on every request prior to the request being handled by our ",(0,a.kt)("inlineCode",{parentName:"p"},"HelloWorldService")," implementation."),(0,a.kt)("h3",{id:"testing-it-out"},"Testing it out"),(0,a.kt)("p",null,"With the above in place, we can run our application and test it out."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"curl -X 'POST' \\\n 'http://localhost:9000/Test' \\\n -H 'User-Agent: Chrome/103.0.0.0' \\\n -H 'Content-Type: application/json'\n")),(0,a.kt)("p",null,"Running this ",(0,a.kt)("inlineCode",{parentName:"p"},"curl")," will cause the following to print out to the console:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"REQUEST_INFO: RequestInfo(Some(application/json),Some(Chrome/103.0.0.0))\n")),(0,a.kt)("h2",{id:"alternative-methods"},"Alternative Methods"),(0,a.kt)("p",null,"If you are working with a tagless ",(0,a.kt)("inlineCode",{parentName:"p"},"F[_]")," rather than ",(0,a.kt)("inlineCode",{parentName:"p"},"IO")," directly, you may want to check out Chris Davenport's ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/davenverse/fiberlocal/"},"implementation\nof FiberLocal"),"."),(0,a.kt)("p",null,"You can also use ",(0,a.kt)("inlineCode",{parentName:"p"},"Kleisli")," to accomplish the same things we showed in this tutorial and you are welcome to do so if you prefer that.\nWe opted to show an example with ",(0,a.kt)("inlineCode",{parentName:"p"},"IOLocal")," since it allows users to use ",(0,a.kt)("inlineCode",{parentName:"p"},"IO")," directly, without monad transformers, which many\nusers will be more comfortable with. Similarly, you could use ",(0,a.kt)("inlineCode",{parentName:"p"},"Local")," from cats-mtl or probably a variety of other approaches.\nWe recommend you use whatever fits the best with your current application design."))}m.isMDXComponent=!0},4386:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/ioLocalDiagram-8b535a4e121c2cb02f518e0f0eccaac3.svg"}}]); \ No newline at end of file diff --git a/assets/js/4d02aadf.2872aa09.js b/assets/js/4d02aadf.11c7e644.js similarity index 99% rename from assets/js/4d02aadf.2872aa09.js rename to assets/js/4d02aadf.11c7e644.js index 4d20d2332..478c2e787 100644 --- a/assets/js/4d02aadf.2872aa09.js +++ b/assets/js/4d02aadf.11c7e644.js @@ -1 +1 @@ -"use strict";(self.webpackChunksmithy4s=self.webpackChunksmithy4s||[]).push([[4444],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>h});var o=n(7294);function s(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function i(e){for(var t=1;t=0||(s[n]=e[n]);return s}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(s[n]=e[n])}return s}var l=o.createContext({}),p=function(e){var t=o.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},c=function(e){var t=p(e.components);return o.createElement(l.Provider,{value:t},e.children)},m="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},d=o.forwardRef((function(e,t){var n=e.components,s=e.mdxType,r=e.originalType,l=e.parentName,c=a(e,["components","mdxType","originalType","parentName"]),m=p(n),d=s,h=m["".concat(l,".").concat(d)]||m[d]||u[d]||r;return n?o.createElement(h,i(i({ref:t},c),{},{components:n})):o.createElement(h,i({ref:t},c))}));function h(e,t){var n=arguments,s=t&&t.mdxType;if("string"==typeof e||s){var r=n.length,i=new Array(r);i[0]=d;var a={};for(var l in t)hasOwnProperty.call(t,l)&&(a[l]=t[l]);a.originalType=e,a[m]="string"==typeof e?e:s,i[1]=a;for(var p=2;p{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>u,frontMatter:()=>r,metadata:()=>a,toc:()=>p});var o=n(7462),s=(n(7294),n(3905));const r={sidebar_label:"Compliance Tests",title:"Compliance Tests"},i=void 0,a={unversionedId:"protocols/compliance-tests",id:"protocols/compliance-tests",title:"Compliance Tests",description:"The Smithy prelude has support for compliance testing for services that use HTTP as their protocol. It is built on top of regular traits, you can read more about it over here.",source:"@site/../docs/target/jvm-2.13/mdoc/03-protocols/05-compliance-tests.md",sourceDirName:"03-protocols",slug:"/protocols/compliance-tests",permalink:"/smithy4s/docs/protocols/compliance-tests",draft:!1,editUrl:"https://github.com/disneystreaming/smithy4s/edit/main/modules/docs/src/03-protocols/05-compliance-tests.md",tags:[],version:"current",sidebarPosition:5,frontMatter:{sidebar_label:"Compliance Tests",title:"Compliance Tests"},sidebar:"tutorialSidebar",previous:{title:"Openapi",permalink:"/smithy4s/docs/protocols/simple-rest-json/openapi"},next:{title:"Deriving CLIs",permalink:"/smithy4s/docs/protocols/deriving-cli"}},l={},p=[{value:"Example specification",id:"example-specification",level:2},{value:"Testing the protocol",id:"testing-the-protocol",level:2}],c={toc:p},m="wrapper";function u(e){let{components:t,...n}=e;return(0,s.kt)(m,(0,o.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,s.kt)("p",null,"The Smithy prelude has support for compliance testing for services that use ",(0,s.kt)("inlineCode",{parentName:"p"},"HTTP")," as their protocol. It is built on top of regular traits, you can read more about it ",(0,s.kt)("a",{parentName:"p",href:"https://awslabs.github.io/smithy/2.0/additional-specs/http-protocol-compliance-tests.html"},"over here"),"."),(0,s.kt)("p",null,"Basically, you annotate operations and/or structures (that depends on the type of test being defined) and protocol implementors can generate tests cases to ensure their implementation behaves correctly."),(0,s.kt)("p",null,"Smithy4s publishes a module that you can use to write compliance test if you're implementing a protocol. Add the following to your dependencies if you use ",(0,s.kt)("inlineCode",{parentName:"p"},"sbt"),":"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-scala"},'\nimport smithy4s.codegen.BuildInfo._\n\nlibraryDependencies ++= Seq(\n "com.disneystreaming.smithy4s" %% "smithy4s-compliance-tests" % smithy4sVersion.value\n)\n')),(0,s.kt)("p",null,"If you use ",(0,s.kt)("inlineCode",{parentName:"p"},"mill"),":"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-scala"},'import smithy4s.codegen.BuildInfo._\n\ndef smithy4sIvyDeps = Agg(\n ivy"software.amazon.smithy:smithy-protocol-test-traits:$smithyVersion"\n)\n\ndef ivyDeps = Agg(\n ivy"com.disneystreaming.smithy4s::smithy4s-compliance-tests:${smithy4sVersion()}"\n)\n')),(0,s.kt)("p",null,"The rest of this document will demonstrate how to write a Smithy specification that specify HTTP compliance tests, and then how to use the module mentioned above to run the tests."),(0,s.kt)("p",null,(0,s.kt)("em",{parentName:"p"},"Note: currently, only ",(0,s.kt)("inlineCode",{parentName:"em"},"httprequesttests-trait")," are supported. other traits support will be integrated soon.")),(0,s.kt)("h2",{id:"example-specification"},"Example specification"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-kotlin"},'$version: "2"\n\nnamespace smithy4s.example.test\n\nuse smithy.test#httpRequestTests\nuse smithy.test#httpResponseTests\nuse alloy#simpleRestJson\n\n@simpleRestJson\nservice HelloService {\n operations: [SayHello, Listen, TestPath]\n}\n\n@http(method: "POST", uri: "/")\n@httpRequestTests([\n {\n id: "say_hello",\n protocol: simpleRestJson,\n params: {\n "greeting": "Hi",\n "name": "Teddy",\n "query": "Hello there"\n },\n method: "POST",\n uri: "/",\n queryParams: [\n "Hi=Hello%20there"\n ],\n headers: {\n "X-Greeting": "Hi",\n },\n body: "{\\"name\\":\\"Teddy\\"}",\n bodyMediaType: "application/json"\n }\n])\n@httpResponseTests([\n {\n id: "say_hello"\n protocol: simpleRestJson\n params: { payload: { result: "Hello!" }, header1: "V1" }\n body: "{\\"result\\":\\"Hello!\\"}"\n headers: { "X-H1": "V1"}\n code: 200\n }\n])\noperation SayHello {\n input: SayHelloInput,\n output: SayHelloOutput\n errors: [SimpleError, ComplexError]\n}\n\n@input\nstructure SayHelloInput {\n @httpHeader("X-Greeting")\n greeting: String,\n\n @httpQuery("Hi")\n query: String,\n\n name: String\n}\n\nstructure SayHelloOutput {\n @required\n @httpPayload\n payload: SayHelloPayload\n\n @required\n @httpHeader("X-H1")\n header1: String\n}\nstructure SayHelloPayload {\n @required\n result: String\n}\n\n\n@http(method: "GET", uri: "/listen")\n@readonly\n@httpRequestTests([\n {\n id: "listen",\n protocol: simpleRestJson,\n method: "GET",\n uri: "/listen"\n }\n])\noperation Listen { }\n\n@http(method: "GET", uri: "/test-path/{path}")\n@readonly\n@httpRequestTests([\n {\n id: "TestPath",\n protocol: simpleRestJson,\n method: "GET",\n uri: "/test-path/sameValue"\n params: { path: "sameValue" }\n }\n])\noperation TestPath {\n input := {\n @httpLabel\n @required\n path: String\n }\n}\n\n// The following shapes are used by the documentation\n@simpleRestJson\nservice HelloWorldService {\n version: "1.0.0",\n operations: [Hello]\n}\n@httpRequestTests([\n {\n id: "helloSuccess"\n protocol: simpleRestJson\n method: "POST"\n uri: "/World"\n params: { name: "World" }\n },\n {\n id: "helloFails"\n protocol: simpleRestJson\n method: "POST"\n uri: "/fail"\n params: { name: "World" }\n }\n])\n@http(method: "POST", uri: "/{name}", code: 200)\noperation Hello {\n input := {\n @httpLabel\n @required\n name: String\n },\n output := {\n @required\n message: String\n }\n}\n\n@httpResponseTests([\n {\n id: "simple_error"\n protocol: simpleRestJson\n params: { expected: -1 }\n code: 400\n body: "{\\"expected\\":-1}"\n bodyMediaType: "application/json"\n requireHeaders: ["X-Error-Type"]\n }\n])\n@error("client")\nstructure SimpleError {\n @required\n expected: Integer\n}\n@httpResponseTests([\n {\n id: "complex_error"\n protocol: simpleRestJson\n params: { value: -1, message: "some error message", details: { date: 123, location: "NYC"} }\n code: 504\n body: "{\\"value\\":-1,\\"message\\":\\"some error message\\",\\"details\\":{\\"date\\":123,\\"location\\":\\"NYC\\"}}"\n bodyMediaType: "application/json"\n requireHeaders: ["X-Error-Type"]\n },\n {\n id: "complex_error_no_details"\n protocol: simpleRestJson\n params: { value: -1, message: "some error message" }\n code: 504\n body: "{\\"value\\":-1,\\"message\\":\\"some error message\\"}"\n bodyMediaType: "application/json"\n requireHeaders: ["X-Error-Type"]\n }\n])\n@error("server")\n@httpError(504)\nstructure ComplexError {\n @required\n value: Integer\n @required\n message: String\n details: ErrorDetails\n}\n\nstructure ErrorDetails {\n @required\n @timestampFormat("epoch-seconds")\n date: Timestamp\n @required\n location: String\n}\n')),(0,s.kt)("p",null,"We have a very simple specification: one operation with basic input and output shapes. We've added a ",(0,s.kt)("inlineCode",{parentName:"p"},"httpRequestTests")," to define a compliance test for protocol implementors."),(0,s.kt)("h2",{id:"testing-the-protocol"},"Testing the protocol"),(0,s.kt)("p",null,"The service in the specification is annotated with the ",(0,s.kt)("inlineCode",{parentName:"p"},"alloy#simpleRestJson")," protocol definition. We'll use the ",(0,s.kt)("inlineCode",{parentName:"p"},"compliance-tests")," module to make sure this protocol can handle such an operation."),(0,s.kt)("p",null,(0,s.kt)("em",{parentName:"p"},"Note: the following code and the ",(0,s.kt)("inlineCode",{parentName:"em"},"compliance-tests")," module do not depend on a specific test framework. If you want to hook it into your test framework, it is easy to do so but it's outside the scope of this document. Refer to ",(0,s.kt)("a",{parentName:"em",href:"https://github.com/disneystreaming/smithy4s/blob/9f2dbcbd29b4dbd35792fa40e423a6395ae3f9e6/modules/compliance-tests/test/src/smithy4s/compliancetests/WeaverComplianceTest.scala"},"this example")," to see how we did it for ",(0,s.kt)("inlineCode",{parentName:"em"},"Weaver")," in this project.")),(0,s.kt)("p",null,"First, some imports:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-scala"},"import cats.effect._\nimport org.http4s._\nimport org.http4s.client.Client\nimport smithy4s.compliancetests._\nimport smithy4s.example.test._\nimport smithy4s.http.HttpMediaType\nimport smithy4s.http4s._\nimport smithy4s.kinds._\nimport smithy4s.Service\nimport smithy4s.schema.Schema\n")),(0,s.kt)("p",null,"Then, you can create and instance of ",(0,s.kt)("inlineCode",{parentName:"p"},"ClientHttpComplianceTestCase")," and/or ",(0,s.kt)("inlineCode",{parentName:"p"},"ServerHttpComplianceTestCase")," while selecting the protocol to use and the service to test:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-scala"},'object SimpleRestJsonIntegration extends Router[IO] with ReverseRouter[IO] {\n type Protocol = alloy.SimpleRestJson\n val protocolTag = alloy.SimpleRestJson\n\n def expectedResponseType(schema: Schema[_]) = HttpMediaType("application/json")\n\n def routes[Alg[_[_, _, _, _, _]]](\n impl: FunctorAlgebra[Alg, IO]\n )(implicit service: Service[Alg]): Resource[IO, HttpRoutes[IO]] =\n SimpleRestJsonBuilder(service).routes(impl).resource\n\n def reverseRoutes[Alg[_[_, _, _, _, _]]](app: HttpApp[IO],testHost: Option[String] = None)(implicit\n service: Service[Alg]\n ): Resource[IO, FunctorAlgebra[Alg, IO]] = {\n import org.http4s.implicits._\n val baseUri = uri"http://localhost/"\n val suppliedHost = testHost.map(host => Uri.unsafeFromString(s"http://$host"))\n SimpleRestJsonBuilder(service)\n .client(Client.fromHttpApp(app))\n .uri(suppliedHost.getOrElse(baseUri))\n .resource\n }\n }\n\nval tests: List[ComplianceTest[IO]] = HttpProtocolCompliance\n .clientAndServerTests(SimpleRestJsonIntegration, HelloWorldService)\n')),(0,s.kt)("p",null,"Now, you can iterate over the test cases and do what you want. This is where you would hook in the test framework of your choice, but in the following example, we're just going to print the result:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-scala"},'import cats.syntax.traverse._\nimport cats.effect.unsafe.implicits.global\n\nval runTests: IO[List[String]] = tests\n .map { tc =>\n tc.run.map(_.toEither).map {\n case Left(value) =>\n s"Failed ${tc.show} with the following message: $value"\n case Right(_) => s"Success ${tc.show}"\n\n }\n }\n .sequence\n')),(0,s.kt)("p",null,"Will produce the following when executed:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre"},'Success smithy4s.example.test#Hello(client|Request): helloSuccess\nFailed smithy4s.example.test#Hello(client|Request): helloFails with the following message: NonEmptyList(path test : the result value: \x1b[33mVector\x1b[39m(\x1b[32m"World"\x1b[39m) was not equal to the expected TestCase value \x1b[33mVector\x1b[39m(\x1b[32m"fail"\x1b[39m).)\nSuccess smithy4s.example.test#Hello(server|Request): helloSuccess\nFailed smithy4s.example.test#Hello(server|Request): helloFails with the following message: NonEmptyList( the result value: \x1b[33mHelloInput\x1b[39m(name = \x1b[32m"fail"\x1b[39m) was not equal to the expected TestCase value \x1b[33mHelloInput\x1b[39m(name = \x1b[32m"World"\x1b[39m).)\n')))}u.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunksmithy4s=self.webpackChunksmithy4s||[]).push([[4444],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>h});var o=n(7294);function s(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function i(e){for(var t=1;t=0||(s[n]=e[n]);return s}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(s[n]=e[n])}return s}var l=o.createContext({}),p=function(e){var t=o.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},c=function(e){var t=p(e.components);return o.createElement(l.Provider,{value:t},e.children)},m="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},d=o.forwardRef((function(e,t){var n=e.components,s=e.mdxType,r=e.originalType,l=e.parentName,c=a(e,["components","mdxType","originalType","parentName"]),m=p(n),d=s,h=m["".concat(l,".").concat(d)]||m[d]||u[d]||r;return n?o.createElement(h,i(i({ref:t},c),{},{components:n})):o.createElement(h,i({ref:t},c))}));function h(e,t){var n=arguments,s=t&&t.mdxType;if("string"==typeof e||s){var r=n.length,i=new Array(r);i[0]=d;var a={};for(var l in t)hasOwnProperty.call(t,l)&&(a[l]=t[l]);a.originalType=e,a[m]="string"==typeof e?e:s,i[1]=a;for(var p=2;p{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>u,frontMatter:()=>r,metadata:()=>a,toc:()=>p});var o=n(7462),s=(n(7294),n(3905));const r={sidebar_label:"Compliance Tests",title:"Compliance Tests"},i=void 0,a={unversionedId:"protocols/compliance-tests",id:"protocols/compliance-tests",title:"Compliance Tests",description:"The Smithy prelude has support for compliance testing for services that use HTTP as their protocol. It is built on top of regular traits, you can read more about it over here.",source:"@site/../docs/target/jvm-2.13/mdoc/03-protocols/05-compliance-tests.md",sourceDirName:"03-protocols",slug:"/protocols/compliance-tests",permalink:"/smithy4s/docs/protocols/compliance-tests",draft:!1,editUrl:"https://github.com/disneystreaming/smithy4s/edit/main/modules/docs/src/03-protocols/05-compliance-tests.md",tags:[],version:"current",sidebarPosition:5,frontMatter:{sidebar_label:"Compliance Tests",title:"Compliance Tests"},sidebar:"tutorialSidebar",previous:{title:"Openapi",permalink:"/smithy4s/docs/protocols/simple-rest-json/openapi"},next:{title:"Deriving CLIs",permalink:"/smithy4s/docs/protocols/deriving-cli"}},l={},p=[{value:"Example specification",id:"example-specification",level:2},{value:"Testing the protocol",id:"testing-the-protocol",level:2}],c={toc:p},m="wrapper";function u(e){let{components:t,...n}=e;return(0,s.kt)(m,(0,o.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,s.kt)("p",null,"The Smithy prelude has support for compliance testing for services that use ",(0,s.kt)("inlineCode",{parentName:"p"},"HTTP")," as their protocol. It is built on top of regular traits, you can read more about it ",(0,s.kt)("a",{parentName:"p",href:"https://awslabs.github.io/smithy/2.0/additional-specs/http-protocol-compliance-tests.html"},"over here"),"."),(0,s.kt)("p",null,"Basically, you annotate operations and/or structures (that depends on the type of test being defined) and protocol implementors can generate tests cases to ensure their implementation behaves correctly."),(0,s.kt)("p",null,"Smithy4s publishes a module that you can use to write compliance test if you're implementing a protocol. Add the following to your dependencies if you use ",(0,s.kt)("inlineCode",{parentName:"p"},"sbt"),":"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-scala"},'\nimport smithy4s.codegen.BuildInfo._\n\nlibraryDependencies ++= Seq(\n "com.disneystreaming.smithy4s" %% "smithy4s-compliance-tests" % smithy4sVersion.value\n)\n')),(0,s.kt)("p",null,"If you use ",(0,s.kt)("inlineCode",{parentName:"p"},"mill"),":"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-scala"},'import smithy4s.codegen.BuildInfo._\n\ndef smithy4sIvyDeps = Agg(\n ivy"software.amazon.smithy:smithy-protocol-test-traits:$smithyVersion"\n)\n\ndef ivyDeps = Agg(\n ivy"com.disneystreaming.smithy4s::smithy4s-compliance-tests:${smithy4sVersion()}"\n)\n')),(0,s.kt)("p",null,"The rest of this document will demonstrate how to write a Smithy specification that specify HTTP compliance tests, and then how to use the module mentioned above to run the tests."),(0,s.kt)("p",null,(0,s.kt)("em",{parentName:"p"},"Note: currently, only ",(0,s.kt)("inlineCode",{parentName:"em"},"httprequesttests-trait")," are supported. other traits support will be integrated soon.")),(0,s.kt)("h2",{id:"example-specification"},"Example specification"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-kotlin"},'$version: "2"\n\nnamespace smithy4s.example.test\n\nuse smithy.test#httpRequestTests\nuse smithy.test#httpResponseTests\nuse alloy#simpleRestJson\n\n@simpleRestJson\nservice HelloService {\n operations: [SayHello, Listen, TestPath]\n}\n\n@http(method: "POST", uri: "/")\n@httpRequestTests([\n {\n id: "say_hello",\n protocol: simpleRestJson,\n params: {\n "greeting": "Hi",\n "name": "Teddy",\n "query": "Hello there"\n },\n method: "POST",\n uri: "/",\n queryParams: [\n "Hi=Hello%20there"\n ],\n headers: {\n "X-Greeting": "Hi",\n },\n body: "{\\"name\\":\\"Teddy\\"}",\n bodyMediaType: "application/json"\n }\n])\n@httpResponseTests([\n {\n id: "say_hello"\n protocol: simpleRestJson\n params: { payload: { result: "Hello!" }, header1: "V1" }\n body: "{\\"result\\":\\"Hello!\\"}"\n headers: { "X-H1": "V1"}\n code: 200\n }\n])\noperation SayHello {\n input: SayHelloInput,\n output: SayHelloOutput\n errors: [SimpleError, ComplexError]\n}\n\n@input\nstructure SayHelloInput {\n @httpHeader("X-Greeting")\n greeting: String,\n\n @httpQuery("Hi")\n query: String,\n\n name: String\n}\n\nstructure SayHelloOutput {\n @required\n @httpPayload\n payload: SayHelloPayload\n\n @required\n @httpHeader("X-H1")\n header1: String\n}\nstructure SayHelloPayload {\n @required\n result: String\n}\n\n\n@http(method: "GET", uri: "/listen")\n@readonly\n@httpRequestTests([\n {\n id: "listen",\n protocol: simpleRestJson,\n method: "GET",\n uri: "/listen"\n }\n])\noperation Listen { }\n\n@http(method: "GET", uri: "/test-path/{path}")\n@readonly\n@httpRequestTests([\n {\n id: "TestPath",\n protocol: simpleRestJson,\n method: "GET",\n uri: "/test-path/sameValue"\n params: { path: "sameValue" }\n }\n])\noperation TestPath {\n input := {\n @httpLabel\n @required\n path: String\n }\n}\n\n// The following shapes are used by the documentation\n@simpleRestJson\nservice HelloWorldService {\n version: "1.0.0",\n operations: [Hello]\n}\n@httpRequestTests([\n {\n id: "helloSuccess"\n protocol: simpleRestJson\n method: "POST"\n uri: "/World"\n params: { name: "World" }\n },\n {\n id: "helloFails"\n protocol: simpleRestJson\n method: "POST"\n uri: "/fail"\n params: { name: "World" }\n }\n])\n@http(method: "POST", uri: "/{name}", code: 200)\noperation Hello {\n input := {\n @httpLabel\n @required\n name: String\n },\n output := {\n @required\n message: String\n }\n}\n\n@httpResponseTests([\n {\n id: "simple_error"\n protocol: simpleRestJson\n params: { expected: -1 }\n code: 400\n body: "{\\"expected\\":-1}"\n bodyMediaType: "application/json"\n requireHeaders: ["X-Error-Type"]\n }\n])\n@error("client")\nstructure SimpleError {\n @required\n expected: Integer\n}\n@httpResponseTests([\n {\n id: "complex_error"\n protocol: simpleRestJson\n params: { value: -1, message: "some error message", details: { date: 123, location: "NYC"} }\n code: 504\n body: "{\\"value\\":-1,\\"message\\":\\"some error message\\",\\"details\\":{\\"date\\":123,\\"location\\":\\"NYC\\"}}"\n bodyMediaType: "application/json"\n requireHeaders: ["X-Error-Type"]\n },\n {\n id: "complex_error_no_details"\n protocol: simpleRestJson\n params: { value: -1, message: "some error message" }\n code: 504\n body: "{\\"value\\":-1,\\"message\\":\\"some error message\\"}"\n bodyMediaType: "application/json"\n requireHeaders: ["X-Error-Type"]\n }\n])\n@error("server")\n@httpError(504)\nstructure ComplexError {\n @required\n value: Integer\n @required\n message: String\n details: ErrorDetails\n}\n\nstructure ErrorDetails {\n @required\n @timestampFormat("epoch-seconds")\n date: Timestamp\n @required\n location: String\n}\n')),(0,s.kt)("p",null,"We have a very simple specification: one operation with basic input and output shapes. We've added a ",(0,s.kt)("inlineCode",{parentName:"p"},"httpRequestTests")," to define a compliance test for protocol implementors."),(0,s.kt)("h2",{id:"testing-the-protocol"},"Testing the protocol"),(0,s.kt)("p",null,"The service in the specification is annotated with the ",(0,s.kt)("inlineCode",{parentName:"p"},"alloy#simpleRestJson")," protocol definition. We'll use the ",(0,s.kt)("inlineCode",{parentName:"p"},"compliance-tests")," module to make sure this protocol can handle such an operation."),(0,s.kt)("p",null,(0,s.kt)("em",{parentName:"p"},"Note: the following code and the ",(0,s.kt)("inlineCode",{parentName:"em"},"compliance-tests")," module do not depend on a specific test framework. If you want to hook it into your test framework, it is easy to do so but it's outside the scope of this document. Refer to ",(0,s.kt)("a",{parentName:"em",href:"https://github.com/disneystreaming/smithy4s/blob/8cb01fd92d65f6e4ec515fccb3677cffe6a1093b/modules/compliance-tests/test/src/smithy4s/compliancetests/WeaverComplianceTest.scala"},"this example")," to see how we did it for ",(0,s.kt)("inlineCode",{parentName:"em"},"Weaver")," in this project.")),(0,s.kt)("p",null,"First, some imports:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-scala"},"import cats.effect._\nimport org.http4s._\nimport org.http4s.client.Client\nimport smithy4s.compliancetests._\nimport smithy4s.example.test._\nimport smithy4s.http.HttpMediaType\nimport smithy4s.http4s._\nimport smithy4s.kinds._\nimport smithy4s.Service\nimport smithy4s.schema.Schema\n")),(0,s.kt)("p",null,"Then, you can create and instance of ",(0,s.kt)("inlineCode",{parentName:"p"},"ClientHttpComplianceTestCase")," and/or ",(0,s.kt)("inlineCode",{parentName:"p"},"ServerHttpComplianceTestCase")," while selecting the protocol to use and the service to test:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-scala"},'object SimpleRestJsonIntegration extends Router[IO] with ReverseRouter[IO] {\n type Protocol = alloy.SimpleRestJson\n val protocolTag = alloy.SimpleRestJson\n\n def expectedResponseType(schema: Schema[_]) = HttpMediaType("application/json")\n\n def routes[Alg[_[_, _, _, _, _]]](\n impl: FunctorAlgebra[Alg, IO]\n )(implicit service: Service[Alg]): Resource[IO, HttpRoutes[IO]] =\n SimpleRestJsonBuilder(service).routes(impl).resource\n\n def reverseRoutes[Alg[_[_, _, _, _, _]]](app: HttpApp[IO],testHost: Option[String] = None)(implicit\n service: Service[Alg]\n ): Resource[IO, FunctorAlgebra[Alg, IO]] = {\n import org.http4s.implicits._\n val baseUri = uri"http://localhost/"\n val suppliedHost = testHost.map(host => Uri.unsafeFromString(s"http://$host"))\n SimpleRestJsonBuilder(service)\n .client(Client.fromHttpApp(app))\n .uri(suppliedHost.getOrElse(baseUri))\n .resource\n }\n }\n\nval tests: List[ComplianceTest[IO]] = HttpProtocolCompliance\n .clientAndServerTests(SimpleRestJsonIntegration, HelloWorldService)\n')),(0,s.kt)("p",null,"Now, you can iterate over the test cases and do what you want. This is where you would hook in the test framework of your choice, but in the following example, we're just going to print the result:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-scala"},'import cats.syntax.traverse._\nimport cats.effect.unsafe.implicits.global\n\nval runTests: IO[List[String]] = tests\n .map { tc =>\n tc.run.map(_.toEither).map {\n case Left(value) =>\n s"Failed ${tc.show} with the following message: $value"\n case Right(_) => s"Success ${tc.show}"\n\n }\n }\n .sequence\n')),(0,s.kt)("p",null,"Will produce the following when executed:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre"},'Success smithy4s.example.test#Hello(client|Request): helloSuccess\nFailed smithy4s.example.test#Hello(client|Request): helloFails with the following message: NonEmptyList(path test : the result value: \x1b[33mVector\x1b[39m(\x1b[32m"World"\x1b[39m) was not equal to the expected TestCase value \x1b[33mVector\x1b[39m(\x1b[32m"fail"\x1b[39m).)\nSuccess smithy4s.example.test#Hello(server|Request): helloSuccess\nFailed smithy4s.example.test#Hello(server|Request): helloFails with the following message: NonEmptyList( the result value: \x1b[33mHelloInput\x1b[39m(name = \x1b[32m"fail"\x1b[39m) was not equal to the expected TestCase value \x1b[33mHelloInput\x1b[39m(name = \x1b[32m"World"\x1b[39m).)\n')))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/4f61a3d4.ca6617fe.js b/assets/js/4f61a3d4.50e132c9.js similarity index 81% rename from assets/js/4f61a3d4.ca6617fe.js rename to assets/js/4f61a3d4.50e132c9.js index fe0b17900..f122b9ef1 100644 --- a/assets/js/4f61a3d4.ca6617fe.js +++ b/assets/js/4f61a3d4.50e132c9.js @@ -1 +1 @@ -"use strict";(self.webpackChunksmithy4s=self.webpackChunksmithy4s||[]).push([[1868],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>y});var s=n(7294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);t&&(s=s.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,s)}return n}function a(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(s=0;s=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var l=s.createContext({}),p=function(e){var t=s.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},c=function(e){var t=p(e.components);return s.createElement(l.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return s.createElement(s.Fragment,{},t)}},d=s.forwardRef((function(e,t){var n=e.components,i=e.mdxType,o=e.originalType,l=e.parentName,c=r(e,["components","mdxType","originalType","parentName"]),u=p(n),d=i,y=u["".concat(l,".").concat(d)]||u[d]||m[d]||o;return n?s.createElement(y,a(a({ref:t},c),{},{components:n})):s.createElement(y,a({ref:t},c))}));function y(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=n.length,a=new Array(o);a[0]=d;var r={};for(var l in t)hasOwnProperty.call(t,l)&&(r[l]=t[l]);r.originalType=e,r[u]="string"==typeof e?e:i,a[1]=r;for(var p=2;p{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>m,frontMatter:()=>o,metadata:()=>r,toc:()=>p});var s=n(7462),i=(n(7294),n(3905));const o={sidebar_label:"Optics",title:"Optics - Lenses and Prisms"},a=void 0,r={unversionedId:"codegen/customisation/optics",id:"codegen/customisation/optics",title:"Optics - Lenses and Prisms",description:"Smithy4s has the ability to render optics (Lens/Prism) instances in the code it generates.",source:"@site/../docs/target/jvm-2.13/mdoc/04-codegen/01-customisation/11-optics.md",sourceDirName:"04-codegen/01-customisation",slug:"/codegen/customisation/optics",permalink:"/smithy4s/docs/codegen/customisation/optics",draft:!1,editUrl:"https://github.com/disneystreaming/smithy4s/edit/main/modules/docs/src/04-codegen/01-customisation/11-optics.md",tags:[],version:"current",sidebarPosition:11,frontMatter:{sidebar_label:"Optics",title:"Optics - Lenses and Prisms"},sidebar:"tutorialSidebar",previous:{title:"Service Product",permalink:"/smithy4s/docs/codegen/customisation/service-product"},next:{title:"Open Enums",permalink:"/smithy4s/docs/codegen/customisation/open-enums"}},l={},p=[{value:"Optics Usage",id:"optics-usage",level:2},{value:"Using 3rd Party Optics Libraries",id:"using-3rd-party-optics-libraries",level:2}],c={toc:p},u="wrapper";function m(e){let{components:t,...n}=e;return(0,i.kt)(u,(0,s.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("p",null,"Smithy4s has the ability to render optics (Lens/Prism) instances in the code it generates."),(0,i.kt)("p",null,"If you're using Smithy4s via ",(0,i.kt)("inlineCode",{parentName:"p"},"mill")," or ",(0,i.kt)("inlineCode",{parentName:"p"},"sbt"),", then you can enable this functionality with the following keys:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"in mill, task: ",(0,i.kt)("inlineCode",{parentName:"li"},"def smithy4sRenderOptics = true")),(0,i.kt)("li",{parentName:"ul"},"in sbt, setting: ",(0,i.kt)("inlineCode",{parentName:"li"},"smithy4sRenderOptics := true"))),(0,i.kt)("p",null,"If you are using Smithy4s via the CLI, then they way to utilize this feature is through your Smithy specifications. The simplest approach is to add a file with the following content to your CLI invocation:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-kotlin"},'$version: "2"\n\nmetadata smithy4sRenderOptics = true\n')),(0,i.kt)("p",null,"Alternatively, if you want to generate optics for only select shapes in your model, you can accomplish this using\nthe ",(0,i.kt)("inlineCode",{parentName:"p"},"smithy4s.meta#generateOptics")," trait. This trait can be used on enum, intEnum, union, and structure shapes."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-kotlin"},"use smithy4s.meta#generateOptics\n\n@generateOptics\nstructure MyStruct {\n one: String\n}\n")),(0,i.kt)("h2",{id:"optics-usage"},"Optics Usage"),(0,i.kt)("p",null,"Below is an example of using the lenses that smithy4s generates. By default, smithy4s will generate lenses for all structure shapes in your input smithy model(s)."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},'import smithy4s.example._\n\nval input = TestInput("test", TestBody(Some("test body")))\n// input: TestInput = TestInput(\n// pathParam = "test",\n// body = TestBody(data = Some(value = "test body")),\n// queryParam = None\n// )\nval lens = TestInput.optics.body.andThen(TestBody.optics.data).some\n// lens: smithy4s.optics.Optional[TestInput, String] = smithy4s.optics.Optional$$anon$1@3d65032c\nval resultGet = lens.project(input)\n// resultGet: Option[String] = Some(value = "test body")\n\nresultGet == Option("test body") // true\n// res1: Boolean = true // true\n\nval resultSet =\n lens.replace("new body")(input)\n// resultSet: TestInput = TestInput(\n// pathParam = "test",\n// body = TestBody(data = Some(value = "new body")),\n// queryParam = None\n// )\n\nval updatedInput = TestInput("test", TestBody(Some("new body")))\n// updatedInput: TestInput = TestInput(\n// pathParam = "test",\n// body = TestBody(data = Some(value = "new body")),\n// queryParam = None\n// )\n\nresultSet == updatedInput // true\n// res2: Boolean = true\n')),(0,i.kt)("p",null,"You can also compose prisms with lenses (and vice-versa) as in the example below:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},'import smithy4s.example._\n\nval input = Podcast.Video(Some("Pod Title"))\n// input: Podcast.Video = Video(\n// title = Some(value = "Pod Title"),\n// url = None,\n// durationMillis = None\n// )\n\nval prism = Podcast.optics.video.andThen(Podcast.Video.optics.title).some\n// prism: smithy4s.optics.Optional[Podcast, String] = smithy4s.optics.Optional$$anon$1@510c51b3\nval result = prism.replace("New Pod Title")(input)\n// result: Podcast = Video(\n// title = Some(value = "New Pod Title"),\n// url = None,\n// durationMillis = None\n// )\n\nPodcast.Video(Some("New Pod Title")) == result // true\n// res4: Boolean = true\n')),(0,i.kt)("p",null,"Smithy4s also provides a ",(0,i.kt)("inlineCode",{parentName:"p"},"value")," function on Prisms and Lenses that can be used to abstract over NewTypes (similar to what ",(0,i.kt)("inlineCode",{parentName:"p"},".some")," does for Option types):"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},'import smithy4s.example._\n\nval input = GetCityInput(CityId("test"))\n// input: GetCityInput = GetCityInput(cityId = "test")\n\nval cityName: smithy4s.optics.Lens[GetCityInput, String] = GetCityInput.optics.cityId.value\n// cityName: smithy4s.optics.Lens[GetCityInput, String] = smithy4s.optics.Lens$$anon$2@67b7c48\nval updated = cityName.replace("Fancy New Name")(input)\n// updated: GetCityInput = GetCityInput(cityId = "Fancy New Name")\n\nval result = cityName.project(updated)\n// result: Option[String] = Some(value = "Fancy New Name")\n\nOption("Fancy New Name") == result // true\n// res6: Boolean = true\n')),(0,i.kt)("h2",{id:"using-3rd-party-optics-libraries"},"Using 3rd Party Optics Libraries"),(0,i.kt)("p",null,"If you'd like to use a third party optics library for more functionality, you can accomplish this by adding an object with a few conversion functions. Here is an example using ",(0,i.kt)("a",{parentName:"p",href:"https://www.optics.dev/Monocle/"},"Monocle"),"."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},"object MonocleConversions {\n\n implicit def smithy4sToMonocleLens[S, A](\n smithy4sLens: smithy4s.optics.Lens[S, A]\n ): monocle.Lens[S, A] =\n monocle.Lens[S, A](smithy4sLens.get)(smithy4sLens.replace)\n\n implicit def smithy4sToMonoclePrism[S, A](\n smithy4sPrism: smithy4s.optics.Prism[S, A]\n ): monocle.Prism[S, A] =\n monocle.Prism(smithy4sPrism.project)(smithy4sPrism.inject)\n\n implicit def smithy4sToMonocleOptional[S, A](\n smithy4sOptional: smithy4s.optics.Optional[S, A]\n ): monocle.Optional[S, A] =\n monocle.Optional(smithy4sOptional.project)(smithy4sOptional.replace)\n\n}\n")),(0,i.kt)("p",null,"Then you can ",(0,i.kt)("inlineCode",{parentName:"p"},"import MonocleConversions._")," at the top of any file you need to seamlessly convert smithy4s optics over to Monocle ones."))}m.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunksmithy4s=self.webpackChunksmithy4s||[]).push([[1868],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>y});var s=n(7294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);t&&(s=s.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,s)}return n}function a(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(s=0;s=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var l=s.createContext({}),p=function(e){var t=s.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},c=function(e){var t=p(e.components);return s.createElement(l.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return s.createElement(s.Fragment,{},t)}},d=s.forwardRef((function(e,t){var n=e.components,i=e.mdxType,o=e.originalType,l=e.parentName,c=r(e,["components","mdxType","originalType","parentName"]),u=p(n),d=i,y=u["".concat(l,".").concat(d)]||u[d]||m[d]||o;return n?s.createElement(y,a(a({ref:t},c),{},{components:n})):s.createElement(y,a({ref:t},c))}));function y(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=n.length,a=new Array(o);a[0]=d;var r={};for(var l in t)hasOwnProperty.call(t,l)&&(r[l]=t[l]);r.originalType=e,r[u]="string"==typeof e?e:i,a[1]=r;for(var p=2;p{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>m,frontMatter:()=>o,metadata:()=>r,toc:()=>p});var s=n(7462),i=(n(7294),n(3905));const o={sidebar_label:"Optics",title:"Optics - Lenses and Prisms"},a=void 0,r={unversionedId:"codegen/customisation/optics",id:"codegen/customisation/optics",title:"Optics - Lenses and Prisms",description:"Smithy4s has the ability to render optics (Lens/Prism) instances in the code it generates.",source:"@site/../docs/target/jvm-2.13/mdoc/04-codegen/01-customisation/11-optics.md",sourceDirName:"04-codegen/01-customisation",slug:"/codegen/customisation/optics",permalink:"/smithy4s/docs/codegen/customisation/optics",draft:!1,editUrl:"https://github.com/disneystreaming/smithy4s/edit/main/modules/docs/src/04-codegen/01-customisation/11-optics.md",tags:[],version:"current",sidebarPosition:11,frontMatter:{sidebar_label:"Optics",title:"Optics - Lenses and Prisms"},sidebar:"tutorialSidebar",previous:{title:"Service Product",permalink:"/smithy4s/docs/codegen/customisation/service-product"},next:{title:"Open Enums",permalink:"/smithy4s/docs/codegen/customisation/open-enums"}},l={},p=[{value:"Optics Usage",id:"optics-usage",level:2},{value:"Using 3rd Party Optics Libraries",id:"using-3rd-party-optics-libraries",level:2}],c={toc:p},u="wrapper";function m(e){let{components:t,...n}=e;return(0,i.kt)(u,(0,s.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("p",null,"Smithy4s has the ability to render optics (Lens/Prism) instances in the code it generates."),(0,i.kt)("p",null,"If you're using Smithy4s via ",(0,i.kt)("inlineCode",{parentName:"p"},"mill")," or ",(0,i.kt)("inlineCode",{parentName:"p"},"sbt"),", then you can enable this functionality with the following keys:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"in mill, task: ",(0,i.kt)("inlineCode",{parentName:"li"},"def smithy4sRenderOptics = true")),(0,i.kt)("li",{parentName:"ul"},"in sbt, setting: ",(0,i.kt)("inlineCode",{parentName:"li"},"smithy4sRenderOptics := true"))),(0,i.kt)("p",null,"If you are using Smithy4s via the CLI, then they way to utilize this feature is through your Smithy specifications. The simplest approach is to add a file with the following content to your CLI invocation:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-kotlin"},'$version: "2"\n\nmetadata smithy4sRenderOptics = true\n')),(0,i.kt)("p",null,"Alternatively, if you want to generate optics for only select shapes in your model, you can accomplish this using\nthe ",(0,i.kt)("inlineCode",{parentName:"p"},"smithy4s.meta#generateOptics")," trait. This trait can be used on enum, intEnum, union, and structure shapes."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-kotlin"},"use smithy4s.meta#generateOptics\n\n@generateOptics\nstructure MyStruct {\n one: String\n}\n")),(0,i.kt)("h2",{id:"optics-usage"},"Optics Usage"),(0,i.kt)("p",null,"Below is an example of using the lenses that smithy4s generates. By default, smithy4s will generate lenses for all structure shapes in your input smithy model(s)."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},'import smithy4s.example._\n\nval input = TestInput("test", TestBody(Some("test body")))\n// input: TestInput = TestInput(\n// pathParam = "test",\n// body = TestBody(data = Some(value = "test body")),\n// queryParam = None\n// )\nval lens = TestInput.optics.body.andThen(TestBody.optics.data).some\n// lens: smithy4s.optics.Optional[TestInput, String] = smithy4s.optics.Optional$$anon$1@4fc3133d\nval resultGet = lens.project(input)\n// resultGet: Option[String] = Some(value = "test body")\n\nresultGet == Option("test body") // true\n// res1: Boolean = true // true\n\nval resultSet =\n lens.replace("new body")(input)\n// resultSet: TestInput = TestInput(\n// pathParam = "test",\n// body = TestBody(data = Some(value = "new body")),\n// queryParam = None\n// )\n\nval updatedInput = TestInput("test", TestBody(Some("new body")))\n// updatedInput: TestInput = TestInput(\n// pathParam = "test",\n// body = TestBody(data = Some(value = "new body")),\n// queryParam = None\n// )\n\nresultSet == updatedInput // true\n// res2: Boolean = true\n')),(0,i.kt)("p",null,"You can also compose prisms with lenses (and vice-versa) as in the example below:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},'import smithy4s.example._\n\nval input = Podcast.Video(Some("Pod Title"))\n// input: Podcast.Video = Video(\n// title = Some(value = "Pod Title"),\n// url = None,\n// durationMillis = None\n// )\n\nval prism = Podcast.optics.video.andThen(Podcast.Video.optics.title).some\n// prism: smithy4s.optics.Optional[Podcast, String] = smithy4s.optics.Optional$$anon$1@25bcb29d\nval result = prism.replace("New Pod Title")(input)\n// result: Podcast = Video(\n// title = Some(value = "New Pod Title"),\n// url = None,\n// durationMillis = None\n// )\n\nPodcast.Video(Some("New Pod Title")) == result // true\n// res4: Boolean = true\n')),(0,i.kt)("p",null,"Smithy4s also provides a ",(0,i.kt)("inlineCode",{parentName:"p"},"value")," function on Prisms and Lenses that can be used to abstract over NewTypes (similar to what ",(0,i.kt)("inlineCode",{parentName:"p"},".some")," does for Option types):"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},'import smithy4s.example._\n\nval input = GetCityInput(CityId("test"))\n// input: GetCityInput = GetCityInput(cityId = "test")\n\nval cityName: smithy4s.optics.Lens[GetCityInput, String] = GetCityInput.optics.cityId.value\n// cityName: smithy4s.optics.Lens[GetCityInput, String] = smithy4s.optics.Lens$$anon$2@46770f11\nval updated = cityName.replace("Fancy New Name")(input)\n// updated: GetCityInput = GetCityInput(cityId = "Fancy New Name")\n\nval result = cityName.project(updated)\n// result: Option[String] = Some(value = "Fancy New Name")\n\nOption("Fancy New Name") == result // true\n// res6: Boolean = true\n')),(0,i.kt)("h2",{id:"using-3rd-party-optics-libraries"},"Using 3rd Party Optics Libraries"),(0,i.kt)("p",null,"If you'd like to use a third party optics library for more functionality, you can accomplish this by adding an object with a few conversion functions. Here is an example using ",(0,i.kt)("a",{parentName:"p",href:"https://www.optics.dev/Monocle/"},"Monocle"),"."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},"object MonocleConversions {\n\n implicit def smithy4sToMonocleLens[S, A](\n smithy4sLens: smithy4s.optics.Lens[S, A]\n ): monocle.Lens[S, A] =\n monocle.Lens[S, A](smithy4sLens.get)(smithy4sLens.replace)\n\n implicit def smithy4sToMonoclePrism[S, A](\n smithy4sPrism: smithy4s.optics.Prism[S, A]\n ): monocle.Prism[S, A] =\n monocle.Prism(smithy4sPrism.project)(smithy4sPrism.inject)\n\n implicit def smithy4sToMonocleOptional[S, A](\n smithy4sOptional: smithy4s.optics.Optional[S, A]\n ): monocle.Optional[S, A] =\n monocle.Optional(smithy4sOptional.project)(smithy4sOptional.replace)\n\n}\n")),(0,i.kt)("p",null,"Then you can ",(0,i.kt)("inlineCode",{parentName:"p"},"import MonocleConversions._")," at the top of any file you need to seamlessly convert smithy4s optics over to Monocle ones."))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/814869ee.abeb2936.js b/assets/js/814869ee.b3f6d5ff.js similarity index 51% rename from assets/js/814869ee.abeb2936.js rename to assets/js/814869ee.b3f6d5ff.js index 903ecbb39..94e8a6e3b 100644 --- a/assets/js/814869ee.abeb2936.js +++ b/assets/js/814869ee.b3f6d5ff.js @@ -1 +1 @@ -"use strict";(self.webpackChunksmithy4s=self.webpackChunksmithy4s||[]).push([[9855],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>y});var i=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function l(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var o=i.createContext({}),m=function(e){var t=i.useContext(o),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},p=function(e){var t=m(e.components);return i.createElement(o.Provider,{value:t},e.children)},d="mdxType",c={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},u=i.forwardRef((function(e,t){var n=e.components,r=e.mdxType,a=e.originalType,o=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),d=m(n),u=r,y=d["".concat(o,".").concat(u)]||d[u]||c[u]||a;return n?i.createElement(y,l(l({ref:t},p),{},{components:n})):i.createElement(y,l({ref:t},p))}));function y(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var a=n.length,l=new Array(a);l[0]=u;var s={};for(var o in t)hasOwnProperty.call(t,o)&&(s[o]=t[o]);s.originalType=e,s[d]="string"==typeof e?e:r,l[1]=s;for(var m=2;m{n.r(t),n.d(t,{assets:()=>o,contentTitle:()=>l,default:()=>c,frontMatter:()=>a,metadata:()=>s,toc:()=>m});var i=n(7462),r=(n(7294),n(3905));const a={sidebar_label:"Installation",title:"Installation"},l=void 0,s={unversionedId:"overview/installation",id:"overview/installation",title:"Installation",description:'Smithy4s generates Scala code from a Smithy model. The generated code includes traits for any services you might define, as well as case classes for models used in these services. It has no dependencies on external libraries or any specific protocol like HTTP or JSON. It does, however, depend on a "core" library that contains a number of interfaces implemented by the generated code.',source:"@site/../docs/target/jvm-2.13/mdoc/01-overview/03-installation.md",sourceDirName:"01-overview",slug:"/overview/installation",permalink:"/smithy4s/docs/overview/installation",draft:!1,editUrl:"https://github.com/disneystreaming/smithy4s/edit/main/modules/docs/src/01-overview/03-installation.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_label:"Installation",title:"Installation"},sidebar:"tutorialSidebar",previous:{title:"Quick Start",permalink:"/smithy4s/docs/overview/quickstart"},next:{title:"Installation (CLI)",permalink:"/smithy4s/docs/overview/cli"}},o={},m=[{value:"SBT",id:"sbt",level:2},{value:"Mill",id:"mill",level:2}],p={toc:m},d="wrapper";function c(e){let{components:t,...n}=e;return(0,r.kt)(d,(0,i.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("p",null,'Smithy4s generates Scala code from a Smithy model. The generated code includes traits for any services you might define, as well as case classes for models used in these services. It has no dependencies on external libraries or any specific protocol like HTTP or JSON. It does, however, depend on a "core" library that contains a number of interfaces implemented by the generated code.'),(0,r.kt)("h2",{id:"sbt"},"SBT"),(0,r.kt)("p",null,(0,r.kt)("em",{parentName:"p"},"For mill support, see ",(0,r.kt)("a",{parentName:"em",href:"#mill"},"Mill")," below.")),(0,r.kt)("p",null,(0,r.kt)("inlineCode",{parentName:"p"},"smithy4s-sbt-codegen")," is a code generating sbt plugin that creates ",(0,r.kt)("inlineCode",{parentName:"p"},".scala")," files corresponding to the provided ",(0,r.kt)("inlineCode",{parentName:"p"},".smithy")," specs."),(0,r.kt)("p",null,"In ",(0,r.kt)("inlineCode",{parentName:"p"},"project/plugins.sbt"),":"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-scala"},'addSbtPlugin("com.disneystreaming.smithy4s" % "smithy4s-sbt-codegen" % "0.18.9")\n')),(0,r.kt)("p",null,"and enable the plugin in the desired sbt module:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-scala"},'import smithy4s.codegen.Smithy4sCodegenPlugin\n\nval myModule = project\n .in(file("modules/my-module"))\n .enablePlugins(Smithy4sCodegenPlugin)\n // version for smithy4s-core is sourced from Smithy4sCodegenPlugin\n .settings(libraryDependencies += "com.disneystreaming.smithy4s" %% "smithy4s-core" % smithy4sVersion.value)\n')),(0,r.kt)("p",null,"This will enable the plugin on ",(0,r.kt)("inlineCode",{parentName:"p"},"myModule"),". We also need to add ",(0,r.kt)("inlineCode",{parentName:"p"},"smithy4s-core ")," here since it is needed for compiling the generated code."),(0,r.kt)("p",null,"By default, the plugin will look in the ",(0,r.kt)("inlineCode",{parentName:"p"},"$MY_MODULE/src/main/smithy")," directory and will write scala code in ",(0,r.kt)("inlineCode",{parentName:"p"},"$MY_MODULE/target/scala-/src_managed/")," when invoking ",(0,r.kt)("inlineCode",{parentName:"p"},"compile"),". The paths are configurable via the ",(0,r.kt)("inlineCode",{parentName:"p"},"smithy4sInputDirs")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"smithy4sOutputDir")," settings keys."),(0,r.kt)("p",null,"For example, in order for the plugin to source ",(0,r.kt)("inlineCode",{parentName:"p"},".smithy")," specs from ",(0,r.kt)("inlineCode",{parentName:"p"},"./smithy_input")," (inside the folder where our ",(0,r.kt)("inlineCode",{parentName:"p"},"build.sbt")," is) and output the generated files into ",(0,r.kt)("inlineCode",{parentName:"p"},"./smithy_output"),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-scala"},'val myModule = project\n .in(file("modules/my-module"))\n .enablePlugins(Smithy4sCodegenPlugin)\n .settings(\n scalaVersion := "2.13.12",\n Compile / smithy4sInputDirs := Seq((ThisBuild / baseDirectory).value / "smithy_input"),\n Compile / smithy4sOutputDir := (ThisBuild / baseDirectory).value / "smithy_output",\n libraryDependencies += "com.disneystreaming.smithy4s" %% "smithy4s-core" % smithy4sVersion.value\n )\n')),(0,r.kt)("h2",{id:"mill"},"Mill"),(0,r.kt)("p",null,(0,r.kt)("inlineCode",{parentName:"p"},"smithy4s-mill-codegen-plugin")," is a plugin to enable Smithy4s code generation on a ",(0,r.kt)("inlineCode",{parentName:"p"},"mill")," module."),(0,r.kt)("p",null,"For example, here, we enabled it on the ",(0,r.kt)("inlineCode",{parentName:"p"},"example")," module:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-scala"},'import $ivy.`com.disneystreaming.smithy4s::smithy4s-mill-codegen-plugin::0.18.9`\nimport smithy4s.codegen.mill._\n\nimport mill._, mill.scalalib._\nobject example extends ScalaModule with Smithy4sModule {\n def scalaVersion = "2.13.8"\n override def ivyDeps = Agg(\n ivy"com.disneystreaming.smithy4s::smithy4s-core:${smithy4sVersion()}"\n )\n}\n')),(0,r.kt)("p",null,"By default, the ",(0,r.kt)("inlineCode",{parentName:"p"},"mill")," plugin will look for Smithy files under the ",(0,r.kt)("inlineCode",{parentName:"p"},"$MY_MODULE/smithy")," directory. The generated code ends up in ",(0,r.kt)("inlineCode",{parentName:"p"},"out/$MY_MODULE/smithy4sOutputDir.dest/scala/"),", again, by default. Code generation happens automatically when you before you ",(0,r.kt)("inlineCode",{parentName:"p"},"compile")," the module. The paths are configurable via the ",(0,r.kt)("inlineCode",{parentName:"p"},"smithy4sInputDirs")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"smithy4sOutputDir")," tasks."),(0,r.kt)("p",null,"For example, here we'll read Smithy files from ",(0,r.kt)("inlineCode",{parentName:"p"},"smithy_input")," and write to ",(0,r.kt)("inlineCode",{parentName:"p"},"smithy_output"),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-scala"},'import $ivy.`com.disneystreaming.smithy4s::smithy4s-mill-codegen-plugin::0.18.9`\nimport smithy4s.codegen.mill._\n\nimport mill._, mill.scalalib._\nobject example extends ScalaModule with Smithy4sModule {\n def scalaVersion = "2.13.8"\n override def ivyDeps = Agg(\n ivy"com.disneystreaming.smithy4s::smithy4s-core:${smithy4sVersion()}"\n )\n\n override def smithy4sInputDirs = T.sources {\n Seq(PathRef(T.ctx().workspace / "smithy_input"))\n }\n override def smithy4sOutputDir = T {\n PathRef(T.ctx().workspace / "smithy_output")\n }\n}\n')))}c.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunksmithy4s=self.webpackChunksmithy4s||[]).push([[9855],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>y});var i=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function l(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var o=i.createContext({}),m=function(e){var t=i.useContext(o),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},p=function(e){var t=m(e.components);return i.createElement(o.Provider,{value:t},e.children)},d="mdxType",c={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},u=i.forwardRef((function(e,t){var n=e.components,r=e.mdxType,a=e.originalType,o=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),d=m(n),u=r,y=d["".concat(o,".").concat(u)]||d[u]||c[u]||a;return n?i.createElement(y,l(l({ref:t},p),{},{components:n})):i.createElement(y,l({ref:t},p))}));function y(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var a=n.length,l=new Array(a);l[0]=u;var s={};for(var o in t)hasOwnProperty.call(t,o)&&(s[o]=t[o]);s.originalType=e,s[d]="string"==typeof e?e:r,l[1]=s;for(var m=2;m{n.r(t),n.d(t,{assets:()=>o,contentTitle:()=>l,default:()=>c,frontMatter:()=>a,metadata:()=>s,toc:()=>m});var i=n(7462),r=(n(7294),n(3905));const a={sidebar_label:"Installation",title:"Installation"},l=void 0,s={unversionedId:"overview/installation",id:"overview/installation",title:"Installation",description:'Smithy4s generates Scala code from a Smithy model. The generated code includes traits for any services you might define, as well as case classes for models used in these services. It has no dependencies on external libraries or any specific protocol like HTTP or JSON. It does, however, depend on a "core" library that contains a number of interfaces implemented by the generated code.',source:"@site/../docs/target/jvm-2.13/mdoc/01-overview/03-installation.md",sourceDirName:"01-overview",slug:"/overview/installation",permalink:"/smithy4s/docs/overview/installation",draft:!1,editUrl:"https://github.com/disneystreaming/smithy4s/edit/main/modules/docs/src/01-overview/03-installation.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_label:"Installation",title:"Installation"},sidebar:"tutorialSidebar",previous:{title:"Quick Start",permalink:"/smithy4s/docs/overview/quickstart"},next:{title:"Installation (CLI)",permalink:"/smithy4s/docs/overview/cli"}},o={},m=[{value:"SBT",id:"sbt",level:2},{value:"Mill",id:"mill",level:2}],p={toc:m},d="wrapper";function c(e){let{components:t,...n}=e;return(0,r.kt)(d,(0,i.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("p",null,'Smithy4s generates Scala code from a Smithy model. The generated code includes traits for any services you might define, as well as case classes for models used in these services. It has no dependencies on external libraries or any specific protocol like HTTP or JSON. It does, however, depend on a "core" library that contains a number of interfaces implemented by the generated code.'),(0,r.kt)("h2",{id:"sbt"},"SBT"),(0,r.kt)("p",null,(0,r.kt)("em",{parentName:"p"},"For mill support, see ",(0,r.kt)("a",{parentName:"em",href:"#mill"},"Mill")," below.")),(0,r.kt)("p",null,(0,r.kt)("inlineCode",{parentName:"p"},"smithy4s-sbt-codegen")," is a code generating sbt plugin that creates ",(0,r.kt)("inlineCode",{parentName:"p"},".scala")," files corresponding to the provided ",(0,r.kt)("inlineCode",{parentName:"p"},".smithy")," specs."),(0,r.kt)("p",null,"In ",(0,r.kt)("inlineCode",{parentName:"p"},"project/plugins.sbt"),":"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-scala"},'addSbtPlugin("com.disneystreaming.smithy4s" % "smithy4s-sbt-codegen" % "0.18.10")\n')),(0,r.kt)("p",null,"and enable the plugin in the desired sbt module:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-scala"},'import smithy4s.codegen.Smithy4sCodegenPlugin\n\nval myModule = project\n .in(file("modules/my-module"))\n .enablePlugins(Smithy4sCodegenPlugin)\n // version for smithy4s-core is sourced from Smithy4sCodegenPlugin\n .settings(libraryDependencies += "com.disneystreaming.smithy4s" %% "smithy4s-core" % smithy4sVersion.value)\n')),(0,r.kt)("p",null,"This will enable the plugin on ",(0,r.kt)("inlineCode",{parentName:"p"},"myModule"),". We also need to add ",(0,r.kt)("inlineCode",{parentName:"p"},"smithy4s-core ")," here since it is needed for compiling the generated code."),(0,r.kt)("p",null,"By default, the plugin will look in the ",(0,r.kt)("inlineCode",{parentName:"p"},"$MY_MODULE/src/main/smithy")," directory and will write scala code in ",(0,r.kt)("inlineCode",{parentName:"p"},"$MY_MODULE/target/scala-/src_managed/")," when invoking ",(0,r.kt)("inlineCode",{parentName:"p"},"compile"),". The paths are configurable via the ",(0,r.kt)("inlineCode",{parentName:"p"},"smithy4sInputDirs")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"smithy4sOutputDir")," settings keys."),(0,r.kt)("p",null,"For example, in order for the plugin to source ",(0,r.kt)("inlineCode",{parentName:"p"},".smithy")," specs from ",(0,r.kt)("inlineCode",{parentName:"p"},"./smithy_input")," (inside the folder where our ",(0,r.kt)("inlineCode",{parentName:"p"},"build.sbt")," is) and output the generated files into ",(0,r.kt)("inlineCode",{parentName:"p"},"./smithy_output"),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-scala"},'val myModule = project\n .in(file("modules/my-module"))\n .enablePlugins(Smithy4sCodegenPlugin)\n .settings(\n scalaVersion := "2.13.12",\n Compile / smithy4sInputDirs := Seq((ThisBuild / baseDirectory).value / "smithy_input"),\n Compile / smithy4sOutputDir := (ThisBuild / baseDirectory).value / "smithy_output",\n libraryDependencies += "com.disneystreaming.smithy4s" %% "smithy4s-core" % smithy4sVersion.value\n )\n')),(0,r.kt)("h2",{id:"mill"},"Mill"),(0,r.kt)("p",null,(0,r.kt)("inlineCode",{parentName:"p"},"smithy4s-mill-codegen-plugin")," is a plugin to enable Smithy4s code generation on a ",(0,r.kt)("inlineCode",{parentName:"p"},"mill")," module."),(0,r.kt)("p",null,"For example, here, we enabled it on the ",(0,r.kt)("inlineCode",{parentName:"p"},"example")," module:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-scala"},'import $ivy.`com.disneystreaming.smithy4s::smithy4s-mill-codegen-plugin::0.18.10`\nimport smithy4s.codegen.mill._\n\nimport mill._, mill.scalalib._\nobject example extends ScalaModule with Smithy4sModule {\n def scalaVersion = "2.13.8"\n override def ivyDeps = Agg(\n ivy"com.disneystreaming.smithy4s::smithy4s-core:${smithy4sVersion()}"\n )\n}\n')),(0,r.kt)("p",null,"By default, the ",(0,r.kt)("inlineCode",{parentName:"p"},"mill")," plugin will look for Smithy files under the ",(0,r.kt)("inlineCode",{parentName:"p"},"$MY_MODULE/smithy")," directory. The generated code ends up in ",(0,r.kt)("inlineCode",{parentName:"p"},"out/$MY_MODULE/smithy4sOutputDir.dest/scala/"),", again, by default. Code generation happens automatically when you before you ",(0,r.kt)("inlineCode",{parentName:"p"},"compile")," the module. The paths are configurable via the ",(0,r.kt)("inlineCode",{parentName:"p"},"smithy4sInputDirs")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"smithy4sOutputDir")," tasks."),(0,r.kt)("p",null,"For example, here we'll read Smithy files from ",(0,r.kt)("inlineCode",{parentName:"p"},"smithy_input")," and write to ",(0,r.kt)("inlineCode",{parentName:"p"},"smithy_output"),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-scala"},'import $ivy.`com.disneystreaming.smithy4s::smithy4s-mill-codegen-plugin::0.18.10`\nimport smithy4s.codegen.mill._\n\nimport mill._, mill.scalalib._\nobject example extends ScalaModule with Smithy4sModule {\n def scalaVersion = "2.13.8"\n override def ivyDeps = Agg(\n ivy"com.disneystreaming.smithy4s::smithy4s-core:${smithy4sVersion()}"\n )\n\n override def smithy4sInputDirs = T.sources {\n Seq(PathRef(T.ctx().workspace / "smithy_input"))\n }\n override def smithy4sOutputDir = T {\n PathRef(T.ctx().workspace / "smithy_output")\n }\n}\n')))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/9bbdc9ed.93aeb439.js b/assets/js/9bbdc9ed.93aeb439.js deleted file mode 100644 index 35fed6fda..000000000 --- a/assets/js/9bbdc9ed.93aeb439.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunksmithy4s=self.webpackChunksmithy4s||[]).push([[3533],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>h});var i=n(7294);function l(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function o(e){for(var t=1;t=0||(l[n]=e[n]);return l}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(l[n]=e[n])}return l}var s=i.createContext({}),m=function(e){var t=i.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},p=function(e){var t=m(e.components);return i.createElement(s.Provider,{value:t},e.children)},c="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},d=i.forwardRef((function(e,t){var n=e.components,l=e.mdxType,r=e.originalType,s=e.parentName,p=a(e,["components","mdxType","originalType","parentName"]),c=m(n),d=l,h=c["".concat(s,".").concat(d)]||c[d]||u[d]||r;return n?i.createElement(h,o(o({ref:t},p),{},{components:n})):i.createElement(h,o({ref:t},p))}));function h(e,t){var n=arguments,l=t&&t.mdxType;if("string"==typeof e||l){var r=n.length,o=new Array(r);o[0]=d;var a={};for(var s in t)hasOwnProperty.call(t,s)&&(a[s]=t[s]);a.originalType=e,a[c]="string"==typeof e?e:l,o[1]=a;for(var m=2;m{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>u,frontMatter:()=>r,metadata:()=>a,toc:()=>m});var i=n(7462),l=(n(7294),n(3905));const r={sidebar_label:"Quick Start",title:"Quick Start"},o=void 0,a={unversionedId:"overview/quickstart",id:"overview/quickstart",title:"Quick Start",description:"Below is a quick example of smithy4s in action. This page does not provide much explanation or detail. For more information on various aspects of smithy4s, read through the other sections of this documentation site.",source:"@site/../docs/target/jvm-2.13/mdoc/01-overview/02-quickstart.md",sourceDirName:"01-overview",slug:"/overview/quickstart",permalink:"/smithy4s/docs/overview/quickstart",draft:!1,editUrl:"https://github.com/disneystreaming/smithy4s/edit/main/modules/docs/src/01-overview/02-quickstart.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_label:"Quick Start",title:"Quick Start"},sidebar:"tutorialSidebar",previous:{title:"Intro",permalink:"/smithy4s/docs/overview/intro"},next:{title:"Installation",permalink:"/smithy4s/docs/overview/installation"}},s={},m=[{value:"For sbt",id:"for-sbt",level:2},{value:"project/plugins.sbt",id:"projectpluginssbt",level:3},{value:"build.sbt",id:"buildsbt",level:3},{value:"For Mill",id:"for-mill",level:2},{value:"Smithy content",id:"smithy-content",level:2},{value:"Using the generated code",id:"using-the-generated-code",level:2},{value:"Run Service",id:"run-service",level:2},{value:"Navigate to localhost:9000/docs",id:"navigate-to-localhost9000docs",level:2},{value:"Client Example",id:"client-example",level:2}],p={toc:m},c="wrapper";function u(e){let{components:t,...n}=e;return(0,l.kt)(c,(0,i.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,l.kt)("p",null,"Below is a quick example of smithy4s in action. This page does not provide much explanation or detail. For more information on various aspects of smithy4s, read through the other sections of this documentation site."),(0,l.kt)("h2",{id:"for-sbt"},"For sbt"),(0,l.kt)("p",null,"This section will get you started with a simple ",(0,l.kt)("inlineCode",{parentName:"p"},"sbt")," module that enables smithy4s code generation. For a similar setup for mill, see ",(0,l.kt)("a",{parentName:"p",href:"#for-mill"},"Mill")," below."),(0,l.kt)("h3",{id:"projectpluginssbt"},"project/plugins.sbt"),(0,l.kt)("p",null,"Add the ",(0,l.kt)("inlineCode",{parentName:"p"},"smithy4s-sbt-codegen")," plugin to your build."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-scala"},'addSbtPlugin("com.disneystreaming.smithy4s" % "smithy4s-sbt-codegen" % "0.18.9")\n')),(0,l.kt)("h3",{id:"buildsbt"},"build.sbt"),(0,l.kt)("p",null,"Enable the plugin in your project, add the smithy and http4s dependencies."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-scala"},'import smithy4s.codegen.Smithy4sCodegenPlugin\n\nThisBuild / scalaVersion := "2.13.12"\n\nval example = project\n .in(file("modules/example"))\n .enablePlugins(Smithy4sCodegenPlugin)\n .settings(\n libraryDependencies ++= Seq(\n "com.disneystreaming.smithy4s" %% "smithy4s-http4s" % smithy4sVersion.value,\n "com.disneystreaming.smithy4s" %% "smithy4s-http4s-swagger" % smithy4sVersion.value,\n "org.http4s" %% "http4s-ember-server" % "0.23.25"\n )\n )\n')),(0,l.kt)("h2",{id:"for-mill"},"For Mill"),(0,l.kt)("p",null,"This section will get you started with a ",(0,l.kt)("inlineCode",{parentName:"p"},"mill")," module with code generation enabled on it."),(0,l.kt)("p",null,"In your ",(0,l.kt)("inlineCode",{parentName:"p"},"build.sc"),":"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-scala"},'import $ivy.`com.disneystreaming.smithy4s::smithy4s-mill-codegen-plugin::0.18.9`\nimport smithy4s.codegen.mill._\n\nimport mill._, mill.scalalib._\nobject example extends ScalaModule with Smithy4sModule {\n def scalaVersion = "2.13.8"\n override def ivyDeps = Agg(\n ivy"com.disneystreaming.smithy4s::smithy4s-core:${smithy4sVersion()}",\n ivy"com.disneystreaming.smithy4s::smithy4s-http4s-swagger:${smithy4sVersion()}",\n ivy"org.http4s::http4s-ember-server:0.23.25"\n )\n}\n')),(0,l.kt)("h2",{id:"smithy-content"},"Smithy content"),(0,l.kt)("p",null,"Now is the time to add some Smithy shapes to see what code generation can do for you. Following the setup above, the location for the Smithy content will change depending on what build tool you used."),(0,l.kt)("p",null,"Now let's define an API in Smithy. Create the following file:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"for ",(0,l.kt)("inlineCode",{parentName:"li"},"sbt"),", you'll write in ",(0,l.kt)("inlineCode",{parentName:"li"},"modules/example/src/main/smithy/ExampleService.smithy"),"."),(0,l.kt)("li",{parentName:"ul"},"for ",(0,l.kt)("inlineCode",{parentName:"li"},"mill"),", you'll write in ",(0,l.kt)("inlineCode",{parentName:"li"},"example/smithy/ExampleService.smithy"))),(0,l.kt)("p",null,"And add the content below:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-kotlin"},'namespace smithy4s.hello\n\nuse alloy#simpleRestJson\n\n@simpleRestJson\nservice HelloWorldService {\n version: "1.0.0",\n operations: [Hello]\n}\n\n@http(method: "POST", uri: "/{name}", code: 200)\noperation Hello {\n input: Person,\n output: Greeting\n}\n\nstructure Person {\n @httpLabel\n @required\n name: String,\n\n @httpQuery("town")\n town: String\n}\n\nstructure Greeting {\n @required\n message: String\n}\n')),(0,l.kt)("p",null,"The Scala code corresponding to this smithy file will be generated the next time you compile your project."),(0,l.kt)("h2",{id:"using-the-generated-code"},"Using the generated code"),(0,l.kt)("p",null,"Now, let's use the generated code by the service. You need to create a scala file at the following location:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"for sbt ",(0,l.kt)("inlineCode",{parentName:"li"},"modules/example/src/main/scala/Main.scala")),(0,l.kt)("li",{parentName:"ul"},"for mill ",(0,l.kt)("inlineCode",{parentName:"li"},"example/src/Main.scala"))),(0,l.kt)("p",null,"Implement your service by extending the generated Service trait. Wire up routes into server."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-scala"},'import smithy4s.example.hello._\nimport cats.effect._\nimport cats.implicits._\nimport org.http4s.implicits._\nimport org.http4s.ember.server._\nimport org.http4s._\nimport com.comcast.ip4s._\nimport smithy4s.http4s.SimpleRestJsonBuilder\n\nobject HelloWorldImpl extends HelloWorldService[IO] {\n def hello(name: String, town: Option[String]): IO[Greeting] = IO.pure {\n town match {\n case None => Greeting(s"Hello $name!")\n case Some(t) => Greeting(s"Hello $name from $t!")\n }\n }\n}\n\nobject Routes {\n private val example: Resource[IO, HttpRoutes[IO]] =\n SimpleRestJsonBuilder.routes(HelloWorldImpl).resource\n\n private val docs: HttpRoutes[IO] =\n smithy4s.http4s.swagger.docs[IO](HelloWorldService)\n\n val all: Resource[IO, HttpRoutes[IO]] = example.map(_ <+> docs)\n}\n\nobject Main extends IOApp.Simple {\n\n val run = Routes.all\n .flatMap { routes =>\n EmberServerBuilder\n .default[IO]\n .withPort(port"9000")\n .withHost(host"localhost")\n .withHttpApp(routes.orNotFound)\n .build\n }\n .use(_ => IO.never)\n\n}\n')),(0,l.kt)("h2",{id:"run-service"},"Run Service"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"for sbt: ",(0,l.kt)("inlineCode",{parentName:"li"},'sbt "example/run"')),(0,l.kt)("li",{parentName:"ul"},"for mill: ",(0,l.kt)("inlineCode",{parentName:"li"},"mill example.run"))),(0,l.kt)("h2",{id:"navigate-to-localhost9000docs"},"Navigate to localhost:9000/docs"),(0,l.kt)("p",null,"Here you will find the automatically generated SwaggerUI which will allow you to easily test your API."),(0,l.kt)("p",null,(0,l.kt)("img",{parentName:"p",src:"https://i.imgur.com/WQgetF6.png",alt:"SwaggerUI documentation site request"})),(0,l.kt)("p",null,(0,l.kt)("img",{parentName:"p",src:"https://i.imgur.com/JRUQyny.png",alt:"SwaggerUI documentation site response"})),(0,l.kt)("h2",{id:"client-example"},"Client Example"),(0,l.kt)("p",null,"You can also generate a client using smithy4s."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-scala"},'import org.http4s.ember.client.EmberClientBuilder\n\nobject ClientImpl extends IOApp.Simple {\n\n val helloWorldClient: Resource[IO, HelloWorldService[IO]] = for {\n client <- EmberClientBuilder.default[IO].build\n helloClient <- SimpleRestJsonBuilder(HelloWorldService)\n .client(client)\n .uri(Uri.unsafeFromString("http://localhost:9000"))\n .resource\n } yield helloClient\n\n val run = helloWorldClient.use(c =>\n c.hello("Sam", Some("New York City"))\n .flatMap(greeting => IO.println(greeting.message))\n )\n\n}\n')))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/9bbdc9ed.9d388908.js b/assets/js/9bbdc9ed.9d388908.js new file mode 100644 index 000000000..0165d726a --- /dev/null +++ b/assets/js/9bbdc9ed.9d388908.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunksmithy4s=self.webpackChunksmithy4s||[]).push([[3533],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>h});var i=n(7294);function l(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function o(e){for(var t=1;t=0||(l[n]=e[n]);return l}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(l[n]=e[n])}return l}var s=i.createContext({}),m=function(e){var t=i.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},p=function(e){var t=m(e.components);return i.createElement(s.Provider,{value:t},e.children)},c="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},d=i.forwardRef((function(e,t){var n=e.components,l=e.mdxType,r=e.originalType,s=e.parentName,p=a(e,["components","mdxType","originalType","parentName"]),c=m(n),d=l,h=c["".concat(s,".").concat(d)]||c[d]||u[d]||r;return n?i.createElement(h,o(o({ref:t},p),{},{components:n})):i.createElement(h,o({ref:t},p))}));function h(e,t){var n=arguments,l=t&&t.mdxType;if("string"==typeof e||l){var r=n.length,o=new Array(r);o[0]=d;var a={};for(var s in t)hasOwnProperty.call(t,s)&&(a[s]=t[s]);a.originalType=e,a[c]="string"==typeof e?e:l,o[1]=a;for(var m=2;m{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>u,frontMatter:()=>r,metadata:()=>a,toc:()=>m});var i=n(7462),l=(n(7294),n(3905));const r={sidebar_label:"Quick Start",title:"Quick Start"},o=void 0,a={unversionedId:"overview/quickstart",id:"overview/quickstart",title:"Quick Start",description:"Below is a quick example of smithy4s in action. This page does not provide much explanation or detail. For more information on various aspects of smithy4s, read through the other sections of this documentation site.",source:"@site/../docs/target/jvm-2.13/mdoc/01-overview/02-quickstart.md",sourceDirName:"01-overview",slug:"/overview/quickstart",permalink:"/smithy4s/docs/overview/quickstart",draft:!1,editUrl:"https://github.com/disneystreaming/smithy4s/edit/main/modules/docs/src/01-overview/02-quickstart.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_label:"Quick Start",title:"Quick Start"},sidebar:"tutorialSidebar",previous:{title:"Intro",permalink:"/smithy4s/docs/overview/intro"},next:{title:"Installation",permalink:"/smithy4s/docs/overview/installation"}},s={},m=[{value:"For sbt",id:"for-sbt",level:2},{value:"project/plugins.sbt",id:"projectpluginssbt",level:3},{value:"build.sbt",id:"buildsbt",level:3},{value:"For Mill",id:"for-mill",level:2},{value:"Smithy content",id:"smithy-content",level:2},{value:"Using the generated code",id:"using-the-generated-code",level:2},{value:"Run Service",id:"run-service",level:2},{value:"Navigate to localhost:9000/docs",id:"navigate-to-localhost9000docs",level:2},{value:"Client Example",id:"client-example",level:2}],p={toc:m},c="wrapper";function u(e){let{components:t,...n}=e;return(0,l.kt)(c,(0,i.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,l.kt)("p",null,"Below is a quick example of smithy4s in action. This page does not provide much explanation or detail. For more information on various aspects of smithy4s, read through the other sections of this documentation site."),(0,l.kt)("h2",{id:"for-sbt"},"For sbt"),(0,l.kt)("p",null,"This section will get you started with a simple ",(0,l.kt)("inlineCode",{parentName:"p"},"sbt")," module that enables smithy4s code generation. For a similar setup for mill, see ",(0,l.kt)("a",{parentName:"p",href:"#for-mill"},"Mill")," below."),(0,l.kt)("h3",{id:"projectpluginssbt"},"project/plugins.sbt"),(0,l.kt)("p",null,"Add the ",(0,l.kt)("inlineCode",{parentName:"p"},"smithy4s-sbt-codegen")," plugin to your build."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-scala"},'addSbtPlugin("com.disneystreaming.smithy4s" % "smithy4s-sbt-codegen" % "0.18.10")\n')),(0,l.kt)("h3",{id:"buildsbt"},"build.sbt"),(0,l.kt)("p",null,"Enable the plugin in your project, add the smithy and http4s dependencies."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-scala"},'import smithy4s.codegen.Smithy4sCodegenPlugin\n\nThisBuild / scalaVersion := "2.13.12"\n\nval example = project\n .in(file("modules/example"))\n .enablePlugins(Smithy4sCodegenPlugin)\n .settings(\n libraryDependencies ++= Seq(\n "com.disneystreaming.smithy4s" %% "smithy4s-http4s" % smithy4sVersion.value,\n "com.disneystreaming.smithy4s" %% "smithy4s-http4s-swagger" % smithy4sVersion.value,\n "org.http4s" %% "http4s-ember-server" % "0.23.25"\n )\n )\n')),(0,l.kt)("h2",{id:"for-mill"},"For Mill"),(0,l.kt)("p",null,"This section will get you started with a ",(0,l.kt)("inlineCode",{parentName:"p"},"mill")," module with code generation enabled on it."),(0,l.kt)("p",null,"In your ",(0,l.kt)("inlineCode",{parentName:"p"},"build.sc"),":"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-scala"},'import $ivy.`com.disneystreaming.smithy4s::smithy4s-mill-codegen-plugin::0.18.10`\nimport smithy4s.codegen.mill._\n\nimport mill._, mill.scalalib._\nobject example extends ScalaModule with Smithy4sModule {\n def scalaVersion = "2.13.8"\n override def ivyDeps = Agg(\n ivy"com.disneystreaming.smithy4s::smithy4s-core:${smithy4sVersion()}",\n ivy"com.disneystreaming.smithy4s::smithy4s-http4s-swagger:${smithy4sVersion()}",\n ivy"org.http4s::http4s-ember-server:0.23.25"\n )\n}\n')),(0,l.kt)("h2",{id:"smithy-content"},"Smithy content"),(0,l.kt)("p",null,"Now is the time to add some Smithy shapes to see what code generation can do for you. Following the setup above, the location for the Smithy content will change depending on what build tool you used."),(0,l.kt)("p",null,"Now let's define an API in Smithy. Create the following file:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"for ",(0,l.kt)("inlineCode",{parentName:"li"},"sbt"),", you'll write in ",(0,l.kt)("inlineCode",{parentName:"li"},"modules/example/src/main/smithy/ExampleService.smithy"),"."),(0,l.kt)("li",{parentName:"ul"},"for ",(0,l.kt)("inlineCode",{parentName:"li"},"mill"),", you'll write in ",(0,l.kt)("inlineCode",{parentName:"li"},"example/smithy/ExampleService.smithy"))),(0,l.kt)("p",null,"And add the content below:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-kotlin"},'namespace smithy4s.hello\n\nuse alloy#simpleRestJson\n\n@simpleRestJson\nservice HelloWorldService {\n version: "1.0.0",\n operations: [Hello]\n}\n\n@http(method: "POST", uri: "/{name}", code: 200)\noperation Hello {\n input: Person,\n output: Greeting\n}\n\nstructure Person {\n @httpLabel\n @required\n name: String,\n\n @httpQuery("town")\n town: String\n}\n\nstructure Greeting {\n @required\n message: String\n}\n')),(0,l.kt)("p",null,"The Scala code corresponding to this smithy file will be generated the next time you compile your project."),(0,l.kt)("h2",{id:"using-the-generated-code"},"Using the generated code"),(0,l.kt)("p",null,"Now, let's use the generated code by the service. You need to create a scala file at the following location:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"for sbt ",(0,l.kt)("inlineCode",{parentName:"li"},"modules/example/src/main/scala/Main.scala")),(0,l.kt)("li",{parentName:"ul"},"for mill ",(0,l.kt)("inlineCode",{parentName:"li"},"example/src/Main.scala"))),(0,l.kt)("p",null,"Implement your service by extending the generated Service trait. Wire up routes into server."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-scala"},'import smithy4s.example.hello._\nimport cats.effect._\nimport cats.implicits._\nimport org.http4s.implicits._\nimport org.http4s.ember.server._\nimport org.http4s._\nimport com.comcast.ip4s._\nimport smithy4s.http4s.SimpleRestJsonBuilder\n\nobject HelloWorldImpl extends HelloWorldService[IO] {\n def hello(name: String, town: Option[String]): IO[Greeting] = IO.pure {\n town match {\n case None => Greeting(s"Hello $name!")\n case Some(t) => Greeting(s"Hello $name from $t!")\n }\n }\n}\n\nobject Routes {\n private val example: Resource[IO, HttpRoutes[IO]] =\n SimpleRestJsonBuilder.routes(HelloWorldImpl).resource\n\n private val docs: HttpRoutes[IO] =\n smithy4s.http4s.swagger.docs[IO](HelloWorldService)\n\n val all: Resource[IO, HttpRoutes[IO]] = example.map(_ <+> docs)\n}\n\nobject Main extends IOApp.Simple {\n\n val run = Routes.all\n .flatMap { routes =>\n EmberServerBuilder\n .default[IO]\n .withPort(port"9000")\n .withHost(host"localhost")\n .withHttpApp(routes.orNotFound)\n .build\n }\n .use(_ => IO.never)\n\n}\n')),(0,l.kt)("h2",{id:"run-service"},"Run Service"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"for sbt: ",(0,l.kt)("inlineCode",{parentName:"li"},'sbt "example/run"')),(0,l.kt)("li",{parentName:"ul"},"for mill: ",(0,l.kt)("inlineCode",{parentName:"li"},"mill example.run"))),(0,l.kt)("h2",{id:"navigate-to-localhost9000docs"},"Navigate to localhost:9000/docs"),(0,l.kt)("p",null,"Here you will find the automatically generated SwaggerUI which will allow you to easily test your API."),(0,l.kt)("p",null,(0,l.kt)("img",{parentName:"p",src:"https://i.imgur.com/WQgetF6.png",alt:"SwaggerUI documentation site request"})),(0,l.kt)("p",null,(0,l.kt)("img",{parentName:"p",src:"https://i.imgur.com/JRUQyny.png",alt:"SwaggerUI documentation site response"})),(0,l.kt)("h2",{id:"client-example"},"Client Example"),(0,l.kt)("p",null,"You can also generate a client using smithy4s."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-scala"},'import org.http4s.ember.client.EmberClientBuilder\n\nobject ClientImpl extends IOApp.Simple {\n\n val helloWorldClient: Resource[IO, HelloWorldService[IO]] = for {\n client <- EmberClientBuilder.default[IO].build\n helloClient <- SimpleRestJsonBuilder(HelloWorldService)\n .client(client)\n .uri(Uri.unsafeFromString("http://localhost:9000"))\n .resource\n } yield helloClient\n\n val run = helloWorldClient.use(c =>\n c.hello("Sam", Some("New York City"))\n .flatMap(greeting => IO.println(greeting.message))\n )\n\n}\n')))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/abe01ffb.f73783d1.js b/assets/js/abe01ffb.61dfaea6.js similarity index 99% rename from assets/js/abe01ffb.f73783d1.js rename to assets/js/abe01ffb.61dfaea6.js index 3786e5f3b..b5d765e8f 100644 --- a/assets/js/abe01ffb.f73783d1.js +++ b/assets/js/abe01ffb.61dfaea6.js @@ -1 +1 @@ -"use strict";(self.webpackChunksmithy4s=self.webpackChunksmithy4s||[]).push([[9905],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>m});var a=n(7294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function r(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var l=a.createContext({}),p=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},c=function(e){var t=p(e.components);return a.createElement(l.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var n=e.components,i=e.mdxType,o=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),d=p(n),h=i,m=d["".concat(l,".").concat(h)]||d[h]||u[h]||o;return n?a.createElement(m,r(r({ref:t},c),{},{components:n})):a.createElement(m,r({ref:t},c))}));function m(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=n.length,r=new Array(o);r[0]=h;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[d]="string"==typeof e?e:i,r[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>r,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>p});var a=n(7462),i=(n(7294),n(3905));const o={sidebar_label:"Services and endpoints",title:"Services and endpoints"},r=void 0,s={unversionedId:"design/services",id:"design/services",title:"Services and endpoints",description:"In addition to relying heavily on a Schema construct, which enables abstracting over serialisation, Smithy4s uses abstractions to codify the notion of interface, to allow for interoperability with various communication protocols. The idea is to reason generically about things of this shape :",source:"@site/../docs/target/jvm-2.13/mdoc/05-design/03-services.md",sourceDirName:"05-design",slug:"/design/services",permalink:"/smithy4s/docs/design/services",draft:!1,editUrl:"https://github.com/disneystreaming/smithy4s/edit/main/modules/docs/src/05-design/03-services.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_label:"Services and endpoints",title:"Services and endpoints"},sidebar:"tutorialSidebar",previous:{title:"Datatypes and schemas",permalink:"/smithy4s/docs/design/schemas"},next:{title:"Dynamic module",permalink:"/smithy4s/docs/guides/dynamic"}},l={},p=[{value:"The duality of final and initial algebras",id:"the-duality-of-final-and-initial-algebras",level:2},{value:"A detour around kinds",id:"a-detour-around-kinds",level:3},{value:"Input",id:"input",level:4},{value:"Error",id:"error",level:4},{value:"Output",id:"output",level:4},{value:"StreamedInput, StreamedOutput",id:"streamedinput-streamedoutput",level:4},{value:"Transformation",id:"transformation",level:3},{value:"Codifying the duality between initial and final algebras",id:"codifying-the-duality-between-initial-and-final-algebras",level:3},{value:"The high-level philosophy of Smithy4s",id:"the-high-level-philosophy-of-smithy4s",level:2},{value:"Logical flow: client-side",id:"logical-flow-client-side",level:3},{value:"Logical flow: server-side",id:"logical-flow-server-side",level:3},{value:"A note about efficiency",id:"a-note-about-efficiency",level:3},{value:"The Endpoint abstraction",id:"the-endpoint-abstraction",level:2},{value:"A note on errors",id:"a-note-on-errors",level:3},{value:"Services and endpoints",id:"services-and-endpoints",level:2},{value:"Conclusion and complete interfaces",id:"conclusion-and-complete-interfaces",level:2}],c={toc:p},d="wrapper";function u(e){let{components:t,...n}=e;return(0,i.kt)(d,(0,a.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("p",null,"In addition to relying heavily on a ",(0,i.kt)("inlineCode",{parentName:"p"},"Schema")," construct, which enables abstracting over serialisation, Smithy4s uses abstractions to codify the notion of interface, to allow for interoperability with various communication protocols. The idea is to reason generically about things of this shape :"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},"trait Interface[Context[_]]{\n def operation1(a: A, b: B): Context[Output1]\n def operation2(c: C, d: D, e: E): Context[Output2]\n}\n")),(0,i.kt)("p",null,"This generalisation enables the easy interpretation of implementations of such interfaces into services (HTTP, RPC, etc), or conversely, the derivation of stub instances of these interfaces to talk to remote services."),(0,i.kt)("p",null,"The creation of an abstraction that allows for this generalisation is a problem similar to the one that lead to the ",(0,i.kt)("inlineCode",{parentName:"p"},"Schema"),' construct: one needs to deconstruct the notion of "interface" into fundamental building blocks.'),(0,i.kt)("h2",{id:"the-duality-of-final-and-initial-algebras"},"The duality of final and initial algebras"),(0,i.kt)("p",null,"Before we dive into the core of the solution, one notion that is drastically helpful is the duality between finally-encoded algebras and initially-encoded algebras."),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},"Finally-encoded algebras are object-oriented encodings of a set of operations, just like above: operations are represented as ",(0,i.kt)("strong",{parentName:"p"},"methods"),' in an interface. Interpretation of expressions written in terms of these methods does not involve any runtime transformation from one context to another: the method call is merely executed. In other words, when they are executed, expressions coming from finally-encoded algebras are already in their "final form".')),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},"Conversely, initially-encoded algebras represent expressions as ",(0,i.kt)("strong",{parentName:"p"},"data"),", implying that interpretation involves a transformation of this data into lower level method calls. However, ",(0,i.kt)("strong",{parentName:"p"},"data")," has the quality of being a first class construct in programming languages, meaning you can pass it around and use it as parameter to functions. This allows for the unification of code-paths, as the differences between some aspects of a bit of logic can be absorbed by the data and handled later on."))),(0,i.kt)("p",null,"Finally-encoded KVStore algebra :"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},"trait KVStore[Context[_]]{\n def put(key: String, value: String): Context[Unit]\n def get(key: String) : Context[Option[String]]\n def delete(key: String) : Context[Unit]\n}\n")),(0,i.kt)("p",null,"Initially-encoded KVStore algebra :"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},"sealed trait KVStoreOp[Output]\nobject KVStoreOp {\n case class Put(key: String, value: String) extends KVStore[Unit]\n case class Get(key: String) extends KVStore[Option[String]]\n case class Delete(key: String) extends KVStore[Unit]\n}\n")),(0,i.kt)("p",null,"These two encodings contain a similar amount of information. It is nearly-trivial to go from a ",(0,i.kt)("inlineCode",{parentName:"p"},"KVstore[Context]")," instance to a ",(0,i.kt)("inlineCode",{parentName:"p"},"KVStoreOp ~> Context")," polymorphic function (natural-transformation), and vice versa:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},"trait ~>[F[_], G[_]]{\n def apply[A](fa: F[A]): G[A]\n}\n\ndef asNaturalTransformation[Context[_]](impl: KVStore[Context]) = new (KVStoreOp ~> Context){\n def apply[A](fa: KVStoreOp[A]): Context[A] = fa match {\n case KVStoreOp.Put(key, value) => impl.put(key, value)\n case KVStoreOp.Get(key) => impl.get(key)\n case KVStoreOp.Delete(key) => impl.delete(key)\n }\n}\n\ndef fromNaturalTransformation[Context[_]](run: KVStoreOp ~> Context) = new KVStore[Context]{\n def put(key: String, value: String) = run(KVStoreOp.Put(key, value))\n def get(key: String) = run(KVStoreOp.Get(key))\n def delete(key: String) = run(KVStoreOp.Delete(key))\n}\n")),(0,i.kt)("p",null,"This duality is heavily used by Smithy4s: finally-encoded interfaces are generally more natural to Scala developers, and are better supported in editors (autocompletion, etc). But from an implementation's perspective, the initial, data-based encoding is really interesting, because operations are reified as ",(0,i.kt)("strong",{parentName:"p"},"data-types")," that can be associated with instances of generic type-classes: it is possible to abstract over data, it is not possible to abstract over method calls."),(0,i.kt)("h3",{id:"a-detour-around-kinds"},"A detour around kinds"),(0,i.kt)("p",null,"The methods generated by Smithy4s are conceptually similar to the methods expressed in the example above, except that the output types are significantly more verbose."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},"trait Interface[Context[_, _, _, _, _,]]{\n def operation1(a: A, b: B): Context[Input, Error, Output, StreamedInput, StreamedOutput]\n}\n")),(0,i.kt)("p",null,"Let's address this awkwardness right away, by explaining the rationale behind this seemingly humongous signature :"),(0,i.kt)("h4",{id:"input"},"Input"),(0,i.kt)("p",null,"It's the input type of an operation. Typically, a case class that holds fields matching the method parameters. We keep track of it in the return type for several reasons:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"In the internal logic of Smithy4s, It prevents having to prematurely shoe-horn kinds into other kinds by means of injection/projection, which helps both implementor and compiler alike"),(0,i.kt)("li",{parentName:"ul"},"It will come in handy for the implementation of some pagination-aware interpreters, as pagination typically works by performing a modification of the previous input in order to get the next batch (page) of results. This implies that the input (and therefore its type) must be tracked across several requests resulting from a single method call.")),(0,i.kt)("h4",{id:"error"},"Error"),(0,i.kt)("p",null,"The execution of an operation can result in errors. The Smithy language allows for tying a list of errors to operations. When generating the associated code, Smithy4s synthesize a union. This allows the coproduct of errors associated to an operation to be represented as a bona fide Scala type, which we can abstract over via some type-class instance. This is also very useful for the writing of bi-functor interpreters, for users that are interested in this kind of UX."),(0,i.kt)("h4",{id:"output"},"Output"),(0,i.kt)("p",null,"No surprise there: this is the data resulting from the run of the operation."),(0,i.kt)("h4",{id:"streamedinput-streamedoutput"},"StreamedInput, StreamedOutput"),(0,i.kt)("p",null,"Smithy supports the concept of ",(0,i.kt)("a",{parentName:"p",href:"https://awslabs.github.io/smithy/1.0/spec/core/stream-traits.html?highlight=streaming#streaming-trait"},"Streaming"),'. It is communicated as a trait that annotates a single field of the input shape or/and output shape of an operation. Scala does not have a "standard" way of expressing streaming semantics. Moreover, streaming constructs in Scala are heavily context dependant. It is therefore impossible for us to incorporate the concept of "streaming" to our ',(0,i.kt)("inlineCode",{parentName:"p"},"Schema")," construct as it is meant to be context-free and third-party-free."),(0,i.kt)("p",null,"To get some intuition for why that is: say we want to express streaming using ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/typelevel/fs2/"},"fs2"),". If we naively generate a case class that has one of its fields annotated with ",(0,i.kt)("inlineCode",{parentName:"p"},"@streaming"),", it means that the the field is of type ",(0,i.kt)("inlineCode",{parentName:"p"},"fs2.Stream[F, A]"),", which means that we either need to make a decision on what the ",(0,i.kt)("inlineCode",{parentName:"p"},"F")," is, which is not okay for obvious reasons, or we need to propagate the ",(0,i.kt)("inlineCode",{parentName:"p"},"F[_]")," type parameter upward to the case class. Now our ",(0,i.kt)("inlineCode",{parentName:"p"},"Schema")," value, which accompanies the case-class, also have to carry the ",(0,i.kt)("inlineCode",{parentName:"p"},"F")," ... this propagates throughout the whole codebase. We deemed that not acceptable."),(0,i.kt)("p",null,"Rather than polluting all layers of abstraction, we decided to just have the concept of operation be impacted and hold the streamed type in a separate type parameter. This allows for interpreters from various ecosystem to emerge. It also has the quality of allowing users to access the unary component of outputs (ie, data that is communicated in the headers of HTTP responses) without necessarily allocating resources to consume the streamed component of the output."),(0,i.kt)("p",null,"NB: at the time of writing this, Smithy4s does not have any streaming-aware interpreter implemented. But streaming is such a fundamental notion in remote interactions, and we had to devise a plan to ensure that third parties could decide to implement interpreters without waiting."),(0,i.kt)("h3",{id:"transformation"},"Transformation"),(0,i.kt)("p",null,"Because of the complex kinds we're dealing with, we codify a polymorphic function (natural-transformation), called ",(0,i.kt)("inlineCode",{parentName:"p"},"smithy4s.kinds.PolyFunction5")," that allows us to work at this level :"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},"trait PolyFunction5[F[_, _, _, _, _], G[_, _, _, _, _]] {\n def apply[I, E, O, SI, SO](fa: F[I, E, O, SI, SO]): G[I, E, O, SI, SO]\n}\n")),(0,i.kt)("p",null,"This is a mouthful, but conceptually, it's exactly the same as our good old polymorphic function typically aliased to ",(0,i.kt)("inlineCode",{parentName:"p"},"~>"),"."),(0,i.kt)("h3",{id:"codifying-the-duality-between-initial-and-final-algebras"},"Codifying the duality between initial and final algebras"),(0,i.kt)("p",null,"What we want users to manipulate is the final-encoded version of a service: a good-old object-oriented interface that has decent editor support. But we need the initial-encoded version to implement interpreters in a generic fashion."),(0,i.kt)("p",null,"So we codify the duality to allow for switching from one to the other via an abstraction called ",(0,i.kt)("inlineCode",{parentName:"p"},"Smithy4s.Service"),", which is the entry point to all interpreters."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},"trait Service[Final[_[_, _, _, _, _]]] {\n type Operation[_, _, _, _, _]\n def toPolyFunction[F[_, _, _, _, _,]](alg: Final[F]): PolyFunction5[Operation, F]\n def fromPolyFunction[F[_, _, _, _, _]](polyFunction: PolyFunction5[Operation, F]): Final[F]\n\n // ...\n}\n")),(0,i.kt)("p",null,"Implementations of such interfaces are typically code-generated. This implies that any smithy ",(0,i.kt)("inlineCode",{parentName:"p"},"Service")," shape gets translated as a finally-encoded interface, but also as an initially-encoded ",(0,i.kt)("inlineCode",{parentName:"p"},"GADT")),(0,i.kt)("h2",{id:"the-high-level-philosophy-of-smithy4s"},"The high-level philosophy of Smithy4s"),(0,i.kt)("p",null,"The goal of Smithy4s is to allow users to derive client stubs and routers in various protocols, by running the generated code (or instances of generated interfaces) in some one-liner functions. To that end, Smithy4s surfaces a number of abstractions (such as ",(0,i.kt)("inlineCode",{parentName:"p"},"smithy4s.schema.Schema"),") that allow for the implementation of (very) polymorphic interpreters. These interpreters operate on the generated code, which reflects what the user defines in their smithy Specs."),(0,i.kt)("p",null,"The abstractions used by interpreters contain all the elements that allow for turning a high-level method call (from an interface generated by Smithy4s) into a low level request of some sort, and then transform a low level response into the output of the method call."),(0,i.kt)("h3",{id:"logical-flow-client-side"},"Logical flow: client-side"),(0,i.kt)("p",null,"Conceptually, to derive a high-level client that uses some sort of ",(0,i.kt)("inlineCode",{parentName:"p"},"Request => Response")," protocol, the implementation has to follow a sequence of steps:"),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Assuming this method call: ",(0,i.kt)("inlineCode",{parentName:"li"},'kvstore.get("key")')),(0,i.kt)("li",{parentName:"ol"},"turning the method call into a piece of data: ",(0,i.kt)("inlineCode",{parentName:"li"},'KVStoreOp.Get("key")')," using the initially-encoded dual of the ",(0,i.kt)("inlineCode",{parentName:"li"},"KVStore")," interface"),(0,i.kt)("li",{parentName:"ol"},"Retrieving the Smithy4s ",(0,i.kt)("inlineCode",{parentName:"li"},"Schemas")," (input and output) associated to the ",(0,i.kt)("inlineCode",{parentName:"li"},"Get")," operation"),(0,i.kt)("li",{parentName:"ol"},"Compiling the schema associated to the input of the ",(0,i.kt)("inlineCode",{parentName:"li"},"Get")," operation into some encoding function: ",(0,i.kt)("inlineCode",{parentName:"li"},"GetInput => Request")),(0,i.kt)("li",{parentName:"ol"},"Running the request through a low-level ",(0,i.kt)("inlineCode",{parentName:"li"},"Request => Response")," function (like an HTTP client)"),(0,i.kt)("li",{parentName:"ol"},"Running ",(0,i.kt)("inlineCode",{parentName:"li"},"Get")," into some function that gives us its ",(0,i.kt)("inlineCode",{parentName:"li"},"GetInput")," representation"),(0,i.kt)("li",{parentName:"ol"},"Compiling the schema associated to the output (",(0,i.kt)("inlineCode",{parentName:"li"},"GetOutput")," ~= ",(0,i.kt)("inlineCode",{parentName:"li"},"Option[String]"),") of the ",(0,i.kt)("inlineCode",{parentName:"li"},"Get")," operation into some decoding function ",(0,i.kt)("inlineCode",{parentName:"li"},"Response => Output"))),(0,i.kt)("p",null,"So we get ",(0,i.kt)("inlineCode",{parentName:"p"},"kvstore.get => KVStoreOp.Get => GetInput => Request => Response => GetOutput"),", which gives us the full data flow, client side."),(0,i.kt)("h3",{id:"logical-flow-server-side"},"Logical flow: server-side"),(0,i.kt)("p",null,"The server side is different in that we want to derive the ",(0,i.kt)("inlineCode",{parentName:"p"},"Request => Response")," function from an instance of our interface (",(0,i.kt)("inlineCode",{parentName:"p"},"KVStore"),"). The goal is to mechanically translate a request into a method call, and a method's output into a response. The sequence:"),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"From a given ",(0,i.kt)("inlineCode",{parentName:"li"},"Request"),", find the corresponding operation ",(0,i.kt)("inlineCode",{parentName:"li"},"Op")," (for instance, by means of HTTP path). Let's assume it's the ",(0,i.kt)("inlineCode",{parentName:"li"},"get")," operation,"),(0,i.kt)("li",{parentName:"ol"},"Retrieve the Smithy4s ",(0,i.kt)("inlineCode",{parentName:"li"},"Schemas")," (input and output) associated to the operation (",(0,i.kt)("inlineCode",{parentName:"li"},"KVStoreOp.Get"),")"),(0,i.kt)("li",{parentName:"ol"},"Compile a ",(0,i.kt)("inlineCode",{parentName:"li"},"Request => GetInput")," decoding function, and run the ",(0,i.kt)("inlineCode",{parentName:"li"},"Request")," through it"),(0,i.kt)("li",{parentName:"ol"},"From ",(0,i.kt)("inlineCode",{parentName:"li"},"GetInput"),", recreate the ",(0,i.kt)("inlineCode",{parentName:"li"},"KVStoreOp.Get")," instance"),(0,i.kt)("li",{parentName:"ol"},"From ",(0,i.kt)("inlineCode",{parentName:"li"},"KVStoreOp.Get"),", use the final-encoded dual of ",(0,i.kt)("inlineCode",{parentName:"li"},"KVStoreOp")," to call the ",(0,i.kt)("inlineCode",{parentName:"li"},"KVStore#get")," method (implemented by the user). This gets us an ",(0,i.kt)("inlineCode",{parentName:"li"},"GetOutput")),(0,i.kt)("li",{parentName:"ol"},"Compile a ",(0,i.kt)("inlineCode",{parentName:"li"},"GetOutput => Response")," encoding function from the schemas, and run the output through it")),(0,i.kt)("p",null,"So we get ",(0,i.kt)("inlineCode",{parentName:"p"},"Request => KVStoreOp.GetInput => KVStoreOp.Get => kvstore.get => GetOutput => Response"),", which gives us the full data flow, service side."),(0,i.kt)("p",null,"Both the service-side and client-side logical flows guide the design of the abstractions that are exposed by Smithy4s."),(0,i.kt)("h3",{id:"a-note-about-efficiency"},"A note about efficiency"),(0,i.kt)("p",null,"The flows described above are merely conceptual, and do not account for the optimisations involved to ensure that schemas are not recompiled into codecs on a per-request basis (which would greatly impact performance). Interpreters provided by Smithy4s (HTTP and co) are written to ensure that all compilation is performed ahead of receiving requests, by means of preliminary computations and caching."),(0,i.kt)("h2",{id:"the-endpoint-abstraction"},"The Endpoint abstraction"),(0,i.kt)("p",null,"The ",(0,i.kt)("inlineCode",{parentName:"p"},"smithy4s.Endpoint")," abstraction ties a specific operation to the various schemas that are tied to it."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},"trait Endpoint[Op[_, _, _, _, _], I, E, O, SI, SO] {\n def schema: OperationSchema[I, E, O, SI, SO]\n def wrap(input: I): Op[I, E, O, SI, SO]\n}\n")),(0,i.kt)("p",null,"where ",(0,i.kt)("inlineCode",{parentName:"p"},"smithy4s.schema.OperationSchema")," is a product of all schemas involved in an specific operation."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},"final case class OperationSchema[I, E, O, SI, SO](\n id: ShapeId,\n hints: Hints,\n input: Schema[I],\n error: Option[ErrorSchema[E]],\n output: Schema[O],\n streamedInput: Option[StreamingSchema[SI]],\n streamedOutput: Option[StreamingSchema[SO]]\n) {\n\n")),(0,i.kt)("p",null,"Endpoints are not type-classes. Instead, an ",(0,i.kt)("inlineCode",{parentName:"p"},"Endpoint")," instance is provided by the companion object of each member of the ",(0,i.kt)("inlineCode",{parentName:"p"},"GADT")," forming the initial-encoding of the service interface. So, going back to our ",(0,i.kt)("inlineCode",{parentName:"p"},"KVStore"),", the corresponding sealed-trait would look like this :"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},"sealed trait KVStoreOp[Input, Error, Output, StreamedInput, StreamedOutput]\n")),(0,i.kt)("p",null,"and the ",(0,i.kt)("inlineCode",{parentName:"p"},"put")," operation would look like :"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},'case class Put(input: PutRequest) extends KVStoreOp[PutRequest, PutError, PutResult, Nothing, Nothing]\nobject Put extends Endpoint[KVStoreOp, PutRequest, PutError, PutResult, Nothing, Nothing] {\n val input = PutRequest.input\n val output = PutRequest.schema\n val streamedInput = SteamingSchema.nothing\n val streamedOutput = StreamingSchema.nothing\n val errorable: Option[Errorable[PutResult]] = this\n // ...\n val schema: OperationSchema[PutRequest, PutError, PutResult, Nothing, Nothing] =\n Schema.operation(ShapeId("namespace", "Put"))\n .withInput(PutRequest.schema)\n .withError(PutError.errorSchema)\n .withOutput(PutResult.schema)\n def wrap(input: PutRequest) = Put(input)\n}\n')),(0,i.kt)("h3",{id:"a-note-on-errors"},"A note on errors"),(0,i.kt)("p",null,"As stated previously, Smithy4s generates a coproduct type for each operation, where the members of the coproduct point to the various errors listed in the smithy operation shape. Additionally, each structure annotated with ",(0,i.kt)("inlineCode",{parentName:"p"},"@error")," in smithy is rendered as a case-class that extends ",(0,i.kt)("inlineCode",{parentName:"p"},"Throwable"),", because ",(0,i.kt)("inlineCode",{parentName:"p"},"Throwables")," are the de-facto standard of doing error handling on the JVM. Even libraries that use ",(0,i.kt)("inlineCode",{parentName:"p"},"Either")," to perform error handling often represent the left-hand-side of the Either as some throwable type, to facilitate the absorption of errors into the error-channels of monadic constructs (",(0,i.kt)("inlineCode",{parentName:"p"},"IO.raiseError"),", etc)"),(0,i.kt)("p",null,"As a result, it is important for Smithy4s to expose functions that generically enable the filtering of throwables against the ",(0,i.kt)("inlineCode",{parentName:"p"},"Error")," type parameter of an operation, so that interpreters can intercept errors and apply the correct encoding (dictated via ",(0,i.kt)("inlineCode",{parentName:"p"},"Schema"),") before communicating them back to the caller over the wire. Conversely, it is important to expose a function that allows to go from the generic ",(0,i.kt)("inlineCode",{parentName:"p"},"Error")," type parameter to ",(0,i.kt)("inlineCode",{parentName:"p"},"Throwable"),", so that errors received via low-level communication channels can be turned into ",(0,i.kt)("inlineCode",{parentName:"p"},"Throwable")," at the client call site, in order to populate the relevant error channel when exposing mono-functor semantics."),(0,i.kt)("p",null,"Therefore, when a smithy operation has ",(0,i.kt)("inlineCode",{parentName:"p"},"errors")," defined, the corresponding ",(0,i.kt)("inlineCode",{parentName:"p"},"smithy4s.schema.OperationSchema")," references a ",(0,i.kt)("inlineCode",{parentName:"p"},"smithy4s.schema.ErrorSchema"),", which looks like this :"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},"case class ErrorSchema[E] private[smithy4s] (\n schema: Schema[E],\n liftError: Throwable => Option[E],\n unliftError: E => Throwable\n)\n")),(0,i.kt)("h2",{id:"services-and-endpoints"},"Services and endpoints"),(0,i.kt)("p",null,"In order to implement any server-side interpreters, it is required to have a list of endpoints. That list is used to implement some matching logic based on the ",(0,i.kt)("inlineCode",{parentName:"p"},"shapeId")," and/or the ",(0,i.kt)("inlineCode",{parentName:"p"},"hints")," associated to the endpoints, in order to deterministically decide where to route a low level ",(0,i.kt)("inlineCode",{parentName:"p"},"Request")," to a specific ",(0,i.kt)("inlineCode",{parentName:"p"},"Endpoint")," instance."),(0,i.kt)("p",null,"For instance, smithy provides a ",(0,i.kt)("inlineCode",{parentName:"p"},"@http")," trait out of the box that can annotate operations :"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-kotlin"},'service KVStore {\n operations: [Get, Put]\n}\n\n@http(method: "GET", uri: "/resource/${key}, code: 200)\noperation Get {\n input: GetInput\n output: GetOutput\n}\n\nstructure GetInput {\n @httpLabel\n key: String\n}\n\nstructure GetOutput {\n value: String\n}\n\n@http(method: "PUT", uri: "/resource/${key}, code: 200)\noperation Put {\n\n}\n\nstructure PutInput {\n @httpLabel\n key: String,\n @httpPayload\n value: String\n}\n')),(0,i.kt)("p",null,"Each ",(0,i.kt)("inlineCode",{parentName:"p"},"@http")," occurrence get translated to a scala value in the ",(0,i.kt)("inlineCode",{parentName:"p"},"Hints")," associated to the corresponding endpoint."),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"On server-side, having a list of all the endpoints associated to a service allows for creating a routing logic that dispatches an HTTP Request to the correct endpoint."),(0,i.kt)("li",{parentName:"ul"},"On client-side, a method call to a service stub gets translated to an instance of the corresponding ",(0,i.kt)("inlineCode",{parentName:"li"},"GADT")," member. From there, we have to retrieve the schemas associated to the member in question. Additionally, we need to extract the input value out of the member, to run it through an encoder derived from the the associated ",(0,i.kt)("inlineCode",{parentName:"li"},"Schema"),".")),(0,i.kt)("p",null,"Therefore, the ",(0,i.kt)("inlineCode",{parentName:"p"},"Service")," abstraction needs to be enriched with the following methods :"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},"trait Service[Final[_[_, _, _, _, _]]] {\n\n type Initial[_, _, _, _, _]\n\n // ...\n\n // useful for server-side\n def endpoints: IndexedSeq[Endpoint[Initial, _, _, _, _, _]]\n // useful for client-side\n\n // provides the index of the endpoint associated to the operation\n def ordinal[I, E, O, SI, SO](op: Initial[I, E, O, SI, SO]): Int\n // extracts the input value out of a reified operation\n def input[I, E, O, SI, SO](op: Operation[I, E, O, SI, SO]): I\n\n}\n")),(0,i.kt)("h2",{id:"conclusion-and-complete-interfaces"},"Conclusion and complete interfaces"),(0,i.kt)("p",null,"Here are links to the complete interfaces discussed in this chapter."),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://github.com/disneystreaming/smithy4s/blob/9f2dbcbd29b4dbd35792fa40e423a6395ae3f9e6/modules/core/src/smithy4s/Service.scala"},"Service")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://github.com/disneystreaming/smithy4s/blob/9f2dbcbd29b4dbd35792fa40e423a6395ae3f9e6/modules/core/src/smithy4s/Endpoint.scala"},"Endpoint"))))}u.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunksmithy4s=self.webpackChunksmithy4s||[]).push([[9905],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>m});var a=n(7294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function r(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var l=a.createContext({}),p=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},c=function(e){var t=p(e.components);return a.createElement(l.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var n=e.components,i=e.mdxType,o=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),d=p(n),h=i,m=d["".concat(l,".").concat(h)]||d[h]||u[h]||o;return n?a.createElement(m,r(r({ref:t},c),{},{components:n})):a.createElement(m,r({ref:t},c))}));function m(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=n.length,r=new Array(o);r[0]=h;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[d]="string"==typeof e?e:i,r[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>r,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>p});var a=n(7462),i=(n(7294),n(3905));const o={sidebar_label:"Services and endpoints",title:"Services and endpoints"},r=void 0,s={unversionedId:"design/services",id:"design/services",title:"Services and endpoints",description:"In addition to relying heavily on a Schema construct, which enables abstracting over serialisation, Smithy4s uses abstractions to codify the notion of interface, to allow for interoperability with various communication protocols. The idea is to reason generically about things of this shape :",source:"@site/../docs/target/jvm-2.13/mdoc/05-design/03-services.md",sourceDirName:"05-design",slug:"/design/services",permalink:"/smithy4s/docs/design/services",draft:!1,editUrl:"https://github.com/disneystreaming/smithy4s/edit/main/modules/docs/src/05-design/03-services.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_label:"Services and endpoints",title:"Services and endpoints"},sidebar:"tutorialSidebar",previous:{title:"Datatypes and schemas",permalink:"/smithy4s/docs/design/schemas"},next:{title:"Dynamic module",permalink:"/smithy4s/docs/guides/dynamic"}},l={},p=[{value:"The duality of final and initial algebras",id:"the-duality-of-final-and-initial-algebras",level:2},{value:"A detour around kinds",id:"a-detour-around-kinds",level:3},{value:"Input",id:"input",level:4},{value:"Error",id:"error",level:4},{value:"Output",id:"output",level:4},{value:"StreamedInput, StreamedOutput",id:"streamedinput-streamedoutput",level:4},{value:"Transformation",id:"transformation",level:3},{value:"Codifying the duality between initial and final algebras",id:"codifying-the-duality-between-initial-and-final-algebras",level:3},{value:"The high-level philosophy of Smithy4s",id:"the-high-level-philosophy-of-smithy4s",level:2},{value:"Logical flow: client-side",id:"logical-flow-client-side",level:3},{value:"Logical flow: server-side",id:"logical-flow-server-side",level:3},{value:"A note about efficiency",id:"a-note-about-efficiency",level:3},{value:"The Endpoint abstraction",id:"the-endpoint-abstraction",level:2},{value:"A note on errors",id:"a-note-on-errors",level:3},{value:"Services and endpoints",id:"services-and-endpoints",level:2},{value:"Conclusion and complete interfaces",id:"conclusion-and-complete-interfaces",level:2}],c={toc:p},d="wrapper";function u(e){let{components:t,...n}=e;return(0,i.kt)(d,(0,a.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("p",null,"In addition to relying heavily on a ",(0,i.kt)("inlineCode",{parentName:"p"},"Schema")," construct, which enables abstracting over serialisation, Smithy4s uses abstractions to codify the notion of interface, to allow for interoperability with various communication protocols. The idea is to reason generically about things of this shape :"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},"trait Interface[Context[_]]{\n def operation1(a: A, b: B): Context[Output1]\n def operation2(c: C, d: D, e: E): Context[Output2]\n}\n")),(0,i.kt)("p",null,"This generalisation enables the easy interpretation of implementations of such interfaces into services (HTTP, RPC, etc), or conversely, the derivation of stub instances of these interfaces to talk to remote services."),(0,i.kt)("p",null,"The creation of an abstraction that allows for this generalisation is a problem similar to the one that lead to the ",(0,i.kt)("inlineCode",{parentName:"p"},"Schema"),' construct: one needs to deconstruct the notion of "interface" into fundamental building blocks.'),(0,i.kt)("h2",{id:"the-duality-of-final-and-initial-algebras"},"The duality of final and initial algebras"),(0,i.kt)("p",null,"Before we dive into the core of the solution, one notion that is drastically helpful is the duality between finally-encoded algebras and initially-encoded algebras."),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},"Finally-encoded algebras are object-oriented encodings of a set of operations, just like above: operations are represented as ",(0,i.kt)("strong",{parentName:"p"},"methods"),' in an interface. Interpretation of expressions written in terms of these methods does not involve any runtime transformation from one context to another: the method call is merely executed. In other words, when they are executed, expressions coming from finally-encoded algebras are already in their "final form".')),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},"Conversely, initially-encoded algebras represent expressions as ",(0,i.kt)("strong",{parentName:"p"},"data"),", implying that interpretation involves a transformation of this data into lower level method calls. However, ",(0,i.kt)("strong",{parentName:"p"},"data")," has the quality of being a first class construct in programming languages, meaning you can pass it around and use it as parameter to functions. This allows for the unification of code-paths, as the differences between some aspects of a bit of logic can be absorbed by the data and handled later on."))),(0,i.kt)("p",null,"Finally-encoded KVStore algebra :"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},"trait KVStore[Context[_]]{\n def put(key: String, value: String): Context[Unit]\n def get(key: String) : Context[Option[String]]\n def delete(key: String) : Context[Unit]\n}\n")),(0,i.kt)("p",null,"Initially-encoded KVStore algebra :"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},"sealed trait KVStoreOp[Output]\nobject KVStoreOp {\n case class Put(key: String, value: String) extends KVStore[Unit]\n case class Get(key: String) extends KVStore[Option[String]]\n case class Delete(key: String) extends KVStore[Unit]\n}\n")),(0,i.kt)("p",null,"These two encodings contain a similar amount of information. It is nearly-trivial to go from a ",(0,i.kt)("inlineCode",{parentName:"p"},"KVstore[Context]")," instance to a ",(0,i.kt)("inlineCode",{parentName:"p"},"KVStoreOp ~> Context")," polymorphic function (natural-transformation), and vice versa:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},"trait ~>[F[_], G[_]]{\n def apply[A](fa: F[A]): G[A]\n}\n\ndef asNaturalTransformation[Context[_]](impl: KVStore[Context]) = new (KVStoreOp ~> Context){\n def apply[A](fa: KVStoreOp[A]): Context[A] = fa match {\n case KVStoreOp.Put(key, value) => impl.put(key, value)\n case KVStoreOp.Get(key) => impl.get(key)\n case KVStoreOp.Delete(key) => impl.delete(key)\n }\n}\n\ndef fromNaturalTransformation[Context[_]](run: KVStoreOp ~> Context) = new KVStore[Context]{\n def put(key: String, value: String) = run(KVStoreOp.Put(key, value))\n def get(key: String) = run(KVStoreOp.Get(key))\n def delete(key: String) = run(KVStoreOp.Delete(key))\n}\n")),(0,i.kt)("p",null,"This duality is heavily used by Smithy4s: finally-encoded interfaces are generally more natural to Scala developers, and are better supported in editors (autocompletion, etc). But from an implementation's perspective, the initial, data-based encoding is really interesting, because operations are reified as ",(0,i.kt)("strong",{parentName:"p"},"data-types")," that can be associated with instances of generic type-classes: it is possible to abstract over data, it is not possible to abstract over method calls."),(0,i.kt)("h3",{id:"a-detour-around-kinds"},"A detour around kinds"),(0,i.kt)("p",null,"The methods generated by Smithy4s are conceptually similar to the methods expressed in the example above, except that the output types are significantly more verbose."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},"trait Interface[Context[_, _, _, _, _,]]{\n def operation1(a: A, b: B): Context[Input, Error, Output, StreamedInput, StreamedOutput]\n}\n")),(0,i.kt)("p",null,"Let's address this awkwardness right away, by explaining the rationale behind this seemingly humongous signature :"),(0,i.kt)("h4",{id:"input"},"Input"),(0,i.kt)("p",null,"It's the input type of an operation. Typically, a case class that holds fields matching the method parameters. We keep track of it in the return type for several reasons:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"In the internal logic of Smithy4s, It prevents having to prematurely shoe-horn kinds into other kinds by means of injection/projection, which helps both implementor and compiler alike"),(0,i.kt)("li",{parentName:"ul"},"It will come in handy for the implementation of some pagination-aware interpreters, as pagination typically works by performing a modification of the previous input in order to get the next batch (page) of results. This implies that the input (and therefore its type) must be tracked across several requests resulting from a single method call.")),(0,i.kt)("h4",{id:"error"},"Error"),(0,i.kt)("p",null,"The execution of an operation can result in errors. The Smithy language allows for tying a list of errors to operations. When generating the associated code, Smithy4s synthesize a union. This allows the coproduct of errors associated to an operation to be represented as a bona fide Scala type, which we can abstract over via some type-class instance. This is also very useful for the writing of bi-functor interpreters, for users that are interested in this kind of UX."),(0,i.kt)("h4",{id:"output"},"Output"),(0,i.kt)("p",null,"No surprise there: this is the data resulting from the run of the operation."),(0,i.kt)("h4",{id:"streamedinput-streamedoutput"},"StreamedInput, StreamedOutput"),(0,i.kt)("p",null,"Smithy supports the concept of ",(0,i.kt)("a",{parentName:"p",href:"https://awslabs.github.io/smithy/1.0/spec/core/stream-traits.html?highlight=streaming#streaming-trait"},"Streaming"),'. It is communicated as a trait that annotates a single field of the input shape or/and output shape of an operation. Scala does not have a "standard" way of expressing streaming semantics. Moreover, streaming constructs in Scala are heavily context dependant. It is therefore impossible for us to incorporate the concept of "streaming" to our ',(0,i.kt)("inlineCode",{parentName:"p"},"Schema")," construct as it is meant to be context-free and third-party-free."),(0,i.kt)("p",null,"To get some intuition for why that is: say we want to express streaming using ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/typelevel/fs2/"},"fs2"),". If we naively generate a case class that has one of its fields annotated with ",(0,i.kt)("inlineCode",{parentName:"p"},"@streaming"),", it means that the the field is of type ",(0,i.kt)("inlineCode",{parentName:"p"},"fs2.Stream[F, A]"),", which means that we either need to make a decision on what the ",(0,i.kt)("inlineCode",{parentName:"p"},"F")," is, which is not okay for obvious reasons, or we need to propagate the ",(0,i.kt)("inlineCode",{parentName:"p"},"F[_]")," type parameter upward to the case class. Now our ",(0,i.kt)("inlineCode",{parentName:"p"},"Schema")," value, which accompanies the case-class, also have to carry the ",(0,i.kt)("inlineCode",{parentName:"p"},"F")," ... this propagates throughout the whole codebase. We deemed that not acceptable."),(0,i.kt)("p",null,"Rather than polluting all layers of abstraction, we decided to just have the concept of operation be impacted and hold the streamed type in a separate type parameter. This allows for interpreters from various ecosystem to emerge. It also has the quality of allowing users to access the unary component of outputs (ie, data that is communicated in the headers of HTTP responses) without necessarily allocating resources to consume the streamed component of the output."),(0,i.kt)("p",null,"NB: at the time of writing this, Smithy4s does not have any streaming-aware interpreter implemented. But streaming is such a fundamental notion in remote interactions, and we had to devise a plan to ensure that third parties could decide to implement interpreters without waiting."),(0,i.kt)("h3",{id:"transformation"},"Transformation"),(0,i.kt)("p",null,"Because of the complex kinds we're dealing with, we codify a polymorphic function (natural-transformation), called ",(0,i.kt)("inlineCode",{parentName:"p"},"smithy4s.kinds.PolyFunction5")," that allows us to work at this level :"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},"trait PolyFunction5[F[_, _, _, _, _], G[_, _, _, _, _]] {\n def apply[I, E, O, SI, SO](fa: F[I, E, O, SI, SO]): G[I, E, O, SI, SO]\n}\n")),(0,i.kt)("p",null,"This is a mouthful, but conceptually, it's exactly the same as our good old polymorphic function typically aliased to ",(0,i.kt)("inlineCode",{parentName:"p"},"~>"),"."),(0,i.kt)("h3",{id:"codifying-the-duality-between-initial-and-final-algebras"},"Codifying the duality between initial and final algebras"),(0,i.kt)("p",null,"What we want users to manipulate is the final-encoded version of a service: a good-old object-oriented interface that has decent editor support. But we need the initial-encoded version to implement interpreters in a generic fashion."),(0,i.kt)("p",null,"So we codify the duality to allow for switching from one to the other via an abstraction called ",(0,i.kt)("inlineCode",{parentName:"p"},"Smithy4s.Service"),", which is the entry point to all interpreters."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},"trait Service[Final[_[_, _, _, _, _]]] {\n type Operation[_, _, _, _, _]\n def toPolyFunction[F[_, _, _, _, _,]](alg: Final[F]): PolyFunction5[Operation, F]\n def fromPolyFunction[F[_, _, _, _, _]](polyFunction: PolyFunction5[Operation, F]): Final[F]\n\n // ...\n}\n")),(0,i.kt)("p",null,"Implementations of such interfaces are typically code-generated. This implies that any smithy ",(0,i.kt)("inlineCode",{parentName:"p"},"Service")," shape gets translated as a finally-encoded interface, but also as an initially-encoded ",(0,i.kt)("inlineCode",{parentName:"p"},"GADT")),(0,i.kt)("h2",{id:"the-high-level-philosophy-of-smithy4s"},"The high-level philosophy of Smithy4s"),(0,i.kt)("p",null,"The goal of Smithy4s is to allow users to derive client stubs and routers in various protocols, by running the generated code (or instances of generated interfaces) in some one-liner functions. To that end, Smithy4s surfaces a number of abstractions (such as ",(0,i.kt)("inlineCode",{parentName:"p"},"smithy4s.schema.Schema"),") that allow for the implementation of (very) polymorphic interpreters. These interpreters operate on the generated code, which reflects what the user defines in their smithy Specs."),(0,i.kt)("p",null,"The abstractions used by interpreters contain all the elements that allow for turning a high-level method call (from an interface generated by Smithy4s) into a low level request of some sort, and then transform a low level response into the output of the method call."),(0,i.kt)("h3",{id:"logical-flow-client-side"},"Logical flow: client-side"),(0,i.kt)("p",null,"Conceptually, to derive a high-level client that uses some sort of ",(0,i.kt)("inlineCode",{parentName:"p"},"Request => Response")," protocol, the implementation has to follow a sequence of steps:"),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Assuming this method call: ",(0,i.kt)("inlineCode",{parentName:"li"},'kvstore.get("key")')),(0,i.kt)("li",{parentName:"ol"},"turning the method call into a piece of data: ",(0,i.kt)("inlineCode",{parentName:"li"},'KVStoreOp.Get("key")')," using the initially-encoded dual of the ",(0,i.kt)("inlineCode",{parentName:"li"},"KVStore")," interface"),(0,i.kt)("li",{parentName:"ol"},"Retrieving the Smithy4s ",(0,i.kt)("inlineCode",{parentName:"li"},"Schemas")," (input and output) associated to the ",(0,i.kt)("inlineCode",{parentName:"li"},"Get")," operation"),(0,i.kt)("li",{parentName:"ol"},"Compiling the schema associated to the input of the ",(0,i.kt)("inlineCode",{parentName:"li"},"Get")," operation into some encoding function: ",(0,i.kt)("inlineCode",{parentName:"li"},"GetInput => Request")),(0,i.kt)("li",{parentName:"ol"},"Running the request through a low-level ",(0,i.kt)("inlineCode",{parentName:"li"},"Request => Response")," function (like an HTTP client)"),(0,i.kt)("li",{parentName:"ol"},"Running ",(0,i.kt)("inlineCode",{parentName:"li"},"Get")," into some function that gives us its ",(0,i.kt)("inlineCode",{parentName:"li"},"GetInput")," representation"),(0,i.kt)("li",{parentName:"ol"},"Compiling the schema associated to the output (",(0,i.kt)("inlineCode",{parentName:"li"},"GetOutput")," ~= ",(0,i.kt)("inlineCode",{parentName:"li"},"Option[String]"),") of the ",(0,i.kt)("inlineCode",{parentName:"li"},"Get")," operation into some decoding function ",(0,i.kt)("inlineCode",{parentName:"li"},"Response => Output"))),(0,i.kt)("p",null,"So we get ",(0,i.kt)("inlineCode",{parentName:"p"},"kvstore.get => KVStoreOp.Get => GetInput => Request => Response => GetOutput"),", which gives us the full data flow, client side."),(0,i.kt)("h3",{id:"logical-flow-server-side"},"Logical flow: server-side"),(0,i.kt)("p",null,"The server side is different in that we want to derive the ",(0,i.kt)("inlineCode",{parentName:"p"},"Request => Response")," function from an instance of our interface (",(0,i.kt)("inlineCode",{parentName:"p"},"KVStore"),"). The goal is to mechanically translate a request into a method call, and a method's output into a response. The sequence:"),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"From a given ",(0,i.kt)("inlineCode",{parentName:"li"},"Request"),", find the corresponding operation ",(0,i.kt)("inlineCode",{parentName:"li"},"Op")," (for instance, by means of HTTP path). Let's assume it's the ",(0,i.kt)("inlineCode",{parentName:"li"},"get")," operation,"),(0,i.kt)("li",{parentName:"ol"},"Retrieve the Smithy4s ",(0,i.kt)("inlineCode",{parentName:"li"},"Schemas")," (input and output) associated to the operation (",(0,i.kt)("inlineCode",{parentName:"li"},"KVStoreOp.Get"),")"),(0,i.kt)("li",{parentName:"ol"},"Compile a ",(0,i.kt)("inlineCode",{parentName:"li"},"Request => GetInput")," decoding function, and run the ",(0,i.kt)("inlineCode",{parentName:"li"},"Request")," through it"),(0,i.kt)("li",{parentName:"ol"},"From ",(0,i.kt)("inlineCode",{parentName:"li"},"GetInput"),", recreate the ",(0,i.kt)("inlineCode",{parentName:"li"},"KVStoreOp.Get")," instance"),(0,i.kt)("li",{parentName:"ol"},"From ",(0,i.kt)("inlineCode",{parentName:"li"},"KVStoreOp.Get"),", use the final-encoded dual of ",(0,i.kt)("inlineCode",{parentName:"li"},"KVStoreOp")," to call the ",(0,i.kt)("inlineCode",{parentName:"li"},"KVStore#get")," method (implemented by the user). This gets us an ",(0,i.kt)("inlineCode",{parentName:"li"},"GetOutput")),(0,i.kt)("li",{parentName:"ol"},"Compile a ",(0,i.kt)("inlineCode",{parentName:"li"},"GetOutput => Response")," encoding function from the schemas, and run the output through it")),(0,i.kt)("p",null,"So we get ",(0,i.kt)("inlineCode",{parentName:"p"},"Request => KVStoreOp.GetInput => KVStoreOp.Get => kvstore.get => GetOutput => Response"),", which gives us the full data flow, service side."),(0,i.kt)("p",null,"Both the service-side and client-side logical flows guide the design of the abstractions that are exposed by Smithy4s."),(0,i.kt)("h3",{id:"a-note-about-efficiency"},"A note about efficiency"),(0,i.kt)("p",null,"The flows described above are merely conceptual, and do not account for the optimisations involved to ensure that schemas are not recompiled into codecs on a per-request basis (which would greatly impact performance). Interpreters provided by Smithy4s (HTTP and co) are written to ensure that all compilation is performed ahead of receiving requests, by means of preliminary computations and caching."),(0,i.kt)("h2",{id:"the-endpoint-abstraction"},"The Endpoint abstraction"),(0,i.kt)("p",null,"The ",(0,i.kt)("inlineCode",{parentName:"p"},"smithy4s.Endpoint")," abstraction ties a specific operation to the various schemas that are tied to it."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},"trait Endpoint[Op[_, _, _, _, _], I, E, O, SI, SO] {\n def schema: OperationSchema[I, E, O, SI, SO]\n def wrap(input: I): Op[I, E, O, SI, SO]\n}\n")),(0,i.kt)("p",null,"where ",(0,i.kt)("inlineCode",{parentName:"p"},"smithy4s.schema.OperationSchema")," is a product of all schemas involved in an specific operation."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},"final case class OperationSchema[I, E, O, SI, SO](\n id: ShapeId,\n hints: Hints,\n input: Schema[I],\n error: Option[ErrorSchema[E]],\n output: Schema[O],\n streamedInput: Option[StreamingSchema[SI]],\n streamedOutput: Option[StreamingSchema[SO]]\n) {\n\n")),(0,i.kt)("p",null,"Endpoints are not type-classes. Instead, an ",(0,i.kt)("inlineCode",{parentName:"p"},"Endpoint")," instance is provided by the companion object of each member of the ",(0,i.kt)("inlineCode",{parentName:"p"},"GADT")," forming the initial-encoding of the service interface. So, going back to our ",(0,i.kt)("inlineCode",{parentName:"p"},"KVStore"),", the corresponding sealed-trait would look like this :"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},"sealed trait KVStoreOp[Input, Error, Output, StreamedInput, StreamedOutput]\n")),(0,i.kt)("p",null,"and the ",(0,i.kt)("inlineCode",{parentName:"p"},"put")," operation would look like :"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},'case class Put(input: PutRequest) extends KVStoreOp[PutRequest, PutError, PutResult, Nothing, Nothing]\nobject Put extends Endpoint[KVStoreOp, PutRequest, PutError, PutResult, Nothing, Nothing] {\n val input = PutRequest.input\n val output = PutRequest.schema\n val streamedInput = SteamingSchema.nothing\n val streamedOutput = StreamingSchema.nothing\n val errorable: Option[Errorable[PutResult]] = this\n // ...\n val schema: OperationSchema[PutRequest, PutError, PutResult, Nothing, Nothing] =\n Schema.operation(ShapeId("namespace", "Put"))\n .withInput(PutRequest.schema)\n .withError(PutError.errorSchema)\n .withOutput(PutResult.schema)\n def wrap(input: PutRequest) = Put(input)\n}\n')),(0,i.kt)("h3",{id:"a-note-on-errors"},"A note on errors"),(0,i.kt)("p",null,"As stated previously, Smithy4s generates a coproduct type for each operation, where the members of the coproduct point to the various errors listed in the smithy operation shape. Additionally, each structure annotated with ",(0,i.kt)("inlineCode",{parentName:"p"},"@error")," in smithy is rendered as a case-class that extends ",(0,i.kt)("inlineCode",{parentName:"p"},"Throwable"),", because ",(0,i.kt)("inlineCode",{parentName:"p"},"Throwables")," are the de-facto standard of doing error handling on the JVM. Even libraries that use ",(0,i.kt)("inlineCode",{parentName:"p"},"Either")," to perform error handling often represent the left-hand-side of the Either as some throwable type, to facilitate the absorption of errors into the error-channels of monadic constructs (",(0,i.kt)("inlineCode",{parentName:"p"},"IO.raiseError"),", etc)"),(0,i.kt)("p",null,"As a result, it is important for Smithy4s to expose functions that generically enable the filtering of throwables against the ",(0,i.kt)("inlineCode",{parentName:"p"},"Error")," type parameter of an operation, so that interpreters can intercept errors and apply the correct encoding (dictated via ",(0,i.kt)("inlineCode",{parentName:"p"},"Schema"),") before communicating them back to the caller over the wire. Conversely, it is important to expose a function that allows to go from the generic ",(0,i.kt)("inlineCode",{parentName:"p"},"Error")," type parameter to ",(0,i.kt)("inlineCode",{parentName:"p"},"Throwable"),", so that errors received via low-level communication channels can be turned into ",(0,i.kt)("inlineCode",{parentName:"p"},"Throwable")," at the client call site, in order to populate the relevant error channel when exposing mono-functor semantics."),(0,i.kt)("p",null,"Therefore, when a smithy operation has ",(0,i.kt)("inlineCode",{parentName:"p"},"errors")," defined, the corresponding ",(0,i.kt)("inlineCode",{parentName:"p"},"smithy4s.schema.OperationSchema")," references a ",(0,i.kt)("inlineCode",{parentName:"p"},"smithy4s.schema.ErrorSchema"),", which looks like this :"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},"case class ErrorSchema[E] private[smithy4s] (\n schema: Schema[E],\n liftError: Throwable => Option[E],\n unliftError: E => Throwable\n)\n")),(0,i.kt)("h2",{id:"services-and-endpoints"},"Services and endpoints"),(0,i.kt)("p",null,"In order to implement any server-side interpreters, it is required to have a list of endpoints. That list is used to implement some matching logic based on the ",(0,i.kt)("inlineCode",{parentName:"p"},"shapeId")," and/or the ",(0,i.kt)("inlineCode",{parentName:"p"},"hints")," associated to the endpoints, in order to deterministically decide where to route a low level ",(0,i.kt)("inlineCode",{parentName:"p"},"Request")," to a specific ",(0,i.kt)("inlineCode",{parentName:"p"},"Endpoint")," instance."),(0,i.kt)("p",null,"For instance, smithy provides a ",(0,i.kt)("inlineCode",{parentName:"p"},"@http")," trait out of the box that can annotate operations :"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-kotlin"},'service KVStore {\n operations: [Get, Put]\n}\n\n@http(method: "GET", uri: "/resource/${key}, code: 200)\noperation Get {\n input: GetInput\n output: GetOutput\n}\n\nstructure GetInput {\n @httpLabel\n key: String\n}\n\nstructure GetOutput {\n value: String\n}\n\n@http(method: "PUT", uri: "/resource/${key}, code: 200)\noperation Put {\n\n}\n\nstructure PutInput {\n @httpLabel\n key: String,\n @httpPayload\n value: String\n}\n')),(0,i.kt)("p",null,"Each ",(0,i.kt)("inlineCode",{parentName:"p"},"@http")," occurrence get translated to a scala value in the ",(0,i.kt)("inlineCode",{parentName:"p"},"Hints")," associated to the corresponding endpoint."),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"On server-side, having a list of all the endpoints associated to a service allows for creating a routing logic that dispatches an HTTP Request to the correct endpoint."),(0,i.kt)("li",{parentName:"ul"},"On client-side, a method call to a service stub gets translated to an instance of the corresponding ",(0,i.kt)("inlineCode",{parentName:"li"},"GADT")," member. From there, we have to retrieve the schemas associated to the member in question. Additionally, we need to extract the input value out of the member, to run it through an encoder derived from the the associated ",(0,i.kt)("inlineCode",{parentName:"li"},"Schema"),".")),(0,i.kt)("p",null,"Therefore, the ",(0,i.kt)("inlineCode",{parentName:"p"},"Service")," abstraction needs to be enriched with the following methods :"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},"trait Service[Final[_[_, _, _, _, _]]] {\n\n type Initial[_, _, _, _, _]\n\n // ...\n\n // useful for server-side\n def endpoints: IndexedSeq[Endpoint[Initial, _, _, _, _, _]]\n // useful for client-side\n\n // provides the index of the endpoint associated to the operation\n def ordinal[I, E, O, SI, SO](op: Initial[I, E, O, SI, SO]): Int\n // extracts the input value out of a reified operation\n def input[I, E, O, SI, SO](op: Operation[I, E, O, SI, SO]): I\n\n}\n")),(0,i.kt)("h2",{id:"conclusion-and-complete-interfaces"},"Conclusion and complete interfaces"),(0,i.kt)("p",null,"Here are links to the complete interfaces discussed in this chapter."),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://github.com/disneystreaming/smithy4s/blob/8cb01fd92d65f6e4ec515fccb3677cffe6a1093b/modules/core/src/smithy4s/Service.scala"},"Service")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://github.com/disneystreaming/smithy4s/blob/8cb01fd92d65f6e4ec515fccb3677cffe6a1093b/modules/core/src/smithy4s/Endpoint.scala"},"Endpoint"))))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/b04b9a17.167e5a13.js b/assets/js/b04b9a17.3b54d9b9.js similarity index 82% rename from assets/js/b04b9a17.167e5a13.js rename to assets/js/b04b9a17.3b54d9b9.js index 37b74f2e2..f44bb040e 100644 --- a/assets/js/b04b9a17.167e5a13.js +++ b/assets/js/b04b9a17.3b54d9b9.js @@ -1 +1 @@ -"use strict";(self.webpackChunksmithy4s=self.webpackChunksmithy4s||[]).push([[2408],{3905:(e,t,i)=>{i.d(t,{Zo:()=>m,kt:()=>h});var n=i(7294);function r(e,t,i){return t in e?Object.defineProperty(e,t,{value:i,enumerable:!0,configurable:!0,writable:!0}):e[t]=i,e}function a(e,t){var i=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),i.push.apply(i,n)}return i}function o(e){for(var t=1;t=0||(r[i]=e[i]);return r}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,i)&&(r[i]=e[i])}return r}var s=n.createContext({}),p=function(e){var t=n.useContext(s),i=t;return e&&(i="function"==typeof e?e(t):o(o({},t),e)),i},m=function(e){var t=p(e.components);return n.createElement(s.Provider,{value:t},e.children)},u="mdxType",c={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var i=e.components,r=e.mdxType,a=e.originalType,s=e.parentName,m=l(e,["components","mdxType","originalType","parentName"]),u=p(i),d=r,h=u["".concat(s,".").concat(d)]||u[d]||c[d]||a;return i?n.createElement(h,o(o({ref:t},m),{},{components:i})):n.createElement(h,o({ref:t},m))}));function h(e,t){var i=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var a=i.length,o=new Array(a);o[0]=d;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[u]="string"==typeof e?e:r,o[1]=l;for(var p=2;p{i.r(t),i.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>c,frontMatter:()=>a,metadata:()=>l,toc:()=>p});var n=i(7462),r=(i(7294),i(3905));const a={sidebar_label:"SimpleRestJson",title:"The SimpleRestJson protocol"},o=void 0,l={unversionedId:"protocols/simple-rest-json/overview",id:"protocols/simple-rest-json/overview",title:"The SimpleRestJson protocol",description:"Smithy4s provides a custom Json-in/Json-out protocol that smithy services can be annotated with.",source:"@site/../docs/target/jvm-2.13/mdoc/03-protocols/04-simple-rest-json/01-overview.md",sourceDirName:"03-protocols/04-simple-rest-json",slug:"/protocols/simple-rest-json/overview",permalink:"/smithy4s/docs/protocols/simple-rest-json/overview",draft:!1,editUrl:"https://github.com/disneystreaming/smithy4s/edit/main/modules/docs/src/03-protocols/04-simple-rest-json/01-overview.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_label:"SimpleRestJson",title:"The SimpleRestJson protocol"},sidebar:"tutorialSidebar",previous:{title:"Localstack",permalink:"/smithy4s/docs/protocols/aws/localstack"},next:{title:"Server",permalink:"/smithy4s/docs/protocols/simple-rest-json/server"}},s={},p=[{value:"Semantics",id:"semantics",level:2},{value:"Example spec",id:"example-spec",level:2},{value:"Supported traits",id:"supported-traits",level:2},{value:"Decoding and encoding unions",id:"decoding-and-encoding-unions",level:2},{value:"Json Array Arity",id:"json-array-arity",level:2},{value:"Explicit Null Encoding",id:"explicit-null-encoding",level:2},{value:"Supported traits",id:"supported-traits-1",level:2},{value:"Structured Strings",id:"structured-strings",level:2}],m={toc:p},u="wrapper";function c(e){let{components:t,...i}=e;return(0,r.kt)(u,(0,n.Z)({},m,i,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("p",null,"Smithy4s provides a custom Json-in/Json-out protocol that smithy services can be annotated with."),(0,r.kt)("p",null,"Smithy4s comes with opt-in http4s-specific module, that contains functions that are aware of this protocol, and can be used to quickly derive http services and clients."),(0,r.kt)("p",null,"As for the json aspect of the protocol, ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/plokhotnyuk/jsoniter-scala/"},"jsoniter-scala")," is used for the (de)serialisation of the http bodies."),(0,r.kt)("h2",{id:"semantics"},"Semantics"),(0,r.kt)("p",null,"In this protocol, the values in shapes are bound to http metadata or body according to the specification of the ",(0,r.kt)("a",{parentName:"p",href:"https://awslabs.github.io/smithy/1.0/spec/core/http-traits.html?highlight=http#http-binding-traits"},"Http Binding traits"),". However, the ",(0,r.kt)("inlineCode",{parentName:"p"},"@mediaType")," trait has no incidence, and all bodies (when present) are serialised in JSON."),(0,r.kt)("h2",{id:"example-spec"},"Example spec"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-kotlin"},'namespace smithy4s.example\n\nuse alloy#simpleRestJson\n\n@simpleRestJson\nservice HelloWorldService {\n version: "1.0.0"\n // Indicates that all operations in `HelloWorldService`,\n // here limited to the Hello operation, can return `GenericServerError`.\n errors: [GenericServerError]\n operations: [Hello]\n}\n\n@error("server")\n@httpError(500)\nstructure GenericServerError {\n message: String\n}\n\n@http(method: "POST", uri: "/{name}", code: 200)\noperation Hello {\n input: Person\n output: Greeting\n}\n\nstructure Person {\n @httpLabel\n @required\n name: String\n\n @httpQuery("town")\n town: String\n}\n\nstructure Greeting {\n @required\n message: String\n}\n')),(0,r.kt)("h2",{id:"supported-traits"},"Supported traits"),(0,r.kt)("p",null,"This protocol and its interpreters, are aware of the following traits provided out of the box:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://awslabs.github.io/smithy/1.0/spec/core/model.html#simple-shapes"},"all simple shapes")),(0,r.kt)("li",{parentName:"ul"},"composite data shapes, including collections, unions, structures."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://awslabs.github.io/smithy/1.0/spec/core/model.html#service"},"operations and services")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://awslabs.github.io/smithy/1.0/spec/core/constraint-traits.html#enum-trait"},"enumerations")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://awslabs.github.io/smithy/1.0/spec/core/type-refinement-traits.html#error-trait"},"error trait")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://awslabs.github.io/smithy/1.0/spec/core/http-traits.html"},"http traits")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://awslabs.github.io/smithy/1.0/spec/core/protocol-traits.html?highlight=timestampformat#timestampformat-trait"},"timestampFormat trait"))),(0,r.kt)("p",null,"For the full list, see below."),(0,r.kt)("h2",{id:"decoding-and-encoding-unions"},"Decoding and encoding unions"),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"SimpleRestJson")," protocol supports 3 different union encodings :"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"tagged (default)"),(0,r.kt)("li",{parentName:"ul"},"untagged"),(0,r.kt)("li",{parentName:"ul"},"discriminated")),(0,r.kt)("p",null,"See the section about ",(0,r.kt)("a",{parentName:"p",href:"/smithy4s/docs/codegen/unions"},"unions")," for a detailed description."),(0,r.kt)("h2",{id:"json-array-arity"},"Json Array Arity"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"By default there is a limit on the arity of an array, which is 1024. This is to prevent the server from being overloaded with a large array as this is a vector for attacks."),(0,r.kt)("li",{parentName:"ul"},"This limit can be changed by setting the maxArity ",(0,r.kt)("inlineCode",{parentName:"li"},"smithy4s.http4s.SimpleRestJsonBuilder.withMaxArity(.)")," to the desired value."),(0,r.kt)("li",{parentName:"ul"},"an example can be seen in the ",(0,r.kt)("a",{parentName:"li",href:"/smithy4s/docs/protocols/simple-rest-json/client"},"client example"))),(0,r.kt)("h2",{id:"explicit-null-encoding"},"Explicit Null Encoding"),(0,r.kt)("p",null,"By default, optional properties (headers, query parameters, structure fields) that are set to ",(0,r.kt)("inlineCode",{parentName:"p"},"None")," and optional properties that are set to default value will be excluded during encoding process. If you wish to change this so that instead they are included and set to ",(0,r.kt)("inlineCode",{parentName:"p"},"null")," explicitly, you can do so by calling ",(0,r.kt)("inlineCode",{parentName:"p"},".withExplicitDefaultsEncoding(true)"),"."),(0,r.kt)("h2",{id:"supported-traits-1"},"Supported traits"),(0,r.kt)("p",null,"Here is the list of traits supported by ",(0,r.kt)("inlineCode",{parentName:"p"},"SimpleRestJson")),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"smithy.api#default")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"smithy.api#error")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"smithy.api#http")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"smithy.api#httpError")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"smithy.api#httpHeader")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"smithy.api#httpLabel")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"smithy.api#httpPayload")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"smithy.api#httpPrefixHeaders")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"smithy.api#httpQuery")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"smithy.api#httpQueryParams")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"smithy.api#httpResponseCode")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"smithy.api#jsonName")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"smithy.api#length")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"smithy.api#pattern")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"smithy.api#range")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"smithy.api#required")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"smithy.api#timestampFormat")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"alloy#uncheckedExamples")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"alloy#uuidFormat")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"alloy#discriminated")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"alloy#untagged"))),(0,r.kt)("p",null,"Currently, ",(0,r.kt)("inlineCode",{parentName:"p"},"@cors")," is not supported. This is because the ",(0,r.kt)("inlineCode",{parentName:"p"},"@cors")," annotation is too restrictive. You can still use it in your model and configure your API using the information found in the generated code. See the ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/disneystreaming/smithy4s/blob/9f2dbcbd29b4dbd35792fa40e423a6395ae3f9e6/modules/guides/src/smithy4s/guides/Cors.scala"},(0,r.kt)("inlineCode",{parentName:"a"},"Cors.scala"))," file in the ",(0,r.kt)("inlineCode",{parentName:"p"},"guides")," module for an example."),(0,r.kt)("h2",{id:"structured-strings"},"Structured Strings"),(0,r.kt)("p",null,"As of smithy4s version ",(0,r.kt)("inlineCode",{parentName:"p"},"0.18.x"),", you are able to create strings which are parsed directly into structures for you. This can be accomplished using the ",(0,r.kt)("inlineCode",{parentName:"p"},"alloy#structurePattern")," trait. For example:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-smithy"},'@structurePattern(pattern: "{foo}_{bar}", target: FooBar)\nstring FooBarString\n\nstructure FooBar {\n @required\n foo: String\n @required\n bar: Integer\n}\n')),(0,r.kt)("p",null,"Now wherever ",(0,r.kt)("inlineCode",{parentName:"p"},"FooBarString")," is used, it will really be parsing the string into the structure ",(0,r.kt)("inlineCode",{parentName:"p"},"FooBar"),". As such, the generated code will replace instances of ",(0,r.kt)("inlineCode",{parentName:"p"},"FooBarString")," with ",(0,r.kt)("inlineCode",{parentName:"p"},"FooBar")," such that the parsing logic is abstracted away from your implementation. See the ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/disneystreaming/alloy#alloystructurepattern"},"alloy documentation")," for more information."))}c.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunksmithy4s=self.webpackChunksmithy4s||[]).push([[2408],{3905:(e,t,i)=>{i.d(t,{Zo:()=>m,kt:()=>h});var n=i(7294);function r(e,t,i){return t in e?Object.defineProperty(e,t,{value:i,enumerable:!0,configurable:!0,writable:!0}):e[t]=i,e}function a(e,t){var i=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),i.push.apply(i,n)}return i}function o(e){for(var t=1;t=0||(r[i]=e[i]);return r}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,i)&&(r[i]=e[i])}return r}var s=n.createContext({}),p=function(e){var t=n.useContext(s),i=t;return e&&(i="function"==typeof e?e(t):o(o({},t),e)),i},m=function(e){var t=p(e.components);return n.createElement(s.Provider,{value:t},e.children)},u="mdxType",c={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var i=e.components,r=e.mdxType,a=e.originalType,s=e.parentName,m=l(e,["components","mdxType","originalType","parentName"]),u=p(i),d=r,h=u["".concat(s,".").concat(d)]||u[d]||c[d]||a;return i?n.createElement(h,o(o({ref:t},m),{},{components:i})):n.createElement(h,o({ref:t},m))}));function h(e,t){var i=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var a=i.length,o=new Array(a);o[0]=d;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[u]="string"==typeof e?e:r,o[1]=l;for(var p=2;p{i.r(t),i.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>c,frontMatter:()=>a,metadata:()=>l,toc:()=>p});var n=i(7462),r=(i(7294),i(3905));const a={sidebar_label:"SimpleRestJson",title:"The SimpleRestJson protocol"},o=void 0,l={unversionedId:"protocols/simple-rest-json/overview",id:"protocols/simple-rest-json/overview",title:"The SimpleRestJson protocol",description:"Smithy4s provides a custom Json-in/Json-out protocol that smithy services can be annotated with.",source:"@site/../docs/target/jvm-2.13/mdoc/03-protocols/04-simple-rest-json/01-overview.md",sourceDirName:"03-protocols/04-simple-rest-json",slug:"/protocols/simple-rest-json/overview",permalink:"/smithy4s/docs/protocols/simple-rest-json/overview",draft:!1,editUrl:"https://github.com/disneystreaming/smithy4s/edit/main/modules/docs/src/03-protocols/04-simple-rest-json/01-overview.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_label:"SimpleRestJson",title:"The SimpleRestJson protocol"},sidebar:"tutorialSidebar",previous:{title:"Localstack",permalink:"/smithy4s/docs/protocols/aws/localstack"},next:{title:"Server",permalink:"/smithy4s/docs/protocols/simple-rest-json/server"}},s={},p=[{value:"Semantics",id:"semantics",level:2},{value:"Example spec",id:"example-spec",level:2},{value:"Supported traits",id:"supported-traits",level:2},{value:"Decoding and encoding unions",id:"decoding-and-encoding-unions",level:2},{value:"Json Array Arity",id:"json-array-arity",level:2},{value:"Explicit Null Encoding",id:"explicit-null-encoding",level:2},{value:"Supported traits",id:"supported-traits-1",level:2},{value:"Structured Strings",id:"structured-strings",level:2}],m={toc:p},u="wrapper";function c(e){let{components:t,...i}=e;return(0,r.kt)(u,(0,n.Z)({},m,i,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("p",null,"Smithy4s provides a custom Json-in/Json-out protocol that smithy services can be annotated with."),(0,r.kt)("p",null,"Smithy4s comes with opt-in http4s-specific module, that contains functions that are aware of this protocol, and can be used to quickly derive http services and clients."),(0,r.kt)("p",null,"As for the json aspect of the protocol, ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/plokhotnyuk/jsoniter-scala/"},"jsoniter-scala")," is used for the (de)serialisation of the http bodies."),(0,r.kt)("h2",{id:"semantics"},"Semantics"),(0,r.kt)("p",null,"In this protocol, the values in shapes are bound to http metadata or body according to the specification of the ",(0,r.kt)("a",{parentName:"p",href:"https://awslabs.github.io/smithy/1.0/spec/core/http-traits.html?highlight=http#http-binding-traits"},"Http Binding traits"),". However, the ",(0,r.kt)("inlineCode",{parentName:"p"},"@mediaType")," trait has no incidence, and all bodies (when present) are serialised in JSON."),(0,r.kt)("h2",{id:"example-spec"},"Example spec"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-kotlin"},'namespace smithy4s.example\n\nuse alloy#simpleRestJson\n\n@simpleRestJson\nservice HelloWorldService {\n version: "1.0.0"\n // Indicates that all operations in `HelloWorldService`,\n // here limited to the Hello operation, can return `GenericServerError`.\n errors: [GenericServerError]\n operations: [Hello]\n}\n\n@error("server")\n@httpError(500)\nstructure GenericServerError {\n message: String\n}\n\n@http(method: "POST", uri: "/{name}", code: 200)\noperation Hello {\n input: Person\n output: Greeting\n}\n\nstructure Person {\n @httpLabel\n @required\n name: String\n\n @httpQuery("town")\n town: String\n}\n\nstructure Greeting {\n @required\n message: String\n}\n')),(0,r.kt)("h2",{id:"supported-traits"},"Supported traits"),(0,r.kt)("p",null,"This protocol and its interpreters, are aware of the following traits provided out of the box:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://awslabs.github.io/smithy/1.0/spec/core/model.html#simple-shapes"},"all simple shapes")),(0,r.kt)("li",{parentName:"ul"},"composite data shapes, including collections, unions, structures."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://awslabs.github.io/smithy/1.0/spec/core/model.html#service"},"operations and services")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://awslabs.github.io/smithy/1.0/spec/core/constraint-traits.html#enum-trait"},"enumerations")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://awslabs.github.io/smithy/1.0/spec/core/type-refinement-traits.html#error-trait"},"error trait")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://awslabs.github.io/smithy/1.0/spec/core/http-traits.html"},"http traits")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://awslabs.github.io/smithy/1.0/spec/core/protocol-traits.html?highlight=timestampformat#timestampformat-trait"},"timestampFormat trait"))),(0,r.kt)("p",null,"For the full list, see below."),(0,r.kt)("h2",{id:"decoding-and-encoding-unions"},"Decoding and encoding unions"),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"SimpleRestJson")," protocol supports 3 different union encodings :"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"tagged (default)"),(0,r.kt)("li",{parentName:"ul"},"untagged"),(0,r.kt)("li",{parentName:"ul"},"discriminated")),(0,r.kt)("p",null,"See the section about ",(0,r.kt)("a",{parentName:"p",href:"/smithy4s/docs/codegen/unions"},"unions")," for a detailed description."),(0,r.kt)("h2",{id:"json-array-arity"},"Json Array Arity"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"By default there is a limit on the arity of an array, which is 1024. This is to prevent the server from being overloaded with a large array as this is a vector for attacks."),(0,r.kt)("li",{parentName:"ul"},"This limit can be changed by setting the maxArity ",(0,r.kt)("inlineCode",{parentName:"li"},"smithy4s.http4s.SimpleRestJsonBuilder.withMaxArity(.)")," to the desired value."),(0,r.kt)("li",{parentName:"ul"},"an example can be seen in the ",(0,r.kt)("a",{parentName:"li",href:"/smithy4s/docs/protocols/simple-rest-json/client"},"client example"))),(0,r.kt)("h2",{id:"explicit-null-encoding"},"Explicit Null Encoding"),(0,r.kt)("p",null,"By default, optional properties (headers, query parameters, structure fields) that are set to ",(0,r.kt)("inlineCode",{parentName:"p"},"None")," and optional properties that are set to default value will be excluded during encoding process. If you wish to change this so that instead they are included and set to ",(0,r.kt)("inlineCode",{parentName:"p"},"null")," explicitly, you can do so by calling ",(0,r.kt)("inlineCode",{parentName:"p"},".withExplicitDefaultsEncoding(true)"),"."),(0,r.kt)("h2",{id:"supported-traits-1"},"Supported traits"),(0,r.kt)("p",null,"Here is the list of traits supported by ",(0,r.kt)("inlineCode",{parentName:"p"},"SimpleRestJson")),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"smithy.api#default")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"smithy.api#error")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"smithy.api#http")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"smithy.api#httpError")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"smithy.api#httpHeader")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"smithy.api#httpLabel")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"smithy.api#httpPayload")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"smithy.api#httpPrefixHeaders")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"smithy.api#httpQuery")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"smithy.api#httpQueryParams")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"smithy.api#httpResponseCode")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"smithy.api#jsonName")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"smithy.api#length")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"smithy.api#pattern")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"smithy.api#range")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"smithy.api#required")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"smithy.api#timestampFormat")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"alloy#uuidFormat")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"alloy#discriminated")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"alloy#nullable")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"alloy#untagged"))),(0,r.kt)("p",null,"Currently, ",(0,r.kt)("inlineCode",{parentName:"p"},"@cors")," is not supported. This is because the ",(0,r.kt)("inlineCode",{parentName:"p"},"@cors")," annotation is too restrictive. You can still use it in your model and configure your API using the information found in the generated code. See the ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/disneystreaming/smithy4s/blob/8cb01fd92d65f6e4ec515fccb3677cffe6a1093b/modules/guides/src/smithy4s/guides/Cors.scala"},(0,r.kt)("inlineCode",{parentName:"a"},"Cors.scala"))," file in the ",(0,r.kt)("inlineCode",{parentName:"p"},"guides")," module for an example."),(0,r.kt)("h2",{id:"structured-strings"},"Structured Strings"),(0,r.kt)("p",null,"As of smithy4s version ",(0,r.kt)("inlineCode",{parentName:"p"},"0.18.x"),", you are able to create strings which are parsed directly into structures for you. This can be accomplished using the ",(0,r.kt)("inlineCode",{parentName:"p"},"alloy#structurePattern")," trait. For example:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-smithy"},'@structurePattern(pattern: "{foo}_{bar}", target: FooBar)\nstring FooBarString\n\nstructure FooBar {\n @required\n foo: String\n @required\n bar: Integer\n}\n')),(0,r.kt)("p",null,"Now wherever ",(0,r.kt)("inlineCode",{parentName:"p"},"FooBarString")," is used, it will really be parsing the string into the structure ",(0,r.kt)("inlineCode",{parentName:"p"},"FooBar"),". As such, the generated code will replace instances of ",(0,r.kt)("inlineCode",{parentName:"p"},"FooBarString")," with ",(0,r.kt)("inlineCode",{parentName:"p"},"FooBar")," such that the parsing logic is abstracted away from your implementation. See the ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/disneystreaming/alloy#alloystructurepattern"},"alloy documentation")," for more information."))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/bb709d94.896f6264.js b/assets/js/bb709d94.3db57c9a.js similarity index 76% rename from assets/js/bb709d94.896f6264.js rename to assets/js/bb709d94.3db57c9a.js index 12a3ffbb1..09f2981a5 100644 --- a/assets/js/bb709d94.896f6264.js +++ b/assets/js/bb709d94.3db57c9a.js @@ -1 +1 @@ -"use strict";(self.webpackChunksmithy4s=self.webpackChunksmithy4s||[]).push([[3459],{3905:(e,r,t)=>{t.d(r,{Zo:()=>u,kt:()=>d});var n=t(7294);function o(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function a(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function i(e){for(var r=1;r=0||(o[t]=e[t]);return o}(e,r);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var l=n.createContext({}),c=function(e){var r=n.useContext(l),t=r;return e&&(t="function"==typeof e?e(r):i(i({},r),e)),t},u=function(e){var r=c(e.components);return n.createElement(l.Provider,{value:r},e.children)},p="mdxType",m={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},h=n.forwardRef((function(e,r){var t=e.components,o=e.mdxType,a=e.originalType,l=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),p=c(t),h=o,d=p["".concat(l,".").concat(h)]||p[h]||m[h]||a;return t?n.createElement(d,i(i({ref:r},u),{},{components:t})):n.createElement(d,i({ref:r},u))}));function d(e,r){var t=arguments,o=r&&r.mdxType;if("string"==typeof e||o){var a=t.length,i=new Array(a);i[0]=h;var s={};for(var l in r)hasOwnProperty.call(r,l)&&(s[l]=r[l]);s.originalType=e,s[p]="string"==typeof e?e:o,i[1]=s;for(var c=2;c{t.r(r),t.d(r,{assets:()=>l,contentTitle:()=>i,default:()=>m,frontMatter:()=>a,metadata:()=>s,toc:()=>c});var n=t(7462),o=(t(7294),t(3905));const a={sidebar_label:"Smithy4s Transformations",title:"Smithy4s Transformations and generalisation"},i=void 0,s={unversionedId:"guides/smithy4s-transformations",id:"guides/smithy4s-transformations",title:"Smithy4s Transformations and generalisation",description:"It is often the case that users may want to manipulate the generated interfaces in a generic way, be that to transform the context in which the interface operates, or to apply some generic behaviour when running methods.",source:"@site/../docs/target/jvm-2.13/mdoc/06-guides/smithy4s-transformations.md",sourceDirName:"06-guides",slug:"/guides/smithy4s-transformations",permalink:"/smithy4s/docs/guides/smithy4s-transformations",draft:!1,editUrl:"https://github.com/disneystreaming/smithy4s/edit/main/modules/docs/src/06-guides/smithy4s-transformations.md",tags:[],version:"current",frontMatter:{sidebar_label:"Smithy4s Transformations",title:"Smithy4s Transformations and generalisation"},sidebar:"tutorialSidebar",previous:{title:"Model preprocessing",permalink:"/smithy4s/docs/guides/model-preprocessing"},next:{title:"Testing",permalink:"/smithy4s/docs/guides/testing"}},l={},c=[{value:"Error-related transformations",id:"error-related-transformations",level:2},{value:"Surfacing errors",id:"surfacing-errors",level:3},{value:"Absorbing errors",id:"absorbing-errors",level:3}],u={toc:c},p="wrapper";function m(e){let{components:r,...t}=e;return(0,o.kt)(p,(0,n.Z)({},u,t,{components:r,mdxType:"MDXLayout"}),(0,o.kt)("p",null,"It is often the case that users may want to manipulate the generated interfaces in a generic way, be that to transform the context in which the interface operates, or to apply some generic behaviour when running methods."),(0,o.kt)("p",null,"The generated code provided by Smithy4s contains the required methods and instances to be able to write transformations very generically. In particular, all generated service interfaces come with an associated ",(0,o.kt)("inlineCode",{parentName:"p"},"FunctorK5"),', which means they can be "mapped" by using a function that\noperates over higher-kinded types with 5 type parameters. Yes, this is scary, but indirections are present to make it easier for the end user.'),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-kotlin"},'$version: "2"\n\nnamespace smithy4s.example.greet\n\nservice GreetService {\n operations: [Greet]\n}\n\noperation Greet {\n input := {\n @required\n name: String\n }\n output := {\n @required\n message: String\n }\n}\n')),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-scala"},'import smithy4s._\nimport smithy4s.kinds.PolyFunction\nimport smithy4s.example.greet._\n\ntype Result[A] = Either[String, A]\n\n// Assuming `GreetService` was generated by smithy4s.\nval greetServiceEither: GreetService[Result] = new GreetService[Result]{\n def greet(name: String): Result[GreetOutput] =\n if (name.isEmpty) Left("What\'s your name ?")\n else Right(GreetOutput(s"Hello $name!"))\n}\n// greetServiceEither: GreetService[Result] = repl.MdocSession$MdocApp$$anon$1@7f3ddf16\n\n// Creating a polymorphic function turning Either to Option :\nval toOption: PolyFunction[Result, Option] = new PolyFunction[Result, Option]{\n def apply[A](result: Result[A]): Option[A] = result.toOption\n}\n// toOption: PolyFunction[Result, Option] = repl.MdocSession$MdocApp$$anon$2@253e8a08\n\n// transforming our service :\nval greetServiceOption: GreetService[Option] = greetServiceEither.transform(toOption)\n// greetServiceOption: GreetService[Option] = smithy4s.example.greet.GreetServiceOperation$Transformed@476a2465\n\nprintln(greetServiceOption.greet("John"))\n// Some(GreetOutput(Hello John!))\n')),(0,o.kt)("h2",{id:"error-related-transformations"},"Error-related transformations"),(0,o.kt)("p",null,"Using transformations, it is possible to surface errors into the context a service operates, or, in the contrary, to absorb errors to make them disappear from the context. The generated interfaces contain the accurate information associated to each method, and the companion objects contain the necessary constructs to transform typed-errors into throwables and to recover type-errors from throwables."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-kotlin"},'$version: "2"\n\nnamespace smithy4s.example\n\nservice KVStore {\n operations: [Get, Put, Delete],\n errors: [UnauthorizedError]\n}\n\noperation Put {\n input: KeyValue\n}\n\noperation Get {\n input: Key,\n output: Value,\n errors: [KeyNotFoundError]\n}\n\noperation Delete {\n input: Key,\n errors: [KeyNotFoundError]\n}\n\nstructure Key {\n @required\n key: String\n}\n\nstructure KeyValue {\n @required\n key: String,\n @required\n value: String\n}\n\nstructure Value {\n @required\n value: String\n}\n\n@error("client")\nstructure UnauthorizedError {\n @required\n reason: String\n}\n\n@error("client")\nstructure KeyNotFoundError {\n @required\n message: String\n}\n')),(0,o.kt)("h3",{id:"surfacing-errors"},"Surfacing errors"),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"smithy4s.Transformation.SurfaceError")," interface codifies the transformation of service implementations from contexts that represent errors as a generic ",(0,o.kt)("inlineCode",{parentName:"p"},"Throwable"),", from contexts that have the awareness of the errors specified in the specifications. It is useful when you want to exhaustively handle the errors that are specified (as opposed to letting them propagate)."),(0,o.kt)("p",null,"To make the ascription of such contexts easier, Smithy4s generates ",(0,o.kt)("inlineCode",{parentName:"p"},"ErrorAware[F[_, _]]"),' type aliases in the companion objects of services. This can\nbe used conjointly with types that have "two" parameters, one for the error, one for the result. For instance ',(0,o.kt)("inlineCode",{parentName:"p"},"type BIO[E, A] = EitherT[IO, E, A]"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-scala"},'import smithy4s.example._\nimport smithy4s.example.KVStore\nimport smithy4s.Transformation\nimport scala.util.{Failure, Success, Try}\n\nobject kvStoreTry extends KVStore[Try] {\n def delete(key: String): Try[Unit] = Success(())\n def put(key: String, value: String): Try[Unit] = Success(())\n def get(key: String): Failure[Value] = Failure(KeyNotFoundError(s"Key $key wasn\'t found"))\n}\n\n// SurfaceError allows to go from mono-functor to bi-functor, for instance, from\n// IO[A] to EitherT[IO, E, A]\nval toEither: Transformation.SurfaceError[Try, Either] =\n new Transformation.SurfaceError[Try, Either] {\n def apply[E, A](\n value: Try[A],\n catcher: Throwable => Option[E]\n ): Either[E, A] = value match {\n case Success(value) => Right(value)\n case Failure(error) =>\n catcher(error) match {\n case None => throw error // don\'t do this at work!\n case Some(e) => Left(e)\n }\n }\n }\n// toEither: Transformation.SurfaceError[Try, Either] = repl.MdocSession$MdocApp$$anon$3@e6b24ce\n\nval kvStoreEither: KVStore.ErrorAware[Either] = kvStoreTry.transform(toEither)\n// kvStoreEither: KVStore.ErrorAware[Either] = smithy4s.example.KVStoreOperation$Transformed@2de675cd\nval result: Either[KVStore.GetError, Value] = kvStoreEither.get("foo")\n// result: Either[KVStore.GetError, Value] = Left(\n// value = KeyNotFoundErrorCase(\n// keyNotFoundError = KeyNotFoundError(message = "Key foo wasn\'t found")\n// )\n// )\n')),(0,o.kt)("h3",{id:"absorbing-errors"},"Absorbing errors"),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"smithy4s.Transformation.AbsorbErrors")," interface is the opposite as the ",(0,o.kt)("inlineCode",{parentName:"p"},"SurfaceError"),": it codifies the absorption of errors known by the service into generic error channels."),(0,o.kt)("p",null,"It is useful to implement services in a way that leverages the type-checker to ensure that the returned errors have been specified in Smithy,\nbefore passing the implementation to a generic router that is only able to work against a monofunctor."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-scala"},'import smithy4s.example._\nimport smithy4s.example.KVStore\nimport smithy4s.Transformation\nimport scala.util.{Failure, Success, Try}\n\nobject kvStoreEither extends KVStore.ErrorAware[Either] {\n def delete(key: String): Either[KVStore.DeleteError, Unit] = Right(())\n def put(key: String, value: String): Either[Nothing, Unit] = Right(())\n def get(key: String): Either[KVStore.GetError, Value] =\n Left(\n KVStore.GetError.KeyNotFoundErrorCase(\n KeyNotFoundError(s"Key $key wasn\'t found")\n )\n )\n}\n\nval toTry: Transformation.AbsorbError[Either, Try] =\n new Transformation.AbsorbError[Either, Try] {\n def apply[E, A](\n value: Either[E, A],\n thrower: E => Throwable\n ): Try[A] = value match {\n case Left(error) => Failure(thrower(error))\n case Right(value) => Success(value)\n }\n }\n// toTry: Transformation.AbsorbError[Either, Try] = repl.MdocSession$MdocApp3$$anon$4@3a80deec\n\nval kvStoreTry: KVStore[Try] = kvStoreEither.transform(toTry)\n// kvStoreTry: KVStore[Try] = smithy4s.example.KVStoreOperation$Transformed@11a9277\nval result: Try[Value] = kvStoreTry.get("foo")\n// result: Try[Value] = Failure(\n// exception = KeyNotFoundError(message = "Key foo wasn\'t found")\n// )\n')))}m.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunksmithy4s=self.webpackChunksmithy4s||[]).push([[3459],{3905:(e,r,t)=>{t.d(r,{Zo:()=>u,kt:()=>d});var n=t(7294);function o(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function a(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function i(e){for(var r=1;r=0||(o[t]=e[t]);return o}(e,r);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var l=n.createContext({}),c=function(e){var r=n.useContext(l),t=r;return e&&(t="function"==typeof e?e(r):i(i({},r),e)),t},u=function(e){var r=c(e.components);return n.createElement(l.Provider,{value:r},e.children)},p="mdxType",m={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},h=n.forwardRef((function(e,r){var t=e.components,o=e.mdxType,a=e.originalType,l=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),p=c(t),h=o,d=p["".concat(l,".").concat(h)]||p[h]||m[h]||a;return t?n.createElement(d,i(i({ref:r},u),{},{components:t})):n.createElement(d,i({ref:r},u))}));function d(e,r){var t=arguments,o=r&&r.mdxType;if("string"==typeof e||o){var a=t.length,i=new Array(a);i[0]=h;var s={};for(var l in r)hasOwnProperty.call(r,l)&&(s[l]=r[l]);s.originalType=e,s[p]="string"==typeof e?e:o,i[1]=s;for(var c=2;c{t.r(r),t.d(r,{assets:()=>l,contentTitle:()=>i,default:()=>m,frontMatter:()=>a,metadata:()=>s,toc:()=>c});var n=t(7462),o=(t(7294),t(3905));const a={sidebar_label:"Smithy4s Transformations",title:"Smithy4s Transformations and generalisation"},i=void 0,s={unversionedId:"guides/smithy4s-transformations",id:"guides/smithy4s-transformations",title:"Smithy4s Transformations and generalisation",description:"It is often the case that users may want to manipulate the generated interfaces in a generic way, be that to transform the context in which the interface operates, or to apply some generic behaviour when running methods.",source:"@site/../docs/target/jvm-2.13/mdoc/06-guides/smithy4s-transformations.md",sourceDirName:"06-guides",slug:"/guides/smithy4s-transformations",permalink:"/smithy4s/docs/guides/smithy4s-transformations",draft:!1,editUrl:"https://github.com/disneystreaming/smithy4s/edit/main/modules/docs/src/06-guides/smithy4s-transformations.md",tags:[],version:"current",frontMatter:{sidebar_label:"Smithy4s Transformations",title:"Smithy4s Transformations and generalisation"},sidebar:"tutorialSidebar",previous:{title:"Model preprocessing",permalink:"/smithy4s/docs/guides/model-preprocessing"},next:{title:"Testing",permalink:"/smithy4s/docs/guides/testing"}},l={},c=[{value:"Error-related transformations",id:"error-related-transformations",level:2},{value:"Surfacing errors",id:"surfacing-errors",level:3},{value:"Absorbing errors",id:"absorbing-errors",level:3}],u={toc:c},p="wrapper";function m(e){let{components:r,...t}=e;return(0,o.kt)(p,(0,n.Z)({},u,t,{components:r,mdxType:"MDXLayout"}),(0,o.kt)("p",null,"It is often the case that users may want to manipulate the generated interfaces in a generic way, be that to transform the context in which the interface operates, or to apply some generic behaviour when running methods."),(0,o.kt)("p",null,"The generated code provided by Smithy4s contains the required methods and instances to be able to write transformations very generically. In particular, all generated service interfaces come with an associated ",(0,o.kt)("inlineCode",{parentName:"p"},"FunctorK5"),', which means they can be "mapped" by using a function that\noperates over higher-kinded types with 5 type parameters. Yes, this is scary, but indirections are present to make it easier for the end user.'),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-kotlin"},'$version: "2"\n\nnamespace smithy4s.example.greet\n\nservice GreetService {\n operations: [Greet]\n}\n\noperation Greet {\n input := {\n @required\n name: String\n }\n output := {\n @required\n message: String\n }\n}\n')),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-scala"},'import smithy4s._\nimport smithy4s.kinds.PolyFunction\nimport smithy4s.example.greet._\n\ntype Result[A] = Either[String, A]\n\n// Assuming `GreetService` was generated by smithy4s.\nval greetServiceEither: GreetService[Result] = new GreetService[Result]{\n def greet(name: String): Result[GreetOutput] =\n if (name.isEmpty) Left("What\'s your name ?")\n else Right(GreetOutput(s"Hello $name!"))\n}\n// greetServiceEither: GreetService[Result] = repl.MdocSession$MdocApp$$anon$1@2e136176\n\n// Creating a polymorphic function turning Either to Option :\nval toOption: PolyFunction[Result, Option] = new PolyFunction[Result, Option]{\n def apply[A](result: Result[A]): Option[A] = result.toOption\n}\n// toOption: PolyFunction[Result, Option] = repl.MdocSession$MdocApp$$anon$2@252d7bda\n\n// transforming our service :\nval greetServiceOption: GreetService[Option] = greetServiceEither.transform(toOption)\n// greetServiceOption: GreetService[Option] = smithy4s.example.greet.GreetServiceOperation$Transformed@281a03ce\n\nprintln(greetServiceOption.greet("John"))\n// Some(GreetOutput(Hello John!))\n')),(0,o.kt)("h2",{id:"error-related-transformations"},"Error-related transformations"),(0,o.kt)("p",null,"Using transformations, it is possible to surface errors into the context a service operates, or, in the contrary, to absorb errors to make them disappear from the context. The generated interfaces contain the accurate information associated to each method, and the companion objects contain the necessary constructs to transform typed-errors into throwables and to recover type-errors from throwables."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-kotlin"},'$version: "2"\n\nnamespace smithy4s.example\n\nservice KVStore {\n operations: [Get, Put, Delete],\n errors: [UnauthorizedError]\n}\n\noperation Put {\n input: KeyValue\n}\n\noperation Get {\n input: Key,\n output: Value,\n errors: [KeyNotFoundError]\n}\n\noperation Delete {\n input: Key,\n errors: [KeyNotFoundError]\n}\n\nstructure Key {\n @required\n key: String\n}\n\nstructure KeyValue {\n @required\n key: String,\n @required\n value: String\n}\n\nstructure Value {\n @required\n value: String\n}\n\n@error("client")\nstructure UnauthorizedError {\n @required\n reason: String\n}\n\n@error("client")\nstructure KeyNotFoundError {\n @required\n message: String\n}\n')),(0,o.kt)("h3",{id:"surfacing-errors"},"Surfacing errors"),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"smithy4s.Transformation.SurfaceError")," interface codifies the transformation of service implementations from contexts that represent errors as a generic ",(0,o.kt)("inlineCode",{parentName:"p"},"Throwable"),", from contexts that have the awareness of the errors specified in the specifications. It is useful when you want to exhaustively handle the errors that are specified (as opposed to letting them propagate)."),(0,o.kt)("p",null,"To make the ascription of such contexts easier, Smithy4s generates ",(0,o.kt)("inlineCode",{parentName:"p"},"ErrorAware[F[_, _]]"),' type aliases in the companion objects of services. This can\nbe used conjointly with types that have "two" parameters, one for the error, one for the result. For instance ',(0,o.kt)("inlineCode",{parentName:"p"},"type BIO[E, A] = EitherT[IO, E, A]"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-scala"},'import smithy4s.example._\nimport smithy4s.example.KVStore\nimport smithy4s.Transformation\nimport scala.util.{Failure, Success, Try}\n\nobject kvStoreTry extends KVStore[Try] {\n def delete(key: String): Try[Unit] = Success(())\n def put(key: String, value: String): Try[Unit] = Success(())\n def get(key: String): Failure[Value] = Failure(KeyNotFoundError(s"Key $key wasn\'t found"))\n}\n\n// SurfaceError allows to go from mono-functor to bi-functor, for instance, from\n// IO[A] to EitherT[IO, E, A]\nval toEither: Transformation.SurfaceError[Try, Either] =\n new Transformation.SurfaceError[Try, Either] {\n def apply[E, A](\n value: Try[A],\n catcher: Throwable => Option[E]\n ): Either[E, A] = value match {\n case Success(value) => Right(value)\n case Failure(error) =>\n catcher(error) match {\n case None => throw error // don\'t do this at work!\n case Some(e) => Left(e)\n }\n }\n }\n// toEither: Transformation.SurfaceError[Try, Either] = repl.MdocSession$MdocApp$$anon$3@4d3af272\n\nval kvStoreEither: KVStore.ErrorAware[Either] = kvStoreTry.transform(toEither)\n// kvStoreEither: KVStore.ErrorAware[Either] = smithy4s.example.KVStoreOperation$Transformed@33b2b965\nval result: Either[KVStore.GetError, Value] = kvStoreEither.get("foo")\n// result: Either[KVStore.GetError, Value] = Left(\n// value = KeyNotFoundErrorCase(\n// keyNotFoundError = KeyNotFoundError(message = "Key foo wasn\'t found")\n// )\n// )\n')),(0,o.kt)("h3",{id:"absorbing-errors"},"Absorbing errors"),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"smithy4s.Transformation.AbsorbErrors")," interface is the opposite as the ",(0,o.kt)("inlineCode",{parentName:"p"},"SurfaceError"),": it codifies the absorption of errors known by the service into generic error channels."),(0,o.kt)("p",null,"It is useful to implement services in a way that leverages the type-checker to ensure that the returned errors have been specified in Smithy,\nbefore passing the implementation to a generic router that is only able to work against a monofunctor."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-scala"},'import smithy4s.example._\nimport smithy4s.example.KVStore\nimport smithy4s.Transformation\nimport scala.util.{Failure, Success, Try}\n\nobject kvStoreEither extends KVStore.ErrorAware[Either] {\n def delete(key: String): Either[KVStore.DeleteError, Unit] = Right(())\n def put(key: String, value: String): Either[Nothing, Unit] = Right(())\n def get(key: String): Either[KVStore.GetError, Value] =\n Left(\n KVStore.GetError.KeyNotFoundErrorCase(\n KeyNotFoundError(s"Key $key wasn\'t found")\n )\n )\n}\n\nval toTry: Transformation.AbsorbError[Either, Try] =\n new Transformation.AbsorbError[Either, Try] {\n def apply[E, A](\n value: Either[E, A],\n thrower: E => Throwable\n ): Try[A] = value match {\n case Left(error) => Failure(thrower(error))\n case Right(value) => Success(value)\n }\n }\n// toTry: Transformation.AbsorbError[Either, Try] = repl.MdocSession$MdocApp3$$anon$4@16cf6be6\n\nval kvStoreTry: KVStore[Try] = kvStoreEither.transform(toTry)\n// kvStoreTry: KVStore[Try] = smithy4s.example.KVStoreOperation$Transformed@17930ff3\nval result: Try[Value] = kvStoreTry.get("foo")\n// result: Try[Value] = Failure(\n// exception = KeyNotFoundError(message = "Key foo wasn\'t found")\n// )\n')))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/ca30b741.6a19265a.js b/assets/js/ca30b741.bd581cc5.js similarity index 99% rename from assets/js/ca30b741.6a19265a.js rename to assets/js/ca30b741.bd581cc5.js index 768eb7b0d..dea27abda 100644 --- a/assets/js/ca30b741.6a19265a.js +++ b/assets/js/ca30b741.bd581cc5.js @@ -1 +1 @@ -"use strict";(self.webpackChunksmithy4s=self.webpackChunksmithy4s||[]).push([[2433],{3905:(e,t,a)=>{a.d(t,{Zo:()=>d,kt:()=>u});var i=a(7294);function n(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function s(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,i)}return a}function o(e){for(var t=1;t=0||(n[a]=e[a]);return n}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(n[a]=e[a])}return n}var l=i.createContext({}),c=function(e){var t=i.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},d=function(e){var t=c(e.components);return i.createElement(l.Provider,{value:t},e.children)},h="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},p=i.forwardRef((function(e,t){var a=e.components,n=e.mdxType,s=e.originalType,l=e.parentName,d=r(e,["components","mdxType","originalType","parentName"]),h=c(a),p=n,u=h["".concat(l,".").concat(p)]||h[p]||m[p]||s;return a?i.createElement(u,o(o({ref:t},d),{},{components:a})):i.createElement(u,o({ref:t},d))}));function u(e,t){var a=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var s=a.length,o=new Array(s);o[0]=p;var r={};for(var l in t)hasOwnProperty.call(t,l)&&(r[l]=t[l]);r.originalType=e,r[h]="string"==typeof e?e:n,o[1]=r;for(var c=2;c{a.r(t),a.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>m,frontMatter:()=>s,metadata:()=>r,toc:()=>c});var i=a(7462),n=(a(7294),a(3905));const s={sidebar_label:"Sharing specifications",title:"Sharing specifications"},o=void 0,r={unversionedId:"overview/sharing-specs",id:"overview/sharing-specs",title:"Sharing specifications",description:"The core Smithy tooling built by AWS makes it easy to load Smithy files that are packaged in jars. Smithy4s makes use of this feature to allow users",source:"@site/../docs/target/jvm-2.13/mdoc/01-overview/05-sharing-specs.md",sourceDirName:"01-overview",slug:"/overview/sharing-specs",permalink:"/smithy4s/docs/overview/sharing-specs",draft:!1,editUrl:"https://github.com/disneystreaming/smithy4s/edit/main/modules/docs/src/01-overview/05-sharing-specs.md",tags:[],version:"current",sidebarPosition:5,frontMatter:{sidebar_label:"Sharing specifications",title:"Sharing specifications"},sidebar:"tutorialSidebar",previous:{title:"Installation (CLI)",permalink:"/smithy4s/docs/overview/cli"},next:{title:"Stubbed implementations",permalink:"/smithy4s/docs/overview/stubs"}},l={},c=[{value:"Scala-agnostic context",id:"scala-agnostic-context",level:2},{value:"Smithy4s-context",id:"smithy4s-context",level:2},{value:"Disabling packaging of smithy files in jars",id:"disabling-packaging-of-smithy-files-in-jars",level:3},{value:"SBT",id:"sbt",level:4},{value:"Mill",id:"mill",level:4},{value:"Disabling the dependency on smithy files in sibling projects",id:"disabling-the-dependency-on-smithy-files-in-sibling-projects",level:3},{value:"SBT",id:"sbt-1",level:4},{value:"Mill",id:"mill-1",level:4},{value:"A word of warning",id:"a-word-of-warning",level:3},{value:"Artifacts containing only specifications",id:"artifacts-containing-only-specifications",level:2},{value:"SBT",id:"sbt-2",level:2},{value:"Mill",id:"mill-2",level:2},{value:"Consequence",id:"consequence",level:2},{value:"Artifacts containing both Smithy files and Smithy4s generated code",id:"artifacts-containing-both-smithy-files-and-smithy4s-generated-code",level:2},{value:"SBT",id:"sbt-3",level:3},{value:"Mill",id:"mill-3",level:3},{value:"Consequence",id:"consequence-1",level:3},{value:"Artifacts containing Smithy4s generated code: dependency tracking",id:"artifacts-containing-smithy4s-generated-code-dependency-tracking",level:2},{value:"Manually skipping (or including) namespaces during code-generation.",id:"manually-skipping-or-including-namespaces-during-code-generation",level:3},{value:"Note regarding credentials",id:"note-regarding-credentials",level:3}],d={toc:c},h="wrapper";function m(e){let{components:t,...a}=e;return(0,n.kt)(h,(0,i.Z)({},d,a,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("p",null,"The core Smithy tooling built by AWS makes it easy to load Smithy files that are packaged in jars. Smithy4s makes use of this feature to allow users\nto generate code from specs that may be found in Maven Central or other artifact repository."),(0,n.kt)("h1",{id:"packaging-specifications-in-order-to-share-them"},"Packaging specifications in order to share them"),(0,n.kt)("h2",{id:"scala-agnostic-context"},"Scala-agnostic context"),(0,n.kt)("p",null,"If you work in a context that is not primordially Scala-centric, you may want to package Smithy specification in Jars to make them easily accessible to various\ncode-generator tools. When that is the case, it is not-advised to use Smithy4s in order to package specifications, as the consuming applications/tools might not\nhave awareness of Scala. The best practice would likely be to have jars that would contain only Smithy files and potentially pure-java custom validators."),(0,n.kt)("p",null,"In order to package Smithy files in jars so that they can be easily consumed by tools, here are the core details:"),(0,n.kt)("ol",null,(0,n.kt)("li",{parentName:"ol"},"All smithy files should be stored under ",(0,n.kt)("inlineCode",{parentName:"li"},"src/main/resources/META-INF/smithy/")," (or in another resource directory, under ",(0,n.kt)("inlineCode",{parentName:"li"},"META-INF/smithy"),")"),(0,n.kt)("li",{parentName:"ol"},"A ",(0,n.kt)("inlineCode",{parentName:"li"},"manifest")," file should be stored under that same directory"),(0,n.kt)("li",{parentName:"ol"},"The ",(0,n.kt)("inlineCode",{parentName:"li"},"manifest")," file should reference all the smithy files that can be found in that ",(0,n.kt)("inlineCode",{parentName:"li"},"META-INF/smithy")," directory."),(0,n.kt)("li",{parentName:"ol"},"If you are using SBT to do this, consider setting ",(0,n.kt)("inlineCode",{parentName:"li"},"autoScalaLibrary := false"),". See ",(0,n.kt)("a",{parentName:"li",href:"https://www.scala-sbt.org/1.x/docs/Configuring-Scala.html#Configuring+the+scala-library+dependency"},"here")," for more information."),(0,n.kt)("li",{parentName:"ol"},"If you are using Mill to do this, consider using a ",(0,n.kt)("inlineCode",{parentName:"li"},"JavaModule")," instead of a ",(0,n.kt)("inlineCode",{parentName:"li"},"ScalaModule"),".")),(0,n.kt)("p",null,"A couple examples:"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/awslabs/smithy/tree/main/smithy-aws-apigateway-traits/src/main/resources/META-INF/smithy"},"smithy-aws-apigateway-traits")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/disneystreaming/smithy4s/blob/9f2dbcbd29b4dbd35792fa40e423a6395ae3f9e6/modules/protocol/resources/META-INF/smithy"},"smithy4s-protocols"))),(0,n.kt)("h2",{id:"smithy4s-context"},"Smithy4s-context"),(0,n.kt)("p",null,"The Smithy4s build-plugins we provide out of the box automatically package the local specifications (used for code-generations) in the resulting jars so that downstream projects (internal and external) can use them. When doing so, Smithy4s abides by the same structure described above."),(0,n.kt)("p",null,"Additionally, Smithy4s will also produce a smithy file containing a piece of metadata listing the namespaces for which code was generated. This way, downstream Smithy4s calls can automatically skip the already-generated namespaces."),(0,n.kt)("p",null,"This does mean two things:"),(0,n.kt)("ol",null,(0,n.kt)("li",{parentName:"ol"},"Users do not have to manually indicate namespaces that were already generated."),(0,n.kt)("li",{parentName:"ol"},"When using multi-module builds, Smithy specifications in one module can depend on Smithy specifications in another module it depends on, without the user having to do anything bespoke for it. The resulting Scala code in the downstream module will simply depend on the one in the upstream module, as if it had been handwritten.")),(0,n.kt)("h3",{id:"disabling-packaging-of-smithy-files-in-jars"},"Disabling packaging of smithy files in jars"),(0,n.kt)("p",null,"If for some reason you want to disable the packaging of Smithy files in the jars created by your build tool, follow the instructions below."),(0,n.kt)("h4",{id:"sbt"},"SBT"),(0,n.kt)("p",null,"Add the following setting to your project"),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-scala"},"Compile / smithy4sSmithyLibrary := false\n")),(0,n.kt)("h4",{id:"mill"},"Mill"),(0,n.kt)("p",null,"Override the following method in your module"),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-scala"},"override def smithy4sSmithyLibrary = T(false)\n")),(0,n.kt)("h3",{id:"disabling-the-dependency-on-smithy-files-in-sibling-projects"},"Disabling the dependency on smithy files in sibling projects"),(0,n.kt)("p",null,"If your project has a multi-module build and some of the modules have the plugin enabled,\ndue to the behavior documented above, dependencies will need to be compiled before code can be generated."),(0,n.kt)("p",null,"Consider the following build (sbt syntax):"),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-scala"},"val a = project\nval b = project.enablePlugin(Smithy4sCodegenPlugin).dependsOn(a)\n")),(0,n.kt)("p",null,"Whenever you want to generate the Scala code in project ",(0,n.kt)("inlineCode",{parentName:"p"},"b"),", your build tool will trigger compilation of ",(0,n.kt)("inlineCode",{parentName:"p"},"a"),". This happens so that the Smithy files in the ",(0,n.kt)("inlineCode",{parentName:"p"},"a")," project get packaged into a JAR file - just like they normally are when you package the ",(0,n.kt)("inlineCode",{parentName:"p"},"a")," project otherwise (for ",(0,n.kt)("inlineCode",{parentName:"p"},"publishLocal"),", ",(0,n.kt)("inlineCode",{parentName:"p"},"stage")," etc.)."),(0,n.kt)("p",null,"You can opt out of this behavior:"),(0,n.kt)("h4",{id:"sbt-1"},"SBT"),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-scala"},"val b = project.settings(\n Compile / smithy4sInternalDependenciesAsJars := Nil\n)//...\n")),(0,n.kt)("h4",{id:"mill-1"},"Mill"),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-scala"},"object b extends Smithy4sModule {\n //...\n override def smithy4sInternalDependenciesAsJars = List.empty[PathRef]\n}\n")),(0,n.kt)("p",null,"This will not only remove the need for compilation (for the purposes of codegen), but also remove any visibility of the Smithy files in the ",(0,n.kt)("strong",{parentName:"p"},"local")," dependencies of your project (",(0,n.kt)("strong",{parentName:"p"},"local")," meaning they're defined in the same build)."),(0,n.kt)("p",null,"You can use the same setting, ",(0,n.kt)("inlineCode",{parentName:"p"},"smithy4sInternalDependenciesAsJars"),", to add additional JARs containing Smithy specs - just keep in mind that remote dependencies (",(0,n.kt)("inlineCode",{parentName:"p"},"libraryDependencies"),") are added automatically!"),(0,n.kt)("h3",{id:"a-word-of-warning"},"A word of warning"),(0,n.kt)("p",null,'Smithy4s optimises for "correctness" as opposed to "compatibility." This means the generated Scala code aims at 1) being an accurate reflection of the Smithy models and 2) providing an idiomatic developer experience. This happens at the cost of a lack of guarantees around the binary compatibility of the generated code when the Schema evolves.'),(0,n.kt)("p",null,"When packaging Smithy specs in artifacts that contain Smithy4s-generated code, developers should keep that aspect in mind, and ensure that the version of Smithy4s that produced upstream artifacts is binary-compatible with the version that they use locally. Tools such as MiMa can help"),(0,n.kt)("p",null,"We cannot recommend treating Smithy4s-generated code as publishable library-material. Should you decide to do so, please exercise caution."),(0,n.kt)("h1",{id:"depending-on-shared-specifications"},"Depending on shared specifications"),(0,n.kt)("h2",{id:"artifacts-containing-only-specifications"},"Artifacts containing only specifications"),(0,n.kt)("p",null,"For instance, AWS publishes a number of ",(0,n.kt)("a",{parentName:"p",href:"https://github.com/awslabs/smithy/tree/main/smithy-aws-apigateway-traits/src/main/resources/META-INF/smithy"},"api-gateway specific traits")," to ",(0,n.kt)("a",{parentName:"p",href:"https://search.maven.org/artifact/software.amazon.smithy/smithy-aws-apigateway-traits"},"Maven central")," (the shapes are defined there in a smithy-compliant Json file)."),(0,n.kt)("h2",{id:"sbt-2"},"SBT"),(0,n.kt)("p",null,"Using the SBT plugin, the ",(0,n.kt)("inlineCode",{parentName:"p"},"Smithy4s")," config object can be used to tag dependencies that Smithy4s should feed to the code generator."),(0,n.kt)("p",null,"You can declare your intent to depend on these smithy definitions as such:"),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-scala"},'libraryDependencies += "software.amazon.smithy" % "smithy-aws-iam-traits" % "1.14.1" % Smithy4s\n')),(0,n.kt)("h2",{id:"mill-2"},"Mill"),(0,n.kt)("p",null,"Mill uses a separate task to define dependencies that the code-generator should have awareness of:"),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-scala"},'def smithy4sIvyDeps = Agg(ivy"software.amazon.smithy::smithy-aws-iam-traits:1.14.1")\n')),(0,n.kt)("h2",{id:"consequence"},"Consequence"),(0,n.kt)("p",null,"This will have the effect of loading the contents of the smithy files (or smithy-compliant Json files) from the artifact into the aggregated model that Smithy4s uses as an input to the code generator. It means that the traits and shapes defined in these files will be available to use in your models, but it also means that Smithy4s will try to generate code for these shapes."),(0,n.kt)("p",null,"This artifact will not be included as a dependency to your project at compile-time (nor runtime), it will only be consumed for the\nSmithy specs (and validators) it may contain."),(0,n.kt)("h2",{id:"artifacts-containing-both-smithy-files-and-smithy4s-generated-code"},"Artifacts containing both Smithy files and Smithy4s generated code"),(0,n.kt)("p",null,'When using Smithy4s, you may want to depend on artifacts that may have been built using Smithy4s, containing both Smithy specifications\nand generated Scala code (or rather, JVM bytecode resulting from the compilation of generated Scala code). In this case, you don\'t have to\ndo anything particular, the simple fact of declaring a library dependency will result in the smithy files contained by that dependency to be\nused during the "compilation" of your smithy specs during the code-generation process.'),(0,n.kt)("h3",{id:"sbt-3"},"SBT"),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-scala"},'libraryDependencies += "organisation" % "artifact" % "version"\n')),(0,n.kt)("h3",{id:"mill-3"},"Mill"),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-scala"},'def ivyDeps = T(Agg(ivy"organisation:artifact:version"))\n')),(0,n.kt)("h3",{id:"consequence-1"},"Consequence"),(0,n.kt)("p",null,'Because the upstream usage of Smithy4s will have resulted in the creation of metadata tracking the namespaces that were already generated, the "local" Smithy4s code-generation will automatically skip the generation of code that should not be generated again.'),(0,n.kt)("h2",{id:"artifacts-containing-smithy4s-generated-code-dependency-tracking"},"Artifacts containing Smithy4s generated code: dependency tracking"),(0,n.kt)("p",null,"When packaging a project/module via SBT or Mill, Smithy4s adds a line to the Jar manifest of the project, informing downstream projects of library dependencies that may have been used during the code-generation of this project/module (ie, the dependencies annotated with ",(0,n.kt)("inlineCode",{parentName:"p"},"% Smithy4s")," in SBT, and the ones provided by\n",(0,n.kt)("inlineCode",{parentName:"p"},"smithy4sIvyDeps")," in mill)."),(0,n.kt)("p",null,"This information is used automatically by downstream projects using Smithy4s, which automatically pulls additional jars that would be specified\nin this bit of metadata."),(0,n.kt)("p",null,"So, for instance, if you have"),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-scala"},'lazy val upstream = (project in file("foo"))\n .enablePlugins(Smithy4sCodegenPlugin)\n .settings(\n organization := "foobar",\n version := "0.0.1",\n libraryDependencies ++= Seq(\n "software.amazon.smithy" % "smithy-aws-iam-traits" % "1.14.1" % Smithy4s\n )\n )\n')),(0,n.kt)("p",null,"and publish this project to an artifact repository, the Jar manifest will contain a line with the relevant\ndependencies (comma separated if there are more than one) :"),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre"},"smithy4sDependencies: software.amazon.smithy:smithy-aws-iam-traits:1.14.1\n")),(0,n.kt)("p",null,"Using this artifact in a downstream project, for instance with :"),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-scala"},'lazy val downstream = (project in file("foo"))\n .enablePlugins(Smithy4sCodegenPlugin)\n .settings(\n libraryDependencies ++= Seq(\n // compile/runtime dependency that contains Smithy4s-generated code but doesn\'t contain smithy files\n "foobar" %% "upstream" % "0.0.1"\n )\n )\n')),(0,n.kt)("p",null,"will result in the ",(0,n.kt)("inlineCode",{parentName:"p"},'"software.amazon.smithy" % "smithy-aws-iam-traits" % "1.14.1"')," dependency being automatically fetched\nand used for the smithy-level classpath of the smithy files contained by ",(0,n.kt)("inlineCode",{parentName:"p"},"downstream"),". This effectively means that smithy files\nin ",(0,n.kt)("inlineCode",{parentName:"p"},"downstream")," can use the Smithy shapes present in the ",(0,n.kt)("inlineCode",{parentName:"p"},"smithy-aws-iam-traits")," artifact."),(0,n.kt)("p",null,"One side-effect of this is that if you produce JARs containing artifacts produced by Smithy4s code generation, they'll contain some common files with other smithy projects, particularly within the ",(0,n.kt)("inlineCode",{parentName:"p"},"META-INF")," folder. You'll need to write a custom ",(0,n.kt)("inlineCode",{parentName:"p"},"assemblyMergeStrategy"),", like so:"),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-sbt"},'assemblyMergeStrategy := {\n case PathList("META-INF", xs @ _*) =>\n xs.map(_.toLowerCase) match {\n // http4s-swagger provides the swagger webjar, which can conflict\n case "resources" :: "webjars" :: xs => MergeStrategy.first\n // There is no harm in removing the tracking file\n case "smithy" :: "smithy4s.tracking.smithy" => MergeStrategy.discard\n // Keep the correct smithy manifest\n case "smithy" :: "manifest" => MergeStrategy.first\n // Discard the rest\n case _ => MergeStrategy.discard\n }\n case x =>\n val oldStrategy = assemblyMergeStrategy.value\n oldStrategy(x)\n}\n')),(0,n.kt)("p",null,"This is perfectly fine to discard this file from your assembly jar."),(0,n.kt)("h3",{id:"manually-skipping-or-including-namespaces-during-code-generation"},"Manually skipping (or including) namespaces during code-generation."),(0,n.kt)("p",null,"Sometimes, you may want to tell Smithy4s to skip code-generation of some namespaces altogether, because the corresponding code may have been produced by another tool than Smithy4s. In that case, you can gain control over which namespaces Smithy4s crawls through when performing the code generation to avoid regenerating code that already exists. This is achieved via a couple of build-settings (the names are shared between SBT and Mill)."),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"smithy4sAllowedNamespaces")," which is an allow-list"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"smithy4sExcludedNamespaces")," which is a disallow-list")),(0,n.kt)("p",null,"By default, Smithy4s tries to generate everything but shapes that are in the following namespaces:"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"smithy4s.api")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"smithy4s.meta")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"alloy")),(0,n.kt)("li",{parentName:"ul"},"namespaces that start with ",(0,n.kt)("inlineCode",{parentName:"li"},"aws")),(0,n.kt)("li",{parentName:"ul"},"namespaces that start with ",(0,n.kt)("inlineCode",{parentName:"li"},"smithy"))),(0,n.kt)("h3",{id:"note-regarding-credentials"},"Note regarding credentials"),(0,n.kt)("p",null,"The SBT plugin provided by Smithy4s uses SBT's resolution mechanism (based on coursier) to retrieve the artifacts from their respective repositories. This implies that the resolvers-related settings are respected, included credentials that may be needed to read from some private artifact repository."),(0,n.kt)("p",null,"In the CLI, the ",(0,n.kt)("a",{parentName:"p",href:"https://get-coursier.io/docs/2.0.0-RC4-1/other-credentials#docsNav"},"mechanisms native to coursier")," are respected."))}m.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunksmithy4s=self.webpackChunksmithy4s||[]).push([[2433],{3905:(e,t,a)=>{a.d(t,{Zo:()=>d,kt:()=>u});var i=a(7294);function n(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function s(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,i)}return a}function o(e){for(var t=1;t=0||(n[a]=e[a]);return n}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(n[a]=e[a])}return n}var l=i.createContext({}),c=function(e){var t=i.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},d=function(e){var t=c(e.components);return i.createElement(l.Provider,{value:t},e.children)},h="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},p=i.forwardRef((function(e,t){var a=e.components,n=e.mdxType,s=e.originalType,l=e.parentName,d=r(e,["components","mdxType","originalType","parentName"]),h=c(a),p=n,u=h["".concat(l,".").concat(p)]||h[p]||m[p]||s;return a?i.createElement(u,o(o({ref:t},d),{},{components:a})):i.createElement(u,o({ref:t},d))}));function u(e,t){var a=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var s=a.length,o=new Array(s);o[0]=p;var r={};for(var l in t)hasOwnProperty.call(t,l)&&(r[l]=t[l]);r.originalType=e,r[h]="string"==typeof e?e:n,o[1]=r;for(var c=2;c{a.r(t),a.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>m,frontMatter:()=>s,metadata:()=>r,toc:()=>c});var i=a(7462),n=(a(7294),a(3905));const s={sidebar_label:"Sharing specifications",title:"Sharing specifications"},o=void 0,r={unversionedId:"overview/sharing-specs",id:"overview/sharing-specs",title:"Sharing specifications",description:"The core Smithy tooling built by AWS makes it easy to load Smithy files that are packaged in jars. Smithy4s makes use of this feature to allow users",source:"@site/../docs/target/jvm-2.13/mdoc/01-overview/05-sharing-specs.md",sourceDirName:"01-overview",slug:"/overview/sharing-specs",permalink:"/smithy4s/docs/overview/sharing-specs",draft:!1,editUrl:"https://github.com/disneystreaming/smithy4s/edit/main/modules/docs/src/01-overview/05-sharing-specs.md",tags:[],version:"current",sidebarPosition:5,frontMatter:{sidebar_label:"Sharing specifications",title:"Sharing specifications"},sidebar:"tutorialSidebar",previous:{title:"Installation (CLI)",permalink:"/smithy4s/docs/overview/cli"},next:{title:"Stubbed implementations",permalink:"/smithy4s/docs/overview/stubs"}},l={},c=[{value:"Scala-agnostic context",id:"scala-agnostic-context",level:2},{value:"Smithy4s-context",id:"smithy4s-context",level:2},{value:"Disabling packaging of smithy files in jars",id:"disabling-packaging-of-smithy-files-in-jars",level:3},{value:"SBT",id:"sbt",level:4},{value:"Mill",id:"mill",level:4},{value:"Disabling the dependency on smithy files in sibling projects",id:"disabling-the-dependency-on-smithy-files-in-sibling-projects",level:3},{value:"SBT",id:"sbt-1",level:4},{value:"Mill",id:"mill-1",level:4},{value:"A word of warning",id:"a-word-of-warning",level:3},{value:"Artifacts containing only specifications",id:"artifacts-containing-only-specifications",level:2},{value:"SBT",id:"sbt-2",level:2},{value:"Mill",id:"mill-2",level:2},{value:"Consequence",id:"consequence",level:2},{value:"Artifacts containing both Smithy files and Smithy4s generated code",id:"artifacts-containing-both-smithy-files-and-smithy4s-generated-code",level:2},{value:"SBT",id:"sbt-3",level:3},{value:"Mill",id:"mill-3",level:3},{value:"Consequence",id:"consequence-1",level:3},{value:"Artifacts containing Smithy4s generated code: dependency tracking",id:"artifacts-containing-smithy4s-generated-code-dependency-tracking",level:2},{value:"Manually skipping (or including) namespaces during code-generation.",id:"manually-skipping-or-including-namespaces-during-code-generation",level:3},{value:"Note regarding credentials",id:"note-regarding-credentials",level:3}],d={toc:c},h="wrapper";function m(e){let{components:t,...a}=e;return(0,n.kt)(h,(0,i.Z)({},d,a,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("p",null,"The core Smithy tooling built by AWS makes it easy to load Smithy files that are packaged in jars. Smithy4s makes use of this feature to allow users\nto generate code from specs that may be found in Maven Central or other artifact repository."),(0,n.kt)("h1",{id:"packaging-specifications-in-order-to-share-them"},"Packaging specifications in order to share them"),(0,n.kt)("h2",{id:"scala-agnostic-context"},"Scala-agnostic context"),(0,n.kt)("p",null,"If you work in a context that is not primordially Scala-centric, you may want to package Smithy specification in Jars to make them easily accessible to various\ncode-generator tools. When that is the case, it is not-advised to use Smithy4s in order to package specifications, as the consuming applications/tools might not\nhave awareness of Scala. The best practice would likely be to have jars that would contain only Smithy files and potentially pure-java custom validators."),(0,n.kt)("p",null,"In order to package Smithy files in jars so that they can be easily consumed by tools, here are the core details:"),(0,n.kt)("ol",null,(0,n.kt)("li",{parentName:"ol"},"All smithy files should be stored under ",(0,n.kt)("inlineCode",{parentName:"li"},"src/main/resources/META-INF/smithy/")," (or in another resource directory, under ",(0,n.kt)("inlineCode",{parentName:"li"},"META-INF/smithy"),")"),(0,n.kt)("li",{parentName:"ol"},"A ",(0,n.kt)("inlineCode",{parentName:"li"},"manifest")," file should be stored under that same directory"),(0,n.kt)("li",{parentName:"ol"},"The ",(0,n.kt)("inlineCode",{parentName:"li"},"manifest")," file should reference all the smithy files that can be found in that ",(0,n.kt)("inlineCode",{parentName:"li"},"META-INF/smithy")," directory."),(0,n.kt)("li",{parentName:"ol"},"If you are using SBT to do this, consider setting ",(0,n.kt)("inlineCode",{parentName:"li"},"autoScalaLibrary := false"),". See ",(0,n.kt)("a",{parentName:"li",href:"https://www.scala-sbt.org/1.x/docs/Configuring-Scala.html#Configuring+the+scala-library+dependency"},"here")," for more information."),(0,n.kt)("li",{parentName:"ol"},"If you are using Mill to do this, consider using a ",(0,n.kt)("inlineCode",{parentName:"li"},"JavaModule")," instead of a ",(0,n.kt)("inlineCode",{parentName:"li"},"ScalaModule"),".")),(0,n.kt)("p",null,"A couple examples:"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/awslabs/smithy/tree/main/smithy-aws-apigateway-traits/src/main/resources/META-INF/smithy"},"smithy-aws-apigateway-traits")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/disneystreaming/smithy4s/blob/8cb01fd92d65f6e4ec515fccb3677cffe6a1093b/modules/protocol/resources/META-INF/smithy"},"smithy4s-protocols"))),(0,n.kt)("h2",{id:"smithy4s-context"},"Smithy4s-context"),(0,n.kt)("p",null,"The Smithy4s build-plugins we provide out of the box automatically package the local specifications (used for code-generations) in the resulting jars so that downstream projects (internal and external) can use them. When doing so, Smithy4s abides by the same structure described above."),(0,n.kt)("p",null,"Additionally, Smithy4s will also produce a smithy file containing a piece of metadata listing the namespaces for which code was generated. This way, downstream Smithy4s calls can automatically skip the already-generated namespaces."),(0,n.kt)("p",null,"This does mean two things:"),(0,n.kt)("ol",null,(0,n.kt)("li",{parentName:"ol"},"Users do not have to manually indicate namespaces that were already generated."),(0,n.kt)("li",{parentName:"ol"},"When using multi-module builds, Smithy specifications in one module can depend on Smithy specifications in another module it depends on, without the user having to do anything bespoke for it. The resulting Scala code in the downstream module will simply depend on the one in the upstream module, as if it had been handwritten.")),(0,n.kt)("h3",{id:"disabling-packaging-of-smithy-files-in-jars"},"Disabling packaging of smithy files in jars"),(0,n.kt)("p",null,"If for some reason you want to disable the packaging of Smithy files in the jars created by your build tool, follow the instructions below."),(0,n.kt)("h4",{id:"sbt"},"SBT"),(0,n.kt)("p",null,"Add the following setting to your project"),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-scala"},"Compile / smithy4sSmithyLibrary := false\n")),(0,n.kt)("h4",{id:"mill"},"Mill"),(0,n.kt)("p",null,"Override the following method in your module"),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-scala"},"override def smithy4sSmithyLibrary = T(false)\n")),(0,n.kt)("h3",{id:"disabling-the-dependency-on-smithy-files-in-sibling-projects"},"Disabling the dependency on smithy files in sibling projects"),(0,n.kt)("p",null,"If your project has a multi-module build and some of the modules have the plugin enabled,\ndue to the behavior documented above, dependencies will need to be compiled before code can be generated."),(0,n.kt)("p",null,"Consider the following build (sbt syntax):"),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-scala"},"val a = project\nval b = project.enablePlugin(Smithy4sCodegenPlugin).dependsOn(a)\n")),(0,n.kt)("p",null,"Whenever you want to generate the Scala code in project ",(0,n.kt)("inlineCode",{parentName:"p"},"b"),", your build tool will trigger compilation of ",(0,n.kt)("inlineCode",{parentName:"p"},"a"),". This happens so that the Smithy files in the ",(0,n.kt)("inlineCode",{parentName:"p"},"a")," project get packaged into a JAR file - just like they normally are when you package the ",(0,n.kt)("inlineCode",{parentName:"p"},"a")," project otherwise (for ",(0,n.kt)("inlineCode",{parentName:"p"},"publishLocal"),", ",(0,n.kt)("inlineCode",{parentName:"p"},"stage")," etc.)."),(0,n.kt)("p",null,"You can opt out of this behavior:"),(0,n.kt)("h4",{id:"sbt-1"},"SBT"),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-scala"},"val b = project.settings(\n Compile / smithy4sInternalDependenciesAsJars := Nil\n)//...\n")),(0,n.kt)("h4",{id:"mill-1"},"Mill"),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-scala"},"object b extends Smithy4sModule {\n //...\n override def smithy4sInternalDependenciesAsJars = List.empty[PathRef]\n}\n")),(0,n.kt)("p",null,"This will not only remove the need for compilation (for the purposes of codegen), but also remove any visibility of the Smithy files in the ",(0,n.kt)("strong",{parentName:"p"},"local")," dependencies of your project (",(0,n.kt)("strong",{parentName:"p"},"local")," meaning they're defined in the same build)."),(0,n.kt)("p",null,"You can use the same setting, ",(0,n.kt)("inlineCode",{parentName:"p"},"smithy4sInternalDependenciesAsJars"),", to add additional JARs containing Smithy specs - just keep in mind that remote dependencies (",(0,n.kt)("inlineCode",{parentName:"p"},"libraryDependencies"),") are added automatically!"),(0,n.kt)("h3",{id:"a-word-of-warning"},"A word of warning"),(0,n.kt)("p",null,'Smithy4s optimises for "correctness" as opposed to "compatibility." This means the generated Scala code aims at 1) being an accurate reflection of the Smithy models and 2) providing an idiomatic developer experience. This happens at the cost of a lack of guarantees around the binary compatibility of the generated code when the Schema evolves.'),(0,n.kt)("p",null,"When packaging Smithy specs in artifacts that contain Smithy4s-generated code, developers should keep that aspect in mind, and ensure that the version of Smithy4s that produced upstream artifacts is binary-compatible with the version that they use locally. Tools such as MiMa can help"),(0,n.kt)("p",null,"We cannot recommend treating Smithy4s-generated code as publishable library-material. Should you decide to do so, please exercise caution."),(0,n.kt)("h1",{id:"depending-on-shared-specifications"},"Depending on shared specifications"),(0,n.kt)("h2",{id:"artifacts-containing-only-specifications"},"Artifacts containing only specifications"),(0,n.kt)("p",null,"For instance, AWS publishes a number of ",(0,n.kt)("a",{parentName:"p",href:"https://github.com/awslabs/smithy/tree/main/smithy-aws-apigateway-traits/src/main/resources/META-INF/smithy"},"api-gateway specific traits")," to ",(0,n.kt)("a",{parentName:"p",href:"https://search.maven.org/artifact/software.amazon.smithy/smithy-aws-apigateway-traits"},"Maven central")," (the shapes are defined there in a smithy-compliant Json file)."),(0,n.kt)("h2",{id:"sbt-2"},"SBT"),(0,n.kt)("p",null,"Using the SBT plugin, the ",(0,n.kt)("inlineCode",{parentName:"p"},"Smithy4s")," config object can be used to tag dependencies that Smithy4s should feed to the code generator."),(0,n.kt)("p",null,"You can declare your intent to depend on these smithy definitions as such:"),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-scala"},'libraryDependencies += "software.amazon.smithy" % "smithy-aws-iam-traits" % "1.14.1" % Smithy4s\n')),(0,n.kt)("h2",{id:"mill-2"},"Mill"),(0,n.kt)("p",null,"Mill uses a separate task to define dependencies that the code-generator should have awareness of:"),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-scala"},'def smithy4sIvyDeps = Agg(ivy"software.amazon.smithy::smithy-aws-iam-traits:1.14.1")\n')),(0,n.kt)("h2",{id:"consequence"},"Consequence"),(0,n.kt)("p",null,"This will have the effect of loading the contents of the smithy files (or smithy-compliant Json files) from the artifact into the aggregated model that Smithy4s uses as an input to the code generator. It means that the traits and shapes defined in these files will be available to use in your models, but it also means that Smithy4s will try to generate code for these shapes."),(0,n.kt)("p",null,"This artifact will not be included as a dependency to your project at compile-time (nor runtime), it will only be consumed for the\nSmithy specs (and validators) it may contain."),(0,n.kt)("h2",{id:"artifacts-containing-both-smithy-files-and-smithy4s-generated-code"},"Artifacts containing both Smithy files and Smithy4s generated code"),(0,n.kt)("p",null,'When using Smithy4s, you may want to depend on artifacts that may have been built using Smithy4s, containing both Smithy specifications\nand generated Scala code (or rather, JVM bytecode resulting from the compilation of generated Scala code). In this case, you don\'t have to\ndo anything particular, the simple fact of declaring a library dependency will result in the smithy files contained by that dependency to be\nused during the "compilation" of your smithy specs during the code-generation process.'),(0,n.kt)("h3",{id:"sbt-3"},"SBT"),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-scala"},'libraryDependencies += "organisation" % "artifact" % "version"\n')),(0,n.kt)("h3",{id:"mill-3"},"Mill"),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-scala"},'def ivyDeps = T(Agg(ivy"organisation:artifact:version"))\n')),(0,n.kt)("h3",{id:"consequence-1"},"Consequence"),(0,n.kt)("p",null,'Because the upstream usage of Smithy4s will have resulted in the creation of metadata tracking the namespaces that were already generated, the "local" Smithy4s code-generation will automatically skip the generation of code that should not be generated again.'),(0,n.kt)("h2",{id:"artifacts-containing-smithy4s-generated-code-dependency-tracking"},"Artifacts containing Smithy4s generated code: dependency tracking"),(0,n.kt)("p",null,"When packaging a project/module via SBT or Mill, Smithy4s adds a line to the Jar manifest of the project, informing downstream projects of library dependencies that may have been used during the code-generation of this project/module (ie, the dependencies annotated with ",(0,n.kt)("inlineCode",{parentName:"p"},"% Smithy4s")," in SBT, and the ones provided by\n",(0,n.kt)("inlineCode",{parentName:"p"},"smithy4sIvyDeps")," in mill)."),(0,n.kt)("p",null,"This information is used automatically by downstream projects using Smithy4s, which automatically pulls additional jars that would be specified\nin this bit of metadata."),(0,n.kt)("p",null,"So, for instance, if you have"),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-scala"},'lazy val upstream = (project in file("foo"))\n .enablePlugins(Smithy4sCodegenPlugin)\n .settings(\n organization := "foobar",\n version := "0.0.1",\n libraryDependencies ++= Seq(\n "software.amazon.smithy" % "smithy-aws-iam-traits" % "1.14.1" % Smithy4s\n )\n )\n')),(0,n.kt)("p",null,"and publish this project to an artifact repository, the Jar manifest will contain a line with the relevant\ndependencies (comma separated if there are more than one) :"),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre"},"smithy4sDependencies: software.amazon.smithy:smithy-aws-iam-traits:1.14.1\n")),(0,n.kt)("p",null,"Using this artifact in a downstream project, for instance with :"),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-scala"},'lazy val downstream = (project in file("foo"))\n .enablePlugins(Smithy4sCodegenPlugin)\n .settings(\n libraryDependencies ++= Seq(\n // compile/runtime dependency that contains Smithy4s-generated code but doesn\'t contain smithy files\n "foobar" %% "upstream" % "0.0.1"\n )\n )\n')),(0,n.kt)("p",null,"will result in the ",(0,n.kt)("inlineCode",{parentName:"p"},'"software.amazon.smithy" % "smithy-aws-iam-traits" % "1.14.1"')," dependency being automatically fetched\nand used for the smithy-level classpath of the smithy files contained by ",(0,n.kt)("inlineCode",{parentName:"p"},"downstream"),". This effectively means that smithy files\nin ",(0,n.kt)("inlineCode",{parentName:"p"},"downstream")," can use the Smithy shapes present in the ",(0,n.kt)("inlineCode",{parentName:"p"},"smithy-aws-iam-traits")," artifact."),(0,n.kt)("p",null,"One side-effect of this is that if you produce JARs containing artifacts produced by Smithy4s code generation, they'll contain some common files with other smithy projects, particularly within the ",(0,n.kt)("inlineCode",{parentName:"p"},"META-INF")," folder. You'll need to write a custom ",(0,n.kt)("inlineCode",{parentName:"p"},"assemblyMergeStrategy"),", like so:"),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-sbt"},'assemblyMergeStrategy := {\n case PathList("META-INF", xs @ _*) =>\n xs.map(_.toLowerCase) match {\n // http4s-swagger provides the swagger webjar, which can conflict\n case "resources" :: "webjars" :: xs => MergeStrategy.first\n // There is no harm in removing the tracking file\n case "smithy" :: "smithy4s.tracking.smithy" => MergeStrategy.discard\n // Keep the correct smithy manifest\n case "smithy" :: "manifest" => MergeStrategy.first\n // Discard the rest\n case _ => MergeStrategy.discard\n }\n case x =>\n val oldStrategy = assemblyMergeStrategy.value\n oldStrategy(x)\n}\n')),(0,n.kt)("p",null,"This is perfectly fine to discard this file from your assembly jar."),(0,n.kt)("h3",{id:"manually-skipping-or-including-namespaces-during-code-generation"},"Manually skipping (or including) namespaces during code-generation."),(0,n.kt)("p",null,"Sometimes, you may want to tell Smithy4s to skip code-generation of some namespaces altogether, because the corresponding code may have been produced by another tool than Smithy4s. In that case, you can gain control over which namespaces Smithy4s crawls through when performing the code generation to avoid regenerating code that already exists. This is achieved via a couple of build-settings (the names are shared between SBT and Mill)."),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"smithy4sAllowedNamespaces")," which is an allow-list"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"smithy4sExcludedNamespaces")," which is a disallow-list")),(0,n.kt)("p",null,"By default, Smithy4s tries to generate everything but shapes that are in the following namespaces:"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"smithy4s.api")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"smithy4s.meta")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"alloy")),(0,n.kt)("li",{parentName:"ul"},"namespaces that start with ",(0,n.kt)("inlineCode",{parentName:"li"},"aws")),(0,n.kt)("li",{parentName:"ul"},"namespaces that start with ",(0,n.kt)("inlineCode",{parentName:"li"},"smithy"))),(0,n.kt)("h3",{id:"note-regarding-credentials"},"Note regarding credentials"),(0,n.kt)("p",null,"The SBT plugin provided by Smithy4s uses SBT's resolution mechanism (based on coursier) to retrieve the artifacts from their respective repositories. This implies that the resolvers-related settings are respected, included credentials that may be needed to read from some private artifact repository."),(0,n.kt)("p",null,"In the CLI, the ",(0,n.kt)("a",{parentName:"p",href:"https://get-coursier.io/docs/2.0.0-RC4-1/other-credentials#docsNav"},"mechanisms native to coursier")," are respected."))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/d2e0906e.42d05ba2.js b/assets/js/d2e0906e.33f23e18.js similarity index 98% rename from assets/js/d2e0906e.42d05ba2.js rename to assets/js/d2e0906e.33f23e18.js index f4f8ef9e8..2a2a30578 100644 --- a/assets/js/d2e0906e.42d05ba2.js +++ b/assets/js/d2e0906e.33f23e18.js @@ -1 +1 @@ -"use strict";(self.webpackChunksmithy4s=self.webpackChunksmithy4s||[]).push([[2419],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>u});var a=n(7294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var l=a.createContext({}),p=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},c=function(e){var t=p(e.components);return a.createElement(l.Provider,{value:t},e.children)},m="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var n=e.components,i=e.mdxType,r=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),m=p(n),h=i,u=m["".concat(l,".").concat(h)]||m[h]||d[h]||r;return n?a.createElement(u,o(o({ref:t},c),{},{components:n})):a.createElement(u,o({ref:t},c))}));function u(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var r=n.length,o=new Array(r);o[0]=h;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[m]="string"==typeof e?e:i,o[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>d,frontMatter:()=>r,metadata:()=>s,toc:()=>p});var a=n(7462),i=(n(7294),n(3905));const r={sidebar_label:"Dynamic module",title:"Dynamic module"},o=void 0,s={unversionedId:"guides/dynamic",id:"guides/dynamic",title:"Dynamic module",description:"Introduction",source:"@site/../docs/target/jvm-2.13/mdoc/06-guides/dynamic.md",sourceDirName:"06-guides",slug:"/guides/dynamic",permalink:"/smithy4s/docs/guides/dynamic",draft:!1,editUrl:"https://github.com/disneystreaming/smithy4s/edit/main/modules/docs/src/06-guides/dynamic.md",tags:[],version:"current",frontMatter:{sidebar_label:"Dynamic module",title:"Dynamic module"},sidebar:"tutorialSidebar",previous:{title:"Services and endpoints",permalink:"/smithy4s/docs/design/services"},next:{title:"Endpoint Specific Middleware",permalink:"/smithy4s/docs/guides/endpoint-middleware"}},l={},p=[{value:"Introduction",id:"introduction",level:2},{value:"(Why) do we need codegen?",id:"why-do-we-need-codegen",level:2},{value:"The Dynamic way",id:"the-dynamic-way",level:2},{value:"Loading a dynamic model",id:"loading-a-dynamic-model",level:2},{value:"Using the DSI",id:"using-the-dsi",level:2},{value:"Case study: dynamic HTTP client",id:"case-study-dynamic-http-client",level:2}],c={toc:p},m="wrapper";function d(e){let{components:t,...n}=e;return(0,i.kt)(m,(0,a.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h2",{id:"introduction"},"Introduction"),(0,i.kt)("p",null,"It is highly recommended to learn about ",(0,i.kt)("a",{parentName:"p",href:"/smithy4s/docs/design/design"},"the library's design")," before going into this section."),(0,i.kt)("p",null,"Smithy4s is first and foremost a code generation tool for the Smithy language in Scala. Although it does provide interpreters for the Smithy services, which can be used to derive e.g. HTTP clients and servers, the codegen way can only get you so far - there are some situations when it's ",(0,i.kt)("strong",{parentName:"p"},"not sufficient for the job"),"."),(0,i.kt)("p",null,"Code generation works well if your Smithy model changes ",(0,i.kt)("strong",{parentName:"p"},"no more often")," than your service's implementation - as long as you run your build whenever you make a code change, codegen will also be triggered,\nand the Scala compiler will ensure you're in sync with the Smithy model in its present state. But what if your Smithy model changes are ",(0,i.kt)("strong",{parentName:"p"},"more frequent")," than the service? Or what if you simply don't have access to all the Smithy models your code might have to work with?"),(0,i.kt)("p",null,"These cases, and possibly others, are why Smithy4s has the ",(0,i.kt)("inlineCode",{parentName:"p"},"dynamic")," module."),(0,i.kt)("h2",{id:"why-do-we-need-codegen"},"(Why) do we need codegen?"),(0,i.kt)("p",null,"As you know by now, Smithy4s's codegen is static - it requires the model to be available at build-time, so that code can be generated and made available to you at compile-time."),(0,i.kt)("p",null,"In short, what happens at ",(0,i.kt)("strong",{parentName:"p"},"build-time")," are the following steps:"),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("strong",{parentName:"li"},"Read")," the Smithy files available to your build"),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("strong",{parentName:"li"},"Build")," a ",(0,i.kt)("a",{parentName:"li",href:"https://smithy.io/2.0/spec/model.html"},"semantic Smithy model"),", which is roughly a graph of shapes that refer to each other"),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("strong",{parentName:"li"},"Generate")," files for each relevant shape in the model (e.g. a service, a structure, an enum...), including metadata (",(0,i.kt)("a",{parentName:"li",href:"/smithy4s/docs/design/services"},"services")," and ",(0,i.kt)("a",{parentName:"li",href:"/smithy4s/docs/design/schemas"},"schemas"),").")),(0,i.kt)("p",null,"Then, there's the ",(0,i.kt)("strong",{parentName:"p"},"runtime")," part. Let's say you're building an HTTP client - in that case, what you see as a Smithy4s user is:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},"SimpleRestJson(WeatherService)\n .client(??? : org.http4s.client.Client[IO])\n .make\n")),(0,i.kt)("p",null,"or more generically:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"interpretToRestClient(WeatherService)\n")),(0,i.kt)("p",null,"The steps that the HTTP client interpreter performs to build a high-level client are:"),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("strong",{parentName:"li"},"Capture")," a ",(0,i.kt)("a",{parentName:"li",href:"/smithy4s/docs/design/services"},"Smithy4s service")," representing the service you wrote in Smithy. This was generated by Smithy4s's codegen."),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("strong",{parentName:"li"},"Analyze")," the service's endpoints, their input/output schemas, the Hints on these schemas..."),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("strong",{parentName:"li"},"Transform")," the service description into a high-level proxy to the underlying client implementation.")),(0,i.kt)("p",null,"Turns out that interpreters like this ",(0,i.kt)("strong",{parentName:"p"},"aren't ",(0,i.kt)("em",{parentName:"strong"},"actually")," aware")," of the fact that there's code generation involved. As long as you can provide a data structure describing your service, its endpoints and their schemas (which is indeed the ",(0,i.kt)("inlineCode",{parentName:"p"},"Service")," type),\nyou can use any interpreter that requires one: code generation is just ",(0,i.kt)("strong",{parentName:"p"},"a means to derive")," such a data structure automatically from your Smithy model."),(0,i.kt)("p",null,"This all is why ",(0,i.kt)("strong",{parentName:"p"},"you don't ",(0,i.kt)("em",{parentName:"strong"},"need")," code generation")," to benefit from the interpreters - you just need a way to instantiate a Smithy4s Service (or Schema, if that's what your interpreter operates on)."),(0,i.kt)("p",null,"The Dynamic module of smithy4s was made exactly for that purpose."),(0,i.kt)("h2",{id:"the-dynamic-way"},"The Dynamic way"),(0,i.kt)("p",null,"In the previous section, we looked at the steps performed at build time to generate code:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Read Smithy files"),(0,i.kt)("li",{parentName:"ul"},"Build a Smithy model"),(0,i.kt)("li",{parentName:"ul"},"Generate Scala files with Smithy4s schemas.")),(0,i.kt)("p",null,"Don't be fooled - although we had Smithy files as the input and Scala files as the output, the really important part was getting from the Smithy model to the ",(0,i.kt)("strong",{parentName:"p"},"Service and Schema instances")," representing it.\nThe Dynamic module of smithy4s provides a way to ",(0,i.kt)("strong",{parentName:"p"},"do this at runtime"),"."),(0,i.kt)("p",null,"And the runtime part, where the interpreter runs? ",(0,i.kt)("strong",{parentName:"p"},"It's the same as before!")," The Service and Schema interfaces are identical regardless of the static/dynamic usecase, and so are the interpreters",(0,i.kt)("sup",{parentName:"p",id:"fnref-1"},(0,i.kt)("a",{parentName:"sup",href:"#fn-1",className:"footnote-ref"},"1")),"."),(0,i.kt)("h2",{id:"loading-a-dynamic-model"},"Loading a dynamic model"),(0,i.kt)("p",null,"First of all, you need the dependency:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},'libraryDependencies ++= Seq(\n // version sourced from the plugin\n "com.disneystreaming.smithy4s" %% "smithy4s-dynamic" % smithy4sVersion.value\n)\n')),(0,i.kt)("p",null,"Now, you need a Smithy model. There are essentially three ways to get one:"),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Load a model using the ",(0,i.kt)("a",{parentName:"li",href:"https://github.com/awslabs/smithy"},"awslabs/smithy")," library's ",(0,i.kt)("inlineCode",{parentName:"li"},"ModelAssembler")),(0,i.kt)("li",{parentName:"ol"},"Load a serialized model from a JSON file (",(0,i.kt)("a",{parentName:"li",href:"https://github.com/disneystreaming/smithy4s/blob/4e678c5f89599f962dc18fb7dcdf3d5d6c0a402b/sampleSpecs/lambda.json"},"example"),"), or"),(0,i.kt)("li",{parentName:"ol"},"Deserialize or generate the ",(0,i.kt)("inlineCode",{parentName:"li"},"smithy4s.dynamic.model.Model")," data structure in any way you want, on your own.")),(0,i.kt)("p",null,"The ",(0,i.kt)("inlineCode",{parentName:"p"},"ModelAssembler")," way only works on the JVM, because Smithy's reference implementation is a Java library. We'll use that way for this guide:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},'import software.amazon.smithy.model.Model\n\nval s = """\n$version: "2"\n\nnamespace weather\n\nuse alloy#simpleRestJson\n\n@simpleRestJson\nservice WeatherService {\n operations: [GetWeather]\n}\n\n@http(method: "GET", uri: "/weather/{city}")\noperation GetWeather {\n input := {\n @httpLabel\n @required\n city: String\n }\n output := {\n @required\n weather: String\n }\n}\n\nstructure Dog {\n @required\n name: String\n}\n"""\n\nval model = Model\n .assembler()\n .addUnparsedModel(\n "weather.smithy",\n s,\n )\n .discoverModels()\n .assemble()\n .unwrap()\n')),(0,i.kt)("p",null,"The entrypoint to loading models is ",(0,i.kt)("inlineCode",{parentName:"p"},"DynamicSchemaIndex"),"."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},"import smithy4s.dynamic.DynamicSchemaIndex\nval dsi = DynamicSchemaIndex.loadModel(model)\n// dsi: DynamicSchemaIndex = smithy4s.dynamic.internals.DynamicSchemaIndexImpl@46c456ad\n")),(0,i.kt)("p",null,"For alternative ways to load a DSI, see ",(0,i.kt)("inlineCode",{parentName:"p"},"DynamicSchemaIndex.load"),"."),(0,i.kt)("h2",{id:"using-the-dsi"},"Using the DSI"),(0,i.kt)("p",null,"Having a ",(0,i.kt)("inlineCode",{parentName:"p"},"DynamicSchemaIndex"),", we can iterate over all the services available to it:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},'dsi.allServices.map(_.service.id)\n// res0: Iterable[smithy4s.ShapeId] = List(\n// ShapeId(namespace = "weather", name = "WeatherService")\n// )\n')),(0,i.kt)("p",null,"as well as the schemas:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},'dsi.allSchemas.map(_.shapeId).filter(_.namespace == "weather")\n// res1: Iterable[smithy4s.ShapeId] = List(\n// ShapeId(namespace = "weather", name = "GetWeatherInput"),\n// ShapeId(namespace = "weather", name = "GetWeatherOutput"),\n// ShapeId(namespace = "weather", name = "Dog")\n// )\n')),(0,i.kt)("p",null,"You can also access a service or schema by ID:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},'import smithy4s.ShapeId\n\ndsi.getService(ShapeId("weather", "WeatherService")).get.service.id\n// res2: ShapeId = ShapeId(namespace = "weather", name = "WeatherService")\ndsi.getSchema(ShapeId("weather", "Dog")).get.shapeId\n// res3: ShapeId = ShapeId(namespace = "weather", name = "Dog")\n')),(0,i.kt)("p",null,"Note that you don't know the exact type of a schema at compile-time:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},'import smithy4s.Schema\n\ndsi.getSchema(ShapeId("weather", "Dog")).get\n// res4: Schema[_] = StructSchema(\n// shapeId = ShapeId(namespace = "weather", name = "Dog"),\n// hints = Impl(memberHintsMap = Map(), targetHintsMap = Map()),\n// fields = Vector(\n// Field(\n// label = "name",\n// schema = PrimitiveSchema(\n// shapeId = ShapeId(namespace = "smithy.api", name = "String"),\n// hints = Impl(\n// memberHintsMap = Map(\n// ShapeId(namespace = "smithy.api", name = "required") -> DynamicBinding(\n// keyId = ShapeId(namespace = "smithy.api", name = "required"),\n// value = DObject(value = ListMap())\n// )\n// ),\n// targetHintsMap = Map()\n// ),\n// tag = PString\n// ),\n// get = Accessor(index = 0)\n// )\n// ),\n// make = \n// )\n')),(0,i.kt)("p",null,"It is very similar for services. This is simply due to the fact that at compile-time (which is where typechecking happens) we have no clue what the possible type of the schema could be.\nAfter all, the String representing the model doesn't have to be constant - it could be fetched from the network, and even vary throughout the lifetime of our application!"),(0,i.kt)("p",null,"This doesn't forbid us from using these dynamic goodies in interpreters, though."),(0,i.kt)("h2",{id:"case-study-dynamic-http-client"},"Case study: dynamic HTTP client"),(0,i.kt)("p",null,"Let's make a REST client for a dynamic service. We'll start by writing an interpreter."),(0,i.kt)("p",null,(0,i.kt)("em",{parentName:"p"},'"But wait, weren\'t we supposed to be able to use the existing interpreters?"')),(0,i.kt)("p",null,"That's true - the underlying implementation will use the interpreters made for the static world as well.\nHowever, due to the strangely-typed nature of the dynamic world, we have to deal with some complexity that's normally invisible to the user."),(0,i.kt)("p",null,"For example, you can write this in the static world:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},'import cats.effect.IO\nimport weather._\n\n// imagine this comes from an interpreter\nval client: WeatherService[IO] = ??? : WeatherService[IO]\n\nclient.getWeather(city = "hello")\n')),(0,i.kt)("p",null,"but you can't do it if your model gets loaded dynamically! You wouldn't be able to compile that code, because there's no way to tell what services you'll load at runtime."),(0,i.kt)("p",null,"This means that we'll need a different way to pass the following pieces to an interpreter at runtime:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"the service being used (",(0,i.kt)("inlineCode",{parentName:"li"},"HelloWorldService"),")"),(0,i.kt)("li",{parentName:"ul"},"the operation being called (",(0,i.kt)("inlineCode",{parentName:"li"},"Hello"),")"),(0,i.kt)("li",{parentName:"ul"},"the operation input (a single parameter: ",(0,i.kt)("inlineCode",{parentName:"li"},"name")," = ",(0,i.kt)("inlineCode",{parentName:"li"},'"Hello"'),")")),(0,i.kt)("p",null,"Let's get to work - we'll need a function that takes a service and its interpreter, the operation name, and some representation of its input. For that input, we'll use smithy4s's ",(0,i.kt)("inlineCode",{parentName:"p"},"Document")," type."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},"import smithy4s.Document\nimport smithy4s.Endpoint\nimport smithy4s.Service\nimport smithy4s.kinds.FunctorAlgebra\nimport smithy4s.kinds.FunctorInterpreter\nimport cats.effect.IO\n\ndef run[Alg[_[_, _, _, _, _]]](\n service: Service[Alg],\n operationName: String,\n input: Document,\n alg: FunctorAlgebra[Alg, IO]\n): IO[Document] = {\n val endpoint = service.endpoints.find(_.id.name == operationName).get\n\n runEndpoint(endpoint, input, service.toPolyFunction(alg))\n}\n\ndef runEndpoint[Op[_, _, _, _, _], I, O](\n endpoint: Endpoint[Op, I, _, O, _, _],\n input: Document,\n interp: FunctorInterpreter[Op, IO],\n): IO[Document] = {\n // Deriving these codecs is a costly operation, so we don't recommend doing it for every call.\n // We do it here for simplicity.\n val inputDecoder = Document.Decoder.fromSchema(endpoint.input)\n val outputEncoder = Document.Encoder.fromSchema(endpoint.output)\n\n val decoded: I = inputDecoder.decode(input).toTry.get\n\n val result: IO[O] = interp(endpoint.wrap(decoded))\n\n result.map(outputEncoder.encode(_))\n}\n")),(0,i.kt)("p",null,"That code is a little heavy and abstract, but there's really no way to avoid abstraction - after all, we need to be prepared for any and all models that our users might give us, so we need to be very abstract!"),(0,i.kt)("p",null,"To explain a little bit:"),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"FunctorAlgebra[Alg, IO]")," is ",(0,i.kt)("inlineCode",{parentName:"p"},"Alg[IO]")," (for a specific shape of ",(0,i.kt)("inlineCode",{parentName:"p"},"Alg"),"). This could be ",(0,i.kt)("inlineCode",{parentName:"p"},"HelloWorldService[IO]"),", if we knew the types (which we don't, because we're in the dynamic, runtime world).\nRelated to that, ",(0,i.kt)("inlineCode",{parentName:"p"},"FunctorInterpreter[Op, IO]")," is a different way to view an ",(0,i.kt)("inlineCode",{parentName:"p"},"Alg[IO]"),", which is as a higher-kinded function. See ",(0,i.kt)("a",{parentName:"p",href:"/smithy4s/docs/design/services#codifying-the-duality-between-initial-and-final-algebras"},"this document")," for more explanation."),(0,i.kt)("p",null,"The steps we're taking are:"),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Find the endpoint within the service, using its operation name"),(0,i.kt)("li",{parentName:"ol"},"In ",(0,i.kt)("inlineCode",{parentName:"li"},"runEndpoint"),", decode the input ",(0,i.kt)("inlineCode",{parentName:"li"},"Document")," to the type the endpoint expects"),(0,i.kt)("li",{parentName:"ol"},"Run the interpreter using the decoded input"),(0,i.kt)("li",{parentName:"ol"},"Encode the output to a ",(0,i.kt)("inlineCode",{parentName:"li"},"Document"),".")),(0,i.kt)("p",null,"Let's see this in action with our actual service! But first, just for this guide, we'll define the routes for a fake instance of the server we're going to call:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},'import org.http4s.HttpApp\nimport org.http4s.MediaType\nimport org.http4s.headers.`Content-Type`\nimport org.http4s.dsl.io._\n\nval routes = HttpApp[IO] { case GET -> Root / "weather" / city =>\n Ok(s"""{"weather": "sunny in $city"}""").map(\n _.withContentType(`Content-Type`(MediaType.application.json))\n )\n}\n// routes: HttpApp[IO] = Kleisli(\n// run = org.http4s.Http$$$Lambda$26385/0x0000000804ed0a78@39c45489\n// )\n')),(0,i.kt)("p",null,"Now we'll build a client based on the service we loaded earlier, using that route as a fake server:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},'import org.http4s.client.Client\nimport smithy4s.http4s.SimpleRestJsonBuilder\n\n// first, we need some Service instance - we get one from the DynamicSchemaIndex we made earlier\nval service = dsi.getService(ShapeId("weather", "WeatherService")).get\n\nval client =\n SimpleRestJsonBuilder(service.service)\n .client(Client.fromHttpApp(routes))\n .make\n .toTry\n .get\n')),(0,i.kt)("p",null,"And finally, what we've been working towards all this time - we'll select the ",(0,i.kt)("inlineCode",{parentName:"p"},"GetWeather")," operation, pass a ",(0,i.kt)("inlineCode",{parentName:"p"},"Document")," representing our input, and the client we've just built."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},'import cats.effect.unsafe.implicits._\n\nrun(\n service = service.service,\n operationName = "GetWeather",\n input = Document.obj("city" -> Document.fromString("London")),\n alg = client,\n).unsafeRunSync().show\n// res6: String = "{weather=\\"sunny in London\\"}"\n')),(0,i.kt)("p",null,"Enjoy the view! As an added bonus, because we happen to have this service at build-time, we can use the same method with a static, compile-time service:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},'import weather._\n\nval clientStatic =\n SimpleRestJsonBuilder(WeatherService)\n .client(Client.fromHttpApp(routes))\n .make\n .toTry\n .get\n// clientStatic: WeatherServiceGen[[I, E, O, SI, SO]IO[O]] = weather.WeatherServiceOperation$Transformed@7b62505d\n\nrun(\n service = WeatherService,\n operationName = "GetWeather",\n input = Document.obj("city" -> Document.fromString("London")),\n alg = clientStatic,\n).unsafeRunSync().show\n// res7: String = "{weather=\\"sunny in London\\"}"\n')),(0,i.kt)("p",null,"Again, this is equivalent to the following call in the static approach:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},'clientStatic.getWeather(city = "London").unsafeRunSync()\n// res8: GetWeatherOutput = GetWeatherOutput(weather = "sunny in London")\n')),(0,i.kt)("div",{className:"footnotes"},(0,i.kt)("hr",{parentName:"div"}),(0,i.kt)("ol",{parentName:"div"},(0,i.kt)("li",{parentName:"ol",id:"fn-1"},"That is, assuming they're written correctly to make no assumptions about the usecase.",(0,i.kt)("a",{parentName:"li",href:"#fnref-1",className:"footnote-backref"},"\u21a9")))))}d.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunksmithy4s=self.webpackChunksmithy4s||[]).push([[2419],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>u});var a=n(7294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var l=a.createContext({}),p=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},c=function(e){var t=p(e.components);return a.createElement(l.Provider,{value:t},e.children)},m="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var n=e.components,i=e.mdxType,r=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),m=p(n),h=i,u=m["".concat(l,".").concat(h)]||m[h]||d[h]||r;return n?a.createElement(u,o(o({ref:t},c),{},{components:n})):a.createElement(u,o({ref:t},c))}));function u(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var r=n.length,o=new Array(r);o[0]=h;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[m]="string"==typeof e?e:i,o[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>d,frontMatter:()=>r,metadata:()=>s,toc:()=>p});var a=n(7462),i=(n(7294),n(3905));const r={sidebar_label:"Dynamic module",title:"Dynamic module"},o=void 0,s={unversionedId:"guides/dynamic",id:"guides/dynamic",title:"Dynamic module",description:"Introduction",source:"@site/../docs/target/jvm-2.13/mdoc/06-guides/dynamic.md",sourceDirName:"06-guides",slug:"/guides/dynamic",permalink:"/smithy4s/docs/guides/dynamic",draft:!1,editUrl:"https://github.com/disneystreaming/smithy4s/edit/main/modules/docs/src/06-guides/dynamic.md",tags:[],version:"current",frontMatter:{sidebar_label:"Dynamic module",title:"Dynamic module"},sidebar:"tutorialSidebar",previous:{title:"Services and endpoints",permalink:"/smithy4s/docs/design/services"},next:{title:"Endpoint Specific Middleware",permalink:"/smithy4s/docs/guides/endpoint-middleware"}},l={},p=[{value:"Introduction",id:"introduction",level:2},{value:"(Why) do we need codegen?",id:"why-do-we-need-codegen",level:2},{value:"The Dynamic way",id:"the-dynamic-way",level:2},{value:"Loading a dynamic model",id:"loading-a-dynamic-model",level:2},{value:"Using the DSI",id:"using-the-dsi",level:2},{value:"Case study: dynamic HTTP client",id:"case-study-dynamic-http-client",level:2}],c={toc:p},m="wrapper";function d(e){let{components:t,...n}=e;return(0,i.kt)(m,(0,a.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h2",{id:"introduction"},"Introduction"),(0,i.kt)("p",null,"It is highly recommended to learn about ",(0,i.kt)("a",{parentName:"p",href:"/smithy4s/docs/design/design"},"the library's design")," before going into this section."),(0,i.kt)("p",null,"Smithy4s is first and foremost a code generation tool for the Smithy language in Scala. Although it does provide interpreters for the Smithy services, which can be used to derive e.g. HTTP clients and servers, the codegen way can only get you so far - there are some situations when it's ",(0,i.kt)("strong",{parentName:"p"},"not sufficient for the job"),"."),(0,i.kt)("p",null,"Code generation works well if your Smithy model changes ",(0,i.kt)("strong",{parentName:"p"},"no more often")," than your service's implementation - as long as you run your build whenever you make a code change, codegen will also be triggered,\nand the Scala compiler will ensure you're in sync with the Smithy model in its present state. But what if your Smithy model changes are ",(0,i.kt)("strong",{parentName:"p"},"more frequent")," than the service? Or what if you simply don't have access to all the Smithy models your code might have to work with?"),(0,i.kt)("p",null,"These cases, and possibly others, are why Smithy4s has the ",(0,i.kt)("inlineCode",{parentName:"p"},"dynamic")," module."),(0,i.kt)("h2",{id:"why-do-we-need-codegen"},"(Why) do we need codegen?"),(0,i.kt)("p",null,"As you know by now, Smithy4s's codegen is static - it requires the model to be available at build-time, so that code can be generated and made available to you at compile-time."),(0,i.kt)("p",null,"In short, what happens at ",(0,i.kt)("strong",{parentName:"p"},"build-time")," are the following steps:"),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("strong",{parentName:"li"},"Read")," the Smithy files available to your build"),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("strong",{parentName:"li"},"Build")," a ",(0,i.kt)("a",{parentName:"li",href:"https://smithy.io/2.0/spec/model.html"},"semantic Smithy model"),", which is roughly a graph of shapes that refer to each other"),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("strong",{parentName:"li"},"Generate")," files for each relevant shape in the model (e.g. a service, a structure, an enum...), including metadata (",(0,i.kt)("a",{parentName:"li",href:"/smithy4s/docs/design/services"},"services")," and ",(0,i.kt)("a",{parentName:"li",href:"/smithy4s/docs/design/schemas"},"schemas"),").")),(0,i.kt)("p",null,"Then, there's the ",(0,i.kt)("strong",{parentName:"p"},"runtime")," part. Let's say you're building an HTTP client - in that case, what you see as a Smithy4s user is:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},"SimpleRestJson(WeatherService)\n .client(??? : org.http4s.client.Client[IO])\n .make\n")),(0,i.kt)("p",null,"or more generically:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"interpretToRestClient(WeatherService)\n")),(0,i.kt)("p",null,"The steps that the HTTP client interpreter performs to build a high-level client are:"),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("strong",{parentName:"li"},"Capture")," a ",(0,i.kt)("a",{parentName:"li",href:"/smithy4s/docs/design/services"},"Smithy4s service")," representing the service you wrote in Smithy. This was generated by Smithy4s's codegen."),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("strong",{parentName:"li"},"Analyze")," the service's endpoints, their input/output schemas, the Hints on these schemas..."),(0,i.kt)("li",{parentName:"ol"},(0,i.kt)("strong",{parentName:"li"},"Transform")," the service description into a high-level proxy to the underlying client implementation.")),(0,i.kt)("p",null,"Turns out that interpreters like this ",(0,i.kt)("strong",{parentName:"p"},"aren't ",(0,i.kt)("em",{parentName:"strong"},"actually")," aware")," of the fact that there's code generation involved. As long as you can provide a data structure describing your service, its endpoints and their schemas (which is indeed the ",(0,i.kt)("inlineCode",{parentName:"p"},"Service")," type),\nyou can use any interpreter that requires one: code generation is just ",(0,i.kt)("strong",{parentName:"p"},"a means to derive")," such a data structure automatically from your Smithy model."),(0,i.kt)("p",null,"This all is why ",(0,i.kt)("strong",{parentName:"p"},"you don't ",(0,i.kt)("em",{parentName:"strong"},"need")," code generation")," to benefit from the interpreters - you just need a way to instantiate a Smithy4s Service (or Schema, if that's what your interpreter operates on)."),(0,i.kt)("p",null,"The Dynamic module of smithy4s was made exactly for that purpose."),(0,i.kt)("h2",{id:"the-dynamic-way"},"The Dynamic way"),(0,i.kt)("p",null,"In the previous section, we looked at the steps performed at build time to generate code:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Read Smithy files"),(0,i.kt)("li",{parentName:"ul"},"Build a Smithy model"),(0,i.kt)("li",{parentName:"ul"},"Generate Scala files with Smithy4s schemas.")),(0,i.kt)("p",null,"Don't be fooled - although we had Smithy files as the input and Scala files as the output, the really important part was getting from the Smithy model to the ",(0,i.kt)("strong",{parentName:"p"},"Service and Schema instances")," representing it.\nThe Dynamic module of smithy4s provides a way to ",(0,i.kt)("strong",{parentName:"p"},"do this at runtime"),"."),(0,i.kt)("p",null,"And the runtime part, where the interpreter runs? ",(0,i.kt)("strong",{parentName:"p"},"It's the same as before!")," The Service and Schema interfaces are identical regardless of the static/dynamic usecase, and so are the interpreters",(0,i.kt)("sup",{parentName:"p",id:"fnref-1"},(0,i.kt)("a",{parentName:"sup",href:"#fn-1",className:"footnote-ref"},"1")),"."),(0,i.kt)("h2",{id:"loading-a-dynamic-model"},"Loading a dynamic model"),(0,i.kt)("p",null,"First of all, you need the dependency:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},'libraryDependencies ++= Seq(\n // version sourced from the plugin\n "com.disneystreaming.smithy4s" %% "smithy4s-dynamic" % smithy4sVersion.value\n)\n')),(0,i.kt)("p",null,"Now, you need a Smithy model. There are essentially three ways to get one:"),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Load a model using the ",(0,i.kt)("a",{parentName:"li",href:"https://github.com/awslabs/smithy"},"awslabs/smithy")," library's ",(0,i.kt)("inlineCode",{parentName:"li"},"ModelAssembler")),(0,i.kt)("li",{parentName:"ol"},"Load a serialized model from a JSON file (",(0,i.kt)("a",{parentName:"li",href:"https://github.com/disneystreaming/smithy4s/blob/4e678c5f89599f962dc18fb7dcdf3d5d6c0a402b/sampleSpecs/lambda.json"},"example"),"), or"),(0,i.kt)("li",{parentName:"ol"},"Deserialize or generate the ",(0,i.kt)("inlineCode",{parentName:"li"},"smithy4s.dynamic.model.Model")," data structure in any way you want, on your own.")),(0,i.kt)("p",null,"The ",(0,i.kt)("inlineCode",{parentName:"p"},"ModelAssembler")," way only works on the JVM, because Smithy's reference implementation is a Java library. We'll use that way for this guide:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},'import software.amazon.smithy.model.Model\n\nval s = """\n$version: "2"\n\nnamespace weather\n\nuse alloy#simpleRestJson\n\n@simpleRestJson\nservice WeatherService {\n operations: [GetWeather]\n}\n\n@http(method: "GET", uri: "/weather/{city}")\noperation GetWeather {\n input := {\n @httpLabel\n @required\n city: String\n }\n output := {\n @required\n weather: String\n }\n}\n\nstructure Dog {\n @required\n name: String\n}\n"""\n\nval model = Model\n .assembler()\n .addUnparsedModel(\n "weather.smithy",\n s,\n )\n .discoverModels()\n .assemble()\n .unwrap()\n')),(0,i.kt)("p",null,"The entrypoint to loading models is ",(0,i.kt)("inlineCode",{parentName:"p"},"DynamicSchemaIndex"),"."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},"import smithy4s.dynamic.DynamicSchemaIndex\nval dsi = DynamicSchemaIndex.loadModel(model)\n// dsi: DynamicSchemaIndex = smithy4s.dynamic.internals.DynamicSchemaIndexImpl@3a09571e\n")),(0,i.kt)("p",null,"For alternative ways to load a DSI, see ",(0,i.kt)("inlineCode",{parentName:"p"},"DynamicSchemaIndex.load"),"."),(0,i.kt)("h2",{id:"using-the-dsi"},"Using the DSI"),(0,i.kt)("p",null,"Having a ",(0,i.kt)("inlineCode",{parentName:"p"},"DynamicSchemaIndex"),", we can iterate over all the services available to it:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},'dsi.allServices.map(_.service.id)\n// res0: Iterable[smithy4s.ShapeId] = List(\n// ShapeId(namespace = "weather", name = "WeatherService")\n// )\n')),(0,i.kt)("p",null,"as well as the schemas:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},'dsi.allSchemas.map(_.shapeId).filter(_.namespace == "weather")\n// res1: Iterable[smithy4s.ShapeId] = List(\n// ShapeId(namespace = "weather", name = "GetWeatherInput"),\n// ShapeId(namespace = "weather", name = "GetWeatherOutput"),\n// ShapeId(namespace = "weather", name = "Dog")\n// )\n')),(0,i.kt)("p",null,"You can also access a service or schema by ID:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},'import smithy4s.ShapeId\n\ndsi.getService(ShapeId("weather", "WeatherService")).get.service.id\n// res2: ShapeId = ShapeId(namespace = "weather", name = "WeatherService")\ndsi.getSchema(ShapeId("weather", "Dog")).get.shapeId\n// res3: ShapeId = ShapeId(namespace = "weather", name = "Dog")\n')),(0,i.kt)("p",null,"Note that you don't know the exact type of a schema at compile-time:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},'import smithy4s.Schema\n\ndsi.getSchema(ShapeId("weather", "Dog")).get\n// res4: Schema[_] = StructSchema(\n// shapeId = ShapeId(namespace = "weather", name = "Dog"),\n// hints = Impl(memberHintsMap = Map(), targetHintsMap = Map()),\n// fields = Vector(\n// Field(\n// label = "name",\n// schema = PrimitiveSchema(\n// shapeId = ShapeId(namespace = "smithy.api", name = "String"),\n// hints = Impl(\n// memberHintsMap = Map(\n// ShapeId(namespace = "smithy.api", name = "required") -> DynamicBinding(\n// keyId = ShapeId(namespace = "smithy.api", name = "required"),\n// value = DObject(value = ListMap())\n// )\n// ),\n// targetHintsMap = Map()\n// ),\n// tag = PString\n// ),\n// get = Accessor(index = 0)\n// )\n// ),\n// make = \n// )\n')),(0,i.kt)("p",null,"It is very similar for services. This is simply due to the fact that at compile-time (which is where typechecking happens) we have no clue what the possible type of the schema could be.\nAfter all, the String representing the model doesn't have to be constant - it could be fetched from the network, and even vary throughout the lifetime of our application!"),(0,i.kt)("p",null,"This doesn't forbid us from using these dynamic goodies in interpreters, though."),(0,i.kt)("h2",{id:"case-study-dynamic-http-client"},"Case study: dynamic HTTP client"),(0,i.kt)("p",null,"Let's make a REST client for a dynamic service. We'll start by writing an interpreter."),(0,i.kt)("p",null,(0,i.kt)("em",{parentName:"p"},'"But wait, weren\'t we supposed to be able to use the existing interpreters?"')),(0,i.kt)("p",null,"That's true - the underlying implementation will use the interpreters made for the static world as well.\nHowever, due to the strangely-typed nature of the dynamic world, we have to deal with some complexity that's normally invisible to the user."),(0,i.kt)("p",null,"For example, you can write this in the static world:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},'import cats.effect.IO\nimport weather._\n\n// imagine this comes from an interpreter\nval client: WeatherService[IO] = ??? : WeatherService[IO]\n\nclient.getWeather(city = "hello")\n')),(0,i.kt)("p",null,"but you can't do it if your model gets loaded dynamically! You wouldn't be able to compile that code, because there's no way to tell what services you'll load at runtime."),(0,i.kt)("p",null,"This means that we'll need a different way to pass the following pieces to an interpreter at runtime:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"the service being used (",(0,i.kt)("inlineCode",{parentName:"li"},"HelloWorldService"),")"),(0,i.kt)("li",{parentName:"ul"},"the operation being called (",(0,i.kt)("inlineCode",{parentName:"li"},"Hello"),")"),(0,i.kt)("li",{parentName:"ul"},"the operation input (a single parameter: ",(0,i.kt)("inlineCode",{parentName:"li"},"name")," = ",(0,i.kt)("inlineCode",{parentName:"li"},'"Hello"'),")")),(0,i.kt)("p",null,"Let's get to work - we'll need a function that takes a service and its interpreter, the operation name, and some representation of its input. For that input, we'll use smithy4s's ",(0,i.kt)("inlineCode",{parentName:"p"},"Document")," type."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},"import smithy4s.Document\nimport smithy4s.Endpoint\nimport smithy4s.Service\nimport smithy4s.kinds.FunctorAlgebra\nimport smithy4s.kinds.FunctorInterpreter\nimport cats.effect.IO\n\ndef run[Alg[_[_, _, _, _, _]]](\n service: Service[Alg],\n operationName: String,\n input: Document,\n alg: FunctorAlgebra[Alg, IO]\n): IO[Document] = {\n val endpoint = service.endpoints.find(_.id.name == operationName).get\n\n runEndpoint(endpoint, input, service.toPolyFunction(alg))\n}\n\ndef runEndpoint[Op[_, _, _, _, _], I, O](\n endpoint: Endpoint[Op, I, _, O, _, _],\n input: Document,\n interp: FunctorInterpreter[Op, IO],\n): IO[Document] = {\n // Deriving these codecs is a costly operation, so we don't recommend doing it for every call.\n // We do it here for simplicity.\n val inputDecoder = Document.Decoder.fromSchema(endpoint.input)\n val outputEncoder = Document.Encoder.fromSchema(endpoint.output)\n\n val decoded: I = inputDecoder.decode(input).toTry.get\n\n val result: IO[O] = interp(endpoint.wrap(decoded))\n\n result.map(outputEncoder.encode(_))\n}\n")),(0,i.kt)("p",null,"That code is a little heavy and abstract, but there's really no way to avoid abstraction - after all, we need to be prepared for any and all models that our users might give us, so we need to be very abstract!"),(0,i.kt)("p",null,"To explain a little bit:"),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"FunctorAlgebra[Alg, IO]")," is ",(0,i.kt)("inlineCode",{parentName:"p"},"Alg[IO]")," (for a specific shape of ",(0,i.kt)("inlineCode",{parentName:"p"},"Alg"),"). This could be ",(0,i.kt)("inlineCode",{parentName:"p"},"HelloWorldService[IO]"),", if we knew the types (which we don't, because we're in the dynamic, runtime world).\nRelated to that, ",(0,i.kt)("inlineCode",{parentName:"p"},"FunctorInterpreter[Op, IO]")," is a different way to view an ",(0,i.kt)("inlineCode",{parentName:"p"},"Alg[IO]"),", which is as a higher-kinded function. See ",(0,i.kt)("a",{parentName:"p",href:"/smithy4s/docs/design/services#codifying-the-duality-between-initial-and-final-algebras"},"this document")," for more explanation."),(0,i.kt)("p",null,"The steps we're taking are:"),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Find the endpoint within the service, using its operation name"),(0,i.kt)("li",{parentName:"ol"},"In ",(0,i.kt)("inlineCode",{parentName:"li"},"runEndpoint"),", decode the input ",(0,i.kt)("inlineCode",{parentName:"li"},"Document")," to the type the endpoint expects"),(0,i.kt)("li",{parentName:"ol"},"Run the interpreter using the decoded input"),(0,i.kt)("li",{parentName:"ol"},"Encode the output to a ",(0,i.kt)("inlineCode",{parentName:"li"},"Document"),".")),(0,i.kt)("p",null,"Let's see this in action with our actual service! But first, just for this guide, we'll define the routes for a fake instance of the server we're going to call:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},'import org.http4s.HttpApp\nimport org.http4s.MediaType\nimport org.http4s.headers.`Content-Type`\nimport org.http4s.dsl.io._\n\nval routes = HttpApp[IO] { case GET -> Root / "weather" / city =>\n Ok(s"""{"weather": "sunny in $city"}""").map(\n _.withContentType(`Content-Type`(MediaType.application.json))\n )\n}\n// routes: HttpApp[IO] = Kleisli(\n// run = org.http4s.Http$$$Lambda$26422/0x0000000804278880@3338f03e\n// )\n')),(0,i.kt)("p",null,"Now we'll build a client based on the service we loaded earlier, using that route as a fake server:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},'import org.http4s.client.Client\nimport smithy4s.http4s.SimpleRestJsonBuilder\n\n// first, we need some Service instance - we get one from the DynamicSchemaIndex we made earlier\nval service = dsi.getService(ShapeId("weather", "WeatherService")).get\n\nval client =\n SimpleRestJsonBuilder(service.service)\n .client(Client.fromHttpApp(routes))\n .make\n .toTry\n .get\n')),(0,i.kt)("p",null,"And finally, what we've been working towards all this time - we'll select the ",(0,i.kt)("inlineCode",{parentName:"p"},"GetWeather")," operation, pass a ",(0,i.kt)("inlineCode",{parentName:"p"},"Document")," representing our input, and the client we've just built."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},'import cats.effect.unsafe.implicits._\n\nrun(\n service = service.service,\n operationName = "GetWeather",\n input = Document.obj("city" -> Document.fromString("London")),\n alg = client,\n).unsafeRunSync().show\n// res6: String = "{weather=\\"sunny in London\\"}"\n')),(0,i.kt)("p",null,"Enjoy the view! As an added bonus, because we happen to have this service at build-time, we can use the same method with a static, compile-time service:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},'import weather._\n\nval clientStatic =\n SimpleRestJsonBuilder(WeatherService)\n .client(Client.fromHttpApp(routes))\n .make\n .toTry\n .get\n// clientStatic: WeatherServiceGen[[I, E, O, SI, SO]IO[O]] = weather.WeatherServiceOperation$Transformed@5c103304\n\nrun(\n service = WeatherService,\n operationName = "GetWeather",\n input = Document.obj("city" -> Document.fromString("London")),\n alg = clientStatic,\n).unsafeRunSync().show\n// res7: String = "{weather=\\"sunny in London\\"}"\n')),(0,i.kt)("p",null,"Again, this is equivalent to the following call in the static approach:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-scala"},'clientStatic.getWeather(city = "London").unsafeRunSync()\n// res8: GetWeatherOutput = GetWeatherOutput(weather = "sunny in London")\n')),(0,i.kt)("div",{className:"footnotes"},(0,i.kt)("hr",{parentName:"div"}),(0,i.kt)("ol",{parentName:"div"},(0,i.kt)("li",{parentName:"ol",id:"fn-1"},"That is, assuming they're written correctly to make no assumptions about the usecase.",(0,i.kt)("a",{parentName:"li",href:"#fnref-1",className:"footnote-backref"},"\u21a9")))))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/main.8fb46f83.js b/assets/js/main.58f4f8bc.js similarity index 99% rename from assets/js/main.8fb46f83.js rename to assets/js/main.58f4f8bc.js index 06755bf75..3e20df4aa 100644 --- a/assets/js/main.8fb46f83.js +++ b/assets/js/main.58f4f8bc.js @@ -1,2 +1,2 @@ -/*! For license information please see main.8fb46f83.js.LICENSE.txt */ -(self.webpackChunksmithy4s=self.webpackChunksmithy4s||[]).push([[179],{4334:(e,t,n)=>{"use strict";function r(e){var t,n,a="";if("string"==typeof e||"number"==typeof e)a+=e;else if("object"==typeof e)if(Array.isArray(e))for(t=0;ta});const a=function(){for(var e,t,n=0,a="";n{"use strict";n.d(t,{Z:()=>o});var r=function(){var e=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,t=0,n={},r={util:{encode:function e(t){return t instanceof a?new a(t.type,e(t.content),t.alias):Array.isArray(t)?t.map(e):t.replace(/&/g,"&").replace(/=d.reach);S+=k.value.length,k=k.next){var x=k.value;if(t.length>e.length)return;if(!(x instanceof a)){var _,C=1;if(b){if(!(_=o(E,S,e,v))||_.index>=e.length)break;var T=_.index,N=_.index+_[0].length,A=S;for(A+=k.value.length;T>=A;)A+=(k=k.next).value.length;if(S=A-=k.value.length,k.value instanceof a)continue;for(var O=k;O!==t.tail&&(Ad.reach&&(d.reach=R);var M=k.prev;if(I&&(M=l(t,M,I),S+=I.length),c(t,M,C),k=l(t,M,new a(f,g?r.tokenize(L,g):L,y,L)),P&&l(t,k,P),C>1){var D={cause:f+","+m,reach:R};i(e,t,n,k.prev,S,D),d&&D.reach>d.reach&&(d.reach=D.reach)}}}}}}function s(){var e={value:null,prev:null,next:null},t={value:null,prev:e,next:null};e.next=t,this.head=e,this.tail=t,this.length=0}function l(e,t,n){var r=t.next,a={value:n,prev:t,next:r};return t.next=a,r.prev=a,e.length++,a}function c(e,t,n){for(var r=t.next,a=0;a"+o.content+""},r}(),a=r;r.default=r,a.languages.markup={comment:{pattern://,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^$|[[\]]/,"doctype-tag":/^DOCTYPE/i,name:/[^\s<>'"]+/}},cdata:{pattern://i,greedy:!0},tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},a.languages.markup.tag.inside["attr-value"].inside.entity=a.languages.markup.entity,a.languages.markup.doctype.inside["internal-subset"].inside=a.languages.markup,a.hooks.add("wrap",(function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&/,"&"))})),Object.defineProperty(a.languages.markup.tag,"addInlined",{value:function(e,t){var n={};n["language-"+t]={pattern:/(^$)/i,lookbehind:!0,inside:a.languages[t]},n.cdata=/^$/i;var r={"included-cdata":{pattern://i,inside:n}};r["language-"+t]={pattern:/[\s\S]+/,inside:a.languages[t]};var o={};o[e]={pattern:RegExp(/(<__[^>]*>)(?:))*\]\]>|(?!)/.source.replace(/__/g,(function(){return e})),"i"),lookbehind:!0,greedy:!0,inside:r},a.languages.insertBefore("markup","cdata",o)}}),Object.defineProperty(a.languages.markup.tag,"addAttribute",{value:function(e,t){a.languages.markup.tag.inside["special-attr"].push({pattern:RegExp(/(^|["'\s])/.source+"(?:"+e+")"+/\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,"i"),lookbehind:!0,inside:{"attr-name":/^[^\s=]+/,"attr-value":{pattern:/=[\s\S]+/,inside:{value:{pattern:/(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,lookbehind:!0,alias:[t,"language-"+t],inside:a.languages[t]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),a.languages.html=a.languages.markup,a.languages.mathml=a.languages.markup,a.languages.svg=a.languages.markup,a.languages.xml=a.languages.extend("markup",{}),a.languages.ssml=a.languages.xml,a.languages.atom=a.languages.xml,a.languages.rss=a.languages.xml,function(e){var t="\\b(?:BASH|BASHOPTS|BASH_ALIASES|BASH_ARGC|BASH_ARGV|BASH_CMDS|BASH_COMPLETION_COMPAT_DIR|BASH_LINENO|BASH_REMATCH|BASH_SOURCE|BASH_VERSINFO|BASH_VERSION|COLORTERM|COLUMNS|COMP_WORDBREAKS|DBUS_SESSION_BUS_ADDRESS|DEFAULTS_PATH|DESKTOP_SESSION|DIRSTACK|DISPLAY|EUID|GDMSESSION|GDM_LANG|GNOME_KEYRING_CONTROL|GNOME_KEYRING_PID|GPG_AGENT_INFO|GROUPS|HISTCONTROL|HISTFILE|HISTFILESIZE|HISTSIZE|HOME|HOSTNAME|HOSTTYPE|IFS|INSTANCE|JOB|LANG|LANGUAGE|LC_ADDRESS|LC_ALL|LC_IDENTIFICATION|LC_MEASUREMENT|LC_MONETARY|LC_NAME|LC_NUMERIC|LC_PAPER|LC_TELEPHONE|LC_TIME|LESSCLOSE|LESSOPEN|LINES|LOGNAME|LS_COLORS|MACHTYPE|MAILCHECK|MANDATORY_PATH|NO_AT_BRIDGE|OLDPWD|OPTERR|OPTIND|ORBIT_SOCKETDIR|OSTYPE|PAPERSIZE|PATH|PIPESTATUS|PPID|PS1|PS2|PS3|PS4|PWD|RANDOM|REPLY|SECONDS|SELINUX_INIT|SESSION|SESSIONTYPE|SESSION_MANAGER|SHELL|SHELLOPTS|SHLVL|SSH_AUTH_SOCK|TERM|UID|UPSTART_EVENTS|UPSTART_INSTANCE|UPSTART_JOB|UPSTART_SESSION|USER|WINDOWID|XAUTHORITY|XDG_CONFIG_DIRS|XDG_CURRENT_DESKTOP|XDG_DATA_DIRS|XDG_GREETER_DATA_DIR|XDG_MENU_PREFIX|XDG_RUNTIME_DIR|XDG_SEAT|XDG_SEAT_PATH|XDG_SESSION_DESKTOP|XDG_SESSION_ID|XDG_SESSION_PATH|XDG_SESSION_TYPE|XDG_VTNR|XMODIFIERS)\\b",n={pattern:/(^(["']?)\w+\2)[ \t]+\S.*/,lookbehind:!0,alias:"punctuation",inside:null},r={bash:n,environment:{pattern:RegExp("\\$"+t),alias:"constant"},variable:[{pattern:/\$?\(\([\s\S]+?\)\)/,greedy:!0,inside:{variable:[{pattern:/(^\$\(\([\s\S]+)\)\)/,lookbehind:!0},/^\$\(\(/],number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[Ee]-?\d+)?/,operator:/--|\+\+|\*\*=?|<<=?|>>=?|&&|\|\||[=!+\-*/%<>^&|]=?|[?~:]/,punctuation:/\(\(?|\)\)?|,|;/}},{pattern:/\$\((?:\([^)]+\)|[^()])+\)|`[^`]+`/,greedy:!0,inside:{variable:/^\$\(|^`|\)$|`$/}},{pattern:/\$\{[^}]+\}/,greedy:!0,inside:{operator:/:[-=?+]?|[!\/]|##?|%%?|\^\^?|,,?/,punctuation:/[\[\]]/,environment:{pattern:RegExp("(\\{)"+t),lookbehind:!0,alias:"constant"}}},/\$(?:\w+|[#?*!@$])/],entity:/\\(?:[abceEfnrtv\\"]|O?[0-7]{1,3}|U[0-9a-fA-F]{8}|u[0-9a-fA-F]{4}|x[0-9a-fA-F]{1,2})/};e.languages.bash={shebang:{pattern:/^#!\s*\/.*/,alias:"important"},comment:{pattern:/(^|[^"{\\$])#.*/,lookbehind:!0},"function-name":[{pattern:/(\bfunction\s+)[\w-]+(?=(?:\s*\(?:\s*\))?\s*\{)/,lookbehind:!0,alias:"function"},{pattern:/\b[\w-]+(?=\s*\(\s*\)\s*\{)/,alias:"function"}],"for-or-select":{pattern:/(\b(?:for|select)\s+)\w+(?=\s+in\s)/,alias:"variable",lookbehind:!0},"assign-left":{pattern:/(^|[\s;|&]|[<>]\()\w+(?=\+?=)/,inside:{environment:{pattern:RegExp("(^|[\\s;|&]|[<>]\\()"+t),lookbehind:!0,alias:"constant"}},alias:"variable",lookbehind:!0},string:[{pattern:/((?:^|[^<])<<-?\s*)(\w+)\s[\s\S]*?(?:\r?\n|\r)\2/,lookbehind:!0,greedy:!0,inside:r},{pattern:/((?:^|[^<])<<-?\s*)(["'])(\w+)\2\s[\s\S]*?(?:\r?\n|\r)\3/,lookbehind:!0,greedy:!0,inside:{bash:n}},{pattern:/(^|[^\\](?:\\\\)*)"(?:\\[\s\S]|\$\([^)]+\)|\$(?!\()|`[^`]+`|[^"\\`$])*"/,lookbehind:!0,greedy:!0,inside:r},{pattern:/(^|[^$\\])'[^']*'/,lookbehind:!0,greedy:!0},{pattern:/\$'(?:[^'\\]|\\[\s\S])*'/,greedy:!0,inside:{entity:r.entity}}],environment:{pattern:RegExp("\\$?"+t),alias:"constant"},variable:r.variable,function:{pattern:/(^|[\s;|&]|[<>]\()(?:add|apropos|apt|apt-cache|apt-get|aptitude|aspell|automysqlbackup|awk|basename|bash|bc|bconsole|bg|bzip2|cal|cat|cfdisk|chgrp|chkconfig|chmod|chown|chroot|cksum|clear|cmp|column|comm|composer|cp|cron|crontab|csplit|curl|cut|date|dc|dd|ddrescue|debootstrap|df|diff|diff3|dig|dir|dircolors|dirname|dirs|dmesg|docker|docker-compose|du|egrep|eject|env|ethtool|expand|expect|expr|fdformat|fdisk|fg|fgrep|file|find|fmt|fold|format|free|fsck|ftp|fuser|gawk|git|gparted|grep|groupadd|groupdel|groupmod|groups|grub-mkconfig|gzip|halt|head|hg|history|host|hostname|htop|iconv|id|ifconfig|ifdown|ifup|import|install|ip|jobs|join|kill|killall|less|link|ln|locate|logname|logrotate|look|lpc|lpr|lprint|lprintd|lprintq|lprm|ls|lsof|lynx|make|man|mc|mdadm|mkconfig|mkdir|mke2fs|mkfifo|mkfs|mkisofs|mknod|mkswap|mmv|more|most|mount|mtools|mtr|mutt|mv|nano|nc|netstat|nice|nl|node|nohup|notify-send|npm|nslookup|op|open|parted|passwd|paste|pathchk|ping|pkill|pnpm|podman|podman-compose|popd|pr|printcap|printenv|ps|pushd|pv|quota|quotacheck|quotactl|ram|rar|rcp|reboot|remsync|rename|renice|rev|rm|rmdir|rpm|rsync|scp|screen|sdiff|sed|sendmail|seq|service|sftp|sh|shellcheck|shuf|shutdown|sleep|slocate|sort|split|ssh|stat|strace|su|sudo|sum|suspend|swapon|sync|tac|tail|tar|tee|time|timeout|top|touch|tr|traceroute|tsort|tty|umount|uname|unexpand|uniq|units|unrar|unshar|unzip|update-grub|uptime|useradd|userdel|usermod|users|uudecode|uuencode|v|vcpkg|vdir|vi|vim|virsh|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yarn|yes|zenity|zip|zsh|zypper)(?=$|[)\s;|&])/,lookbehind:!0},keyword:{pattern:/(^|[\s;|&]|[<>]\()(?:case|do|done|elif|else|esac|fi|for|function|if|in|select|then|until|while)(?=$|[)\s;|&])/,lookbehind:!0},builtin:{pattern:/(^|[\s;|&]|[<>]\()(?:\.|:|alias|bind|break|builtin|caller|cd|command|continue|declare|echo|enable|eval|exec|exit|export|getopts|hash|help|let|local|logout|mapfile|printf|pwd|read|readarray|readonly|return|set|shift|shopt|source|test|times|trap|type|typeset|ulimit|umask|unalias|unset)(?=$|[)\s;|&])/,lookbehind:!0,alias:"class-name"},boolean:{pattern:/(^|[\s;|&]|[<>]\()(?:false|true)(?=$|[)\s;|&])/,lookbehind:!0},"file-descriptor":{pattern:/\B&\d\b/,alias:"important"},operator:{pattern:/\d?<>|>\||\+=|=[=~]?|!=?|<<[<-]?|[&\d]?>>|\d[<>]&?|[<>][&=]?|&[>&]?|\|[&|]?/,inside:{"file-descriptor":{pattern:/^\d/,alias:"important"}}},punctuation:/\$?\(\(?|\)\)?|\.\.|[{}[\];\\]/,number:{pattern:/(^|\s)(?:[1-9]\d*|0)(?:[.,]\d+)?\b/,lookbehind:!0}},n.inside=e.languages.bash;for(var a=["comment","function-name","for-or-select","assign-left","string","environment","function","keyword","builtin","boolean","file-descriptor","operator","punctuation","number"],o=r.variable[1].inside,i=0;i]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/},a.languages.c=a.languages.extend("clike",{comment:{pattern:/\/\/(?:[^\r\n\\]|\\(?:\r\n?|\n|(?![\r\n])))*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},"class-name":{pattern:/(\b(?:enum|struct)\s+(?:__attribute__\s*\(\([\s\S]*?\)\)\s*)?)\w+|\b[a-z]\w*_t\b/,lookbehind:!0},keyword:/\b(?:_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local|__attribute__|asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|inline|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|typeof|union|unsigned|void|volatile|while)\b/,function:/\b[a-z_]\w*(?=\s*\()/i,number:/(?:\b0x(?:[\da-f]+(?:\.[\da-f]*)?|\.[\da-f]+)(?:p[+-]?\d+)?|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?)[ful]{0,4}/i,operator:/>>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*/%&|^!=<>]=?/}),a.languages.insertBefore("c","string",{char:{pattern:/'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n]){0,32}'/,greedy:!0}}),a.languages.insertBefore("c","string",{macro:{pattern:/(^[\t ]*)#\s*[a-z](?:[^\r\n\\/]|\/(?!\*)|\/\*(?:[^*]|\*(?!\/))*\*\/|\\(?:\r\n|[\s\S]))*/im,lookbehind:!0,greedy:!0,alias:"property",inside:{string:[{pattern:/^(#\s*include\s*)<[^>]+>/,lookbehind:!0},a.languages.c.string],char:a.languages.c.char,comment:a.languages.c.comment,"macro-name":[{pattern:/(^#\s*define\s+)\w+\b(?!\()/i,lookbehind:!0},{pattern:/(^#\s*define\s+)\w+\b(?=\()/i,lookbehind:!0,alias:"function"}],directive:{pattern:/^(#\s*)[a-z]+/,lookbehind:!0,alias:"keyword"},"directive-hash":/^#/,punctuation:/##|\\(?=[\r\n])/,expression:{pattern:/\S[\s\S]*/,inside:a.languages.c}}}}),a.languages.insertBefore("c","function",{constant:/\b(?:EOF|NULL|SEEK_CUR|SEEK_END|SEEK_SET|__DATE__|__FILE__|__LINE__|__TIMESTAMP__|__TIME__|__func__|stderr|stdin|stdout)\b/}),delete a.languages.c.boolean,function(e){var t=/\b(?:alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|char8_t|class|co_await|co_return|co_yield|compl|concept|const|const_cast|consteval|constexpr|constinit|continue|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|final|float|for|friend|goto|if|import|inline|int|int16_t|int32_t|int64_t|int8_t|long|module|mutable|namespace|new|noexcept|nullptr|operator|override|private|protected|public|register|reinterpret_cast|requires|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|uint16_t|uint32_t|uint64_t|uint8_t|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/,n=/\b(?!)\w+(?:\s*\.\s*\w+)*\b/.source.replace(//g,(function(){return t.source}));e.languages.cpp=e.languages.extend("c",{"class-name":[{pattern:RegExp(/(\b(?:class|concept|enum|struct|typename)\s+)(?!)\w+/.source.replace(//g,(function(){return t.source}))),lookbehind:!0},/\b[A-Z]\w*(?=\s*::\s*\w+\s*\()/,/\b[A-Z_]\w*(?=\s*::\s*~\w+\s*\()/i,/\b\w+(?=\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>\s*::\s*\w+\s*\()/],keyword:t,number:{pattern:/(?:\b0b[01']+|\b0x(?:[\da-f']+(?:\.[\da-f']*)?|\.[\da-f']+)(?:p[+-]?[\d']+)?|(?:\b[\d']+(?:\.[\d']*)?|\B\.[\d']+)(?:e[+-]?[\d']+)?)[ful]{0,4}/i,greedy:!0},operator:/>>=?|<<=?|->|--|\+\+|&&|\|\||[?:~]|<=>|[-+*/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/,boolean:/\b(?:false|true)\b/}),e.languages.insertBefore("cpp","string",{module:{pattern:RegExp(/(\b(?:import|module)\s+)/.source+"(?:"+/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|<[^<>\r\n]*>/.source+"|"+/(?:\s*:\s*)?|:\s*/.source.replace(//g,(function(){return n}))+")"),lookbehind:!0,greedy:!0,inside:{string:/^[<"][\s\S]+/,operator:/:/,punctuation:/\./}},"raw-string":{pattern:/R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/,alias:"string",greedy:!0}}),e.languages.insertBefore("cpp","keyword",{"generic-function":{pattern:/\b(?!operator\b)[a-z_]\w*\s*<(?:[^<>]|<[^<>]*>)*>(?=\s*\()/i,inside:{function:/^\w+/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:e.languages.cpp}}}}),e.languages.insertBefore("cpp","operator",{"double-colon":{pattern:/::/,alias:"punctuation"}}),e.languages.insertBefore("cpp","class-name",{"base-clause":{pattern:/(\b(?:class|struct)\s+\w+\s*:\s*)[^;{}"'\s]+(?:\s+[^;{}"'\s]+)*(?=\s*[;{])/,lookbehind:!0,greedy:!0,inside:e.languages.extend("cpp",{})}}),e.languages.insertBefore("inside","double-colon",{"class-name":/\b[a-z_]\w*\b(?!\s*::)/i},e.languages.cpp["base-clause"])}(a),function(e){var t=/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;e.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-](?:[^;{\s]|\s+(?![\s{]))*(?:;|(?=\s*\{))/,inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+t.source+"|"+/(?:[^\\\r\n()"']|\\[\s\S])*/.source+")\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+t.source+"$"),alias:"url"}}},selector:{pattern:RegExp("(^|[{}\\s])[^{}\\s](?:[^{};\"'\\s]|\\s+(?![\\s{])|"+t.source+")*(?=\\s*\\{)"),lookbehind:!0},string:{pattern:t,greedy:!0},property:{pattern:/(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,lookbehind:!0},important:/!important\b/i,function:{pattern:/(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,lookbehind:!0},punctuation:/[(){};:,]/},e.languages.css.atrule.inside.rest=e.languages.css;var n=e.languages.markup;n&&(n.tag.addInlined("style","css"),n.tag.addAttribute("style","css"))}(a),function(e){var t,n=/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/;e.languages.css.selector={pattern:e.languages.css.selector.pattern,lookbehind:!0,inside:t={"pseudo-element":/:(?:after|before|first-letter|first-line|selection)|::[-\w]+/,"pseudo-class":/:[-\w]+/,class:/\.[-\w]+/,id:/#[-\w]+/,attribute:{pattern:RegExp("\\[(?:[^[\\]\"']|"+n.source+")*\\]"),greedy:!0,inside:{punctuation:/^\[|\]$/,"case-sensitivity":{pattern:/(\s)[si]$/i,lookbehind:!0,alias:"keyword"},namespace:{pattern:/^(\s*)(?:(?!\s)[-*\w\xA0-\uFFFF])*\|(?!=)/,lookbehind:!0,inside:{punctuation:/\|$/}},"attr-name":{pattern:/^(\s*)(?:(?!\s)[-\w\xA0-\uFFFF])+/,lookbehind:!0},"attr-value":[n,{pattern:/(=\s*)(?:(?!\s)[-\w\xA0-\uFFFF])+(?=\s*$)/,lookbehind:!0}],operator:/[|~*^$]?=/}},"n-th":[{pattern:/(\(\s*)[+-]?\d*[\dn](?:\s*[+-]\s*\d+)?(?=\s*\))/,lookbehind:!0,inside:{number:/[\dn]+/,operator:/[+-]/}},{pattern:/(\(\s*)(?:even|odd)(?=\s*\))/i,lookbehind:!0}],combinator:/>|\+|~|\|\|/,punctuation:/[(),]/}},e.languages.css.atrule.inside["selector-function-argument"].inside=t,e.languages.insertBefore("css","property",{variable:{pattern:/(^|[^-\w\xA0-\uFFFF])--(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*/i,lookbehind:!0}});var r={pattern:/(\b\d+)(?:%|[a-z]+(?![\w-]))/,lookbehind:!0},a={pattern:/(^|[^\w.-])-?(?:\d+(?:\.\d+)?|\.\d+)/,lookbehind:!0};e.languages.insertBefore("css","function",{operator:{pattern:/(\s)[+\-*\/](?=\s)/,lookbehind:!0},hexcode:{pattern:/\B#[\da-f]{3,8}\b/i,alias:"color"},color:[{pattern:/(^|[^\w-])(?:AliceBlue|AntiqueWhite|Aqua|Aquamarine|Azure|Beige|Bisque|Black|BlanchedAlmond|Blue|BlueViolet|Brown|BurlyWood|CadetBlue|Chartreuse|Chocolate|Coral|CornflowerBlue|Cornsilk|Crimson|Cyan|DarkBlue|DarkCyan|DarkGoldenRod|DarkGr[ae]y|DarkGreen|DarkKhaki|DarkMagenta|DarkOliveGreen|DarkOrange|DarkOrchid|DarkRed|DarkSalmon|DarkSeaGreen|DarkSlateBlue|DarkSlateGr[ae]y|DarkTurquoise|DarkViolet|DeepPink|DeepSkyBlue|DimGr[ae]y|DodgerBlue|FireBrick|FloralWhite|ForestGreen|Fuchsia|Gainsboro|GhostWhite|Gold|GoldenRod|Gr[ae]y|Green|GreenYellow|HoneyDew|HotPink|IndianRed|Indigo|Ivory|Khaki|Lavender|LavenderBlush|LawnGreen|LemonChiffon|LightBlue|LightCoral|LightCyan|LightGoldenRodYellow|LightGr[ae]y|LightGreen|LightPink|LightSalmon|LightSeaGreen|LightSkyBlue|LightSlateGr[ae]y|LightSteelBlue|LightYellow|Lime|LimeGreen|Linen|Magenta|Maroon|MediumAquaMarine|MediumBlue|MediumOrchid|MediumPurple|MediumSeaGreen|MediumSlateBlue|MediumSpringGreen|MediumTurquoise|MediumVioletRed|MidnightBlue|MintCream|MistyRose|Moccasin|NavajoWhite|Navy|OldLace|Olive|OliveDrab|Orange|OrangeRed|Orchid|PaleGoldenRod|PaleGreen|PaleTurquoise|PaleVioletRed|PapayaWhip|PeachPuff|Peru|Pink|Plum|PowderBlue|Purple|Red|RosyBrown|RoyalBlue|SaddleBrown|Salmon|SandyBrown|SeaGreen|SeaShell|Sienna|Silver|SkyBlue|SlateBlue|SlateGr[ae]y|Snow|SpringGreen|SteelBlue|Tan|Teal|Thistle|Tomato|Transparent|Turquoise|Violet|Wheat|White|WhiteSmoke|Yellow|YellowGreen)(?![\w-])/i,lookbehind:!0},{pattern:/\b(?:hsl|rgb)\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*\)\B|\b(?:hsl|rgb)a\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*,\s*(?:0|0?\.\d+|1)\s*\)\B/i,inside:{unit:r,number:a,function:/[\w-]+(?=\()/,punctuation:/[(),]/}}],entity:/\\[\da-f]{1,8}/i,unit:r,number:a})}(a),a.languages.javascript=a.languages.extend("clike",{"class-name":[a.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,lookbehind:!0}],keyword:[{pattern:/((?:^|\})\s*)catch\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],function:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:{pattern:RegExp(/(^|[^\w$])/.source+"(?:"+/NaN|Infinity/.source+"|"+/0[bB][01]+(?:_[01]+)*n?/.source+"|"+/0[oO][0-7]+(?:_[0-7]+)*n?/.source+"|"+/0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source+"|"+/\d+(?:_\d+)*n/.source+"|"+/(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/.source+")"+/(?![\w$])/.source),lookbehind:!0},operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),a.languages.javascript["class-name"][0].pattern=/(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/,a.languages.insertBefore("javascript","keyword",{regex:{pattern:/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)\/(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/,lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:a.languages.regex},"regex-delimiter":/^\/|\/$/,"regex-flags":/^[a-z]+$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:a.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:a.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:a.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:a.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),a.languages.insertBefore("javascript","string",{hashbang:{pattern:/^#!.*/,greedy:!0,alias:"comment"},"template-string":{pattern:/`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:a.languages.javascript}},string:/[\s\S]+/}},"string-property":{pattern:/((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,lookbehind:!0,greedy:!0,alias:"property"}}),a.languages.insertBefore("javascript","operator",{"literal-property":{pattern:/((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,lookbehind:!0,alias:"property"}}),a.languages.markup&&(a.languages.markup.tag.addInlined("script","javascript"),a.languages.markup.tag.addAttribute(/on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/.source,"javascript")),a.languages.js=a.languages.javascript,function(e){var t=/#(?!\{).+/,n={pattern:/#\{[^}]+\}/,alias:"variable"};e.languages.coffeescript=e.languages.extend("javascript",{comment:t,string:[{pattern:/'(?:\\[\s\S]|[^\\'])*'/,greedy:!0},{pattern:/"(?:\\[\s\S]|[^\\"])*"/,greedy:!0,inside:{interpolation:n}}],keyword:/\b(?:and|break|by|catch|class|continue|debugger|delete|do|each|else|extend|extends|false|finally|for|if|in|instanceof|is|isnt|let|loop|namespace|new|no|not|null|of|off|on|or|own|return|super|switch|then|this|throw|true|try|typeof|undefined|unless|until|when|while|window|with|yes|yield)\b/,"class-member":{pattern:/@(?!\d)\w+/,alias:"variable"}}),e.languages.insertBefore("coffeescript","comment",{"multiline-comment":{pattern:/###[\s\S]+?###/,alias:"comment"},"block-regex":{pattern:/\/{3}[\s\S]*?\/{3}/,alias:"regex",inside:{comment:t,interpolation:n}}}),e.languages.insertBefore("coffeescript","string",{"inline-javascript":{pattern:/`(?:\\[\s\S]|[^\\`])*`/,inside:{delimiter:{pattern:/^`|`$/,alias:"punctuation"},script:{pattern:/[\s\S]+/,alias:"language-javascript",inside:e.languages.javascript}}},"multiline-string":[{pattern:/'''[\s\S]*?'''/,greedy:!0,alias:"string"},{pattern:/"""[\s\S]*?"""/,greedy:!0,alias:"string",inside:{interpolation:n}}]}),e.languages.insertBefore("coffeescript","keyword",{property:/(?!\d)\w+(?=\s*:(?!:))/}),delete e.languages.coffeescript["template-string"],e.languages.coffee=e.languages.coffeescript}(a),function(e){var t=/[*&][^\s[\]{},]+/,n=/!(?:<[\w\-%#;/?:@&=+$,.!~*'()[\]]+>|(?:[a-zA-Z\d-]*!)?[\w\-%#;/?:@&=+$.~*'()]+)?/,r="(?:"+n.source+"(?:[ \t]+"+t.source+")?|"+t.source+"(?:[ \t]+"+n.source+")?)",a=/(?:[^\s\x00-\x08\x0e-\x1f!"#%&'*,\-:>?@[\]`{|}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]|[?:-])(?:[ \t]*(?:(?![#:])|:))*/.source.replace(//g,(function(){return/[^\s\x00-\x08\x0e-\x1f,[\]{}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]/.source})),o=/"(?:[^"\\\r\n]|\\.)*"|'(?:[^'\\\r\n]|\\.)*'/.source;function i(e,t){t=(t||"").replace(/m/g,"")+"m";var n=/([:\-,[{]\s*(?:\s<>[ \t]+)?)(?:<>)(?=[ \t]*(?:$|,|\]|\}|(?:[\r\n]\s*)?#))/.source.replace(/<>/g,(function(){return r})).replace(/<>/g,(function(){return e}));return RegExp(n,t)}e.languages.yaml={scalar:{pattern:RegExp(/([\-:]\s*(?:\s<>[ \t]+)?[|>])[ \t]*(?:((?:\r?\n|\r)[ \t]+)\S[^\r\n]*(?:\2[^\r\n]+)*)/.source.replace(/<>/g,(function(){return r}))),lookbehind:!0,alias:"string"},comment:/#.*/,key:{pattern:RegExp(/((?:^|[:\-,[{\r\n?])[ \t]*(?:<>[ \t]+)?)<>(?=\s*:\s)/.source.replace(/<>/g,(function(){return r})).replace(/<>/g,(function(){return"(?:"+a+"|"+o+")"}))),lookbehind:!0,greedy:!0,alias:"atrule"},directive:{pattern:/(^[ \t]*)%.+/m,lookbehind:!0,alias:"important"},datetime:{pattern:i(/\d{4}-\d\d?-\d\d?(?:[tT]|[ \t]+)\d\d?:\d{2}:\d{2}(?:\.\d*)?(?:[ \t]*(?:Z|[-+]\d\d?(?::\d{2})?))?|\d{4}-\d{2}-\d{2}|\d\d?:\d{2}(?::\d{2}(?:\.\d*)?)?/.source),lookbehind:!0,alias:"number"},boolean:{pattern:i(/false|true/.source,"i"),lookbehind:!0,alias:"important"},null:{pattern:i(/null|~/.source,"i"),lookbehind:!0,alias:"important"},string:{pattern:i(o),lookbehind:!0,greedy:!0},number:{pattern:i(/[+-]?(?:0x[\da-f]+|0o[0-7]+|(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?|\.inf|\.nan)/.source,"i"),lookbehind:!0},tag:n,important:t,punctuation:/---|[:[\]{}\-,|>?]|\.\.\./},e.languages.yml=e.languages.yaml}(a),function(e){var t=/(?:\\.|[^\\\n\r]|(?:\n|\r\n?)(?![\r\n]))/.source;function n(e){return e=e.replace(//g,(function(){return t})),RegExp(/((?:^|[^\\])(?:\\{2})*)/.source+"(?:"+e+")")}var r=/(?:\\.|``(?:[^`\r\n]|`(?!`))+``|`[^`\r\n]+`|[^\\|\r\n`])+/.source,a=/\|?__(?:\|__)+\|?(?:(?:\n|\r\n?)|(?![\s\S]))/.source.replace(/__/g,(function(){return r})),o=/\|?[ \t]*:?-{3,}:?[ \t]*(?:\|[ \t]*:?-{3,}:?[ \t]*)+\|?(?:\n|\r\n?)/.source;e.languages.markdown=e.languages.extend("markup",{}),e.languages.insertBefore("markdown","prolog",{"front-matter-block":{pattern:/(^(?:\s*[\r\n])?)---(?!.)[\s\S]*?[\r\n]---(?!.)/,lookbehind:!0,greedy:!0,inside:{punctuation:/^---|---$/,"front-matter":{pattern:/\S+(?:\s+\S+)*/,alias:["yaml","language-yaml"],inside:e.languages.yaml}}},blockquote:{pattern:/^>(?:[\t ]*>)*/m,alias:"punctuation"},table:{pattern:RegExp("^"+a+o+"(?:"+a+")*","m"),inside:{"table-data-rows":{pattern:RegExp("^("+a+o+")(?:"+a+")*$"),lookbehind:!0,inside:{"table-data":{pattern:RegExp(r),inside:e.languages.markdown},punctuation:/\|/}},"table-line":{pattern:RegExp("^("+a+")"+o+"$"),lookbehind:!0,inside:{punctuation:/\||:?-{3,}:?/}},"table-header-row":{pattern:RegExp("^"+a+"$"),inside:{"table-header":{pattern:RegExp(r),alias:"important",inside:e.languages.markdown},punctuation:/\|/}}}},code:[{pattern:/((?:^|\n)[ \t]*\n|(?:^|\r\n?)[ \t]*\r\n?)(?: {4}|\t).+(?:(?:\n|\r\n?)(?: {4}|\t).+)*/,lookbehind:!0,alias:"keyword"},{pattern:/^```[\s\S]*?^```$/m,greedy:!0,inside:{"code-block":{pattern:/^(```.*(?:\n|\r\n?))[\s\S]+?(?=(?:\n|\r\n?)^```$)/m,lookbehind:!0},"code-language":{pattern:/^(```).+/,lookbehind:!0},punctuation:/```/}}],title:[{pattern:/\S.*(?:\n|\r\n?)(?:==+|--+)(?=[ \t]*$)/m,alias:"important",inside:{punctuation:/==+$|--+$/}},{pattern:/(^\s*)#.+/m,lookbehind:!0,alias:"important",inside:{punctuation:/^#+|#+$/}}],hr:{pattern:/(^\s*)([*-])(?:[\t ]*\2){2,}(?=\s*$)/m,lookbehind:!0,alias:"punctuation"},list:{pattern:/(^\s*)(?:[*+-]|\d+\.)(?=[\t ].)/m,lookbehind:!0,alias:"punctuation"},"url-reference":{pattern:/!?\[[^\]]+\]:[\t ]+(?:\S+|<(?:\\.|[^>\\])+>)(?:[\t ]+(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\)))?/,inside:{variable:{pattern:/^(!?\[)[^\]]+/,lookbehind:!0},string:/(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\))$/,punctuation:/^[\[\]!:]|[<>]/},alias:"url"},bold:{pattern:n(/\b__(?:(?!_)|_(?:(?!_))+_)+__\b|\*\*(?:(?!\*)|\*(?:(?!\*))+\*)+\*\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^..)[\s\S]+(?=..$)/,lookbehind:!0,inside:{}},punctuation:/\*\*|__/}},italic:{pattern:n(/\b_(?:(?!_)|__(?:(?!_))+__)+_\b|\*(?:(?!\*)|\*\*(?:(?!\*))+\*\*)+\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^.)[\s\S]+(?=.$)/,lookbehind:!0,inside:{}},punctuation:/[*_]/}},strike:{pattern:n(/(~~?)(?:(?!~))+\2/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^~~?)[\s\S]+(?=\1$)/,lookbehind:!0,inside:{}},punctuation:/~~?/}},"code-snippet":{pattern:/(^|[^\\`])(?:``[^`\r\n]+(?:`[^`\r\n]+)*``(?!`)|`[^`\r\n]+`(?!`))/,lookbehind:!0,greedy:!0,alias:["code","keyword"]},url:{pattern:n(/!?\[(?:(?!\]))+\](?:\([^\s)]+(?:[\t ]+"(?:\\.|[^"\\])*")?\)|[ \t]?\[(?:(?!\]))+\])/.source),lookbehind:!0,greedy:!0,inside:{operator:/^!/,content:{pattern:/(^\[)[^\]]+(?=\])/,lookbehind:!0,inside:{}},variable:{pattern:/(^\][ \t]?\[)[^\]]+(?=\]$)/,lookbehind:!0},url:{pattern:/(^\]\()[^\s)]+/,lookbehind:!0},string:{pattern:/(^[ \t]+)"(?:\\.|[^"\\])*"(?=\)$)/,lookbehind:!0}}}}),["url","bold","italic","strike"].forEach((function(t){["url","bold","italic","strike","code-snippet"].forEach((function(n){t!==n&&(e.languages.markdown[t].inside.content.inside[n]=e.languages.markdown[n])}))})),e.hooks.add("after-tokenize",(function(e){"markdown"!==e.language&&"md"!==e.language||function e(t){if(t&&"string"!=typeof t)for(var n=0,r=t.length;n",quot:'"'},l=String.fromCodePoint||String.fromCharCode;e.languages.md=e.languages.markdown}(a),a.languages.graphql={comment:/#.*/,description:{pattern:/(?:"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*")(?=\s*[a-z_])/i,greedy:!0,alias:"string",inside:{"language-markdown":{pattern:/(^"(?:"")?)(?!\1)[\s\S]+(?=\1$)/,lookbehind:!0,inside:a.languages.markdown}}},string:{pattern:/"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*"/,greedy:!0},number:/(?:\B-|\b)\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,boolean:/\b(?:false|true)\b/,variable:/\$[a-z_]\w*/i,directive:{pattern:/@[a-z_]\w*/i,alias:"function"},"attr-name":{pattern:/\b[a-z_]\w*(?=\s*(?:\((?:[^()"]|"(?:\\.|[^\\"\r\n])*")*\))?:)/i,greedy:!0},"atom-input":{pattern:/\b[A-Z]\w*Input\b/,alias:"class-name"},scalar:/\b(?:Boolean|Float|ID|Int|String)\b/,constant:/\b[A-Z][A-Z_\d]*\b/,"class-name":{pattern:/(\b(?:enum|implements|interface|on|scalar|type|union)\s+|&\s*|:\s*|\[)[A-Z_]\w*/,lookbehind:!0},fragment:{pattern:/(\bfragment\s+|\.{3}\s*(?!on\b))[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},"definition-mutation":{pattern:/(\bmutation\s+)[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},"definition-query":{pattern:/(\bquery\s+)[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},keyword:/\b(?:directive|enum|extend|fragment|implements|input|interface|mutation|on|query|repeatable|scalar|schema|subscription|type|union)\b/,operator:/[!=|&]|\.{3}/,"property-query":/\w+(?=\s*\()/,object:/\w+(?=\s*\{)/,punctuation:/[!(){}\[\]:=,]/,property:/\w+/},a.hooks.add("after-tokenize",(function(e){if("graphql"===e.language)for(var t=e.tokens.filter((function(e){return"string"!=typeof e&&"comment"!==e.type&&"scalar"!==e.type})),n=0;n0)){var s=f(/^\{$/,/^\}$/);if(-1===s)continue;for(var l=n;l=0&&p(c,"variable-input")}}}}function u(e){return t[n+e]}function d(e,t){t=t||0;for(var n=0;n?|<|>)?|>[>=]?|\b(?:AND|BETWEEN|DIV|ILIKE|IN|IS|LIKE|NOT|OR|REGEXP|RLIKE|SOUNDS LIKE|XOR)\b/i,punctuation:/[;[\]()`,.]/},function(e){var t=e.languages.javascript["template-string"],n=t.pattern.source,r=t.inside.interpolation,a=r.inside["interpolation-punctuation"],o=r.pattern.source;function i(t,r){if(e.languages[t])return{pattern:RegExp("((?:"+r+")\\s*)"+n),lookbehind:!0,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},"embedded-code":{pattern:/[\s\S]+/,alias:t}}}}function s(e,t){return"___"+t.toUpperCase()+"_"+e+"___"}function l(t,n,r){var a={code:t,grammar:n,language:r};return e.hooks.run("before-tokenize",a),a.tokens=e.tokenize(a.code,a.grammar),e.hooks.run("after-tokenize",a),a.tokens}function c(t){var n={};n["interpolation-punctuation"]=a;var o=e.tokenize(t,n);if(3===o.length){var i=[1,1];i.push.apply(i,l(o[1],e.languages.javascript,"javascript")),o.splice.apply(o,i)}return new e.Token("interpolation",o,r.alias,t)}function u(t,n,r){var a=e.tokenize(t,{interpolation:{pattern:RegExp(o),lookbehind:!0}}),i=0,u={},d=l(a.map((function(e){if("string"==typeof e)return e;for(var n,a=e.content;-1!==t.indexOf(n=s(i++,r)););return u[n]=a,n})).join(""),n,r),f=Object.keys(u);return i=0,function e(t){for(var n=0;n=f.length)return;var r=t[n];if("string"==typeof r||"string"==typeof r.content){var a=f[i],o="string"==typeof r?r:r.content,s=o.indexOf(a);if(-1!==s){++i;var l=o.substring(0,s),d=c(u[a]),p=o.substring(s+a.length),m=[];if(l&&m.push(l),m.push(d),p){var h=[p];e(h),m.push.apply(m,h)}"string"==typeof r?(t.splice.apply(t,[n,1].concat(m)),n+=m.length-1):r.content=m}}else{var g=r.content;Array.isArray(g)?e(g):e([g])}}}(d),new e.Token(r,d,"language-"+r,t)}e.languages.javascript["template-string"]=[i("css",/\b(?:styled(?:\([^)]*\))?(?:\s*\.\s*\w+(?:\([^)]*\))*)*|css(?:\s*\.\s*(?:global|resolve))?|createGlobalStyle|keyframes)/.source),i("html",/\bhtml|\.\s*(?:inner|outer)HTML\s*\+?=/.source),i("svg",/\bsvg/.source),i("markdown",/\b(?:markdown|md)/.source),i("graphql",/\b(?:gql|graphql(?:\s*\.\s*experimental)?)/.source),i("sql",/\bsql/.source),t].filter(Boolean);var d={javascript:!0,js:!0,typescript:!0,ts:!0,jsx:!0,tsx:!0};function f(e){return"string"==typeof e?e:Array.isArray(e)?e.map(f).join(""):f(e.content)}e.hooks.add("after-tokenize",(function(t){t.language in d&&function t(n){for(var r=0,a=n.length;r]|<(?:[^<>]|<[^<>]*>)*>)*>)?/,lookbehind:!0,greedy:!0,inside:null},builtin:/\b(?:Array|Function|Promise|any|boolean|console|never|number|string|symbol|unknown)\b/}),e.languages.typescript.keyword.push(/\b(?:abstract|declare|is|keyof|readonly|require)\b/,/\b(?:asserts|infer|interface|module|namespace|type)\b(?=\s*(?:[{_$a-zA-Z\xA0-\uFFFF]|$))/,/\btype\b(?=\s*(?:[\{*]|$))/),delete e.languages.typescript.parameter,delete e.languages.typescript["literal-property"];var t=e.languages.extend("typescript",{});delete t["class-name"],e.languages.typescript["class-name"].inside=t,e.languages.insertBefore("typescript","function",{decorator:{pattern:/@[$\w\xA0-\uFFFF]+/,inside:{at:{pattern:/^@/,alias:"operator"},function:/^[\s\S]+/}},"generic-function":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>(?=\s*\()/,greedy:!0,inside:{function:/^#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:t}}}}),e.languages.ts=e.languages.typescript}(a),function(e){function t(e,t){return RegExp(e.replace(//g,(function(){return/(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/.source})),t)}e.languages.insertBefore("javascript","function-variable",{"method-variable":{pattern:RegExp("(\\.\\s*)"+e.languages.javascript["function-variable"].pattern.source),lookbehind:!0,alias:["function-variable","method","function","property-access"]}}),e.languages.insertBefore("javascript","function",{method:{pattern:RegExp("(\\.\\s*)"+e.languages.javascript.function.source),lookbehind:!0,alias:["function","property-access"]}}),e.languages.insertBefore("javascript","constant",{"known-class-name":[{pattern:/\b(?:(?:Float(?:32|64)|(?:Int|Uint)(?:8|16|32)|Uint8Clamped)?Array|ArrayBuffer|BigInt|Boolean|DataView|Date|Error|Function|Intl|JSON|(?:Weak)?(?:Map|Set)|Math|Number|Object|Promise|Proxy|Reflect|RegExp|String|Symbol|WebAssembly)\b/,alias:"class-name"},{pattern:/\b(?:[A-Z]\w*)Error\b/,alias:"class-name"}]}),e.languages.insertBefore("javascript","keyword",{imports:{pattern:t(/(\bimport\b\s*)(?:(?:\s*,\s*(?:\*\s*as\s+|\{[^{}]*\}))?|\*\s*as\s+|\{[^{}]*\})(?=\s*\bfrom\b)/.source),lookbehind:!0,inside:e.languages.javascript},exports:{pattern:t(/(\bexport\b\s*)(?:\*(?:\s*as\s+)?(?=\s*\bfrom\b)|\{[^{}]*\})/.source),lookbehind:!0,inside:e.languages.javascript}}),e.languages.javascript.keyword.unshift({pattern:/\b(?:as|default|export|from|import)\b/,alias:"module"},{pattern:/\b(?:await|break|catch|continue|do|else|finally|for|if|return|switch|throw|try|while|yield)\b/,alias:"control-flow"},{pattern:/\bnull\b/,alias:["null","nil"]},{pattern:/\bundefined\b/,alias:"nil"}),e.languages.insertBefore("javascript","operator",{spread:{pattern:/\.{3}/,alias:"operator"},arrow:{pattern:/=>/,alias:"operator"}}),e.languages.insertBefore("javascript","punctuation",{"property-access":{pattern:t(/(\.\s*)#?/.source),lookbehind:!0},"maybe-class-name":{pattern:/(^|[^$\w\xA0-\uFFFF])[A-Z][$\w\xA0-\uFFFF]+/,lookbehind:!0},dom:{pattern:/\b(?:document|(?:local|session)Storage|location|navigator|performance|window)\b/,alias:"variable"},console:{pattern:/\bconsole(?=\s*\.)/,alias:"class-name"}});for(var n=["function","function-variable","method","method-variable","property-access"],r=0;r*\.{3}(?:[^{}]|)*\})/.source;function o(e,t){return e=e.replace(//g,(function(){return n})).replace(//g,(function(){return r})).replace(//g,(function(){return a})),RegExp(e,t)}a=o(a).source,e.languages.jsx=e.languages.extend("markup",t),e.languages.jsx.tag.pattern=o(/<\/?(?:[\w.:-]+(?:+(?:[\w.:$-]+(?:=(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s{'"/>=]+|))?|))**\/?)?>/.source),e.languages.jsx.tag.inside.tag.pattern=/^<\/?[^\s>\/]*/,e.languages.jsx.tag.inside["attr-value"].pattern=/=(?!\{)(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s'">]+)/,e.languages.jsx.tag.inside.tag.inside["class-name"]=/^[A-Z]\w*(?:\.[A-Z]\w*)*$/,e.languages.jsx.tag.inside.comment=t.comment,e.languages.insertBefore("inside","attr-name",{spread:{pattern:o(//.source),inside:e.languages.jsx}},e.languages.jsx.tag),e.languages.insertBefore("inside","special-attr",{script:{pattern:o(/=/.source),alias:"language-javascript",inside:{"script-punctuation":{pattern:/^=(?=\{)/,alias:"punctuation"},rest:e.languages.jsx}}},e.languages.jsx.tag);var i=function(e){return e?"string"==typeof e?e:"string"==typeof e.content?e.content:e.content.map(i).join(""):""},s=function(t){for(var n=[],r=0;r0&&n[n.length-1].tagName===i(a.content[0].content[1])&&n.pop():"/>"===a.content[a.content.length-1].content||n.push({tagName:i(a.content[0].content[1]),openedBraces:0}):n.length>0&&"punctuation"===a.type&&"{"===a.content?n[n.length-1].openedBraces++:n.length>0&&n[n.length-1].openedBraces>0&&"punctuation"===a.type&&"}"===a.content?n[n.length-1].openedBraces--:o=!0),(o||"string"==typeof a)&&n.length>0&&0===n[n.length-1].openedBraces){var l=i(a);r0&&("string"==typeof t[r-1]||"plain-text"===t[r-1].type)&&(l=i(t[r-1])+l,t.splice(r-1,1),r--),t[r]=new e.Token("plain-text",l,null,l)}a.content&&"string"!=typeof a.content&&s(a.content)}};e.hooks.add("after-tokenize",(function(e){"jsx"!==e.language&&"tsx"!==e.language||s(e.tokens)}))}(a),function(e){e.languages.diff={coord:[/^(?:\*{3}|-{3}|\+{3}).*$/m,/^@@.*@@$/m,/^\d.*$/m]};var t={"deleted-sign":"-","deleted-arrow":"<","inserted-sign":"+","inserted-arrow":">",unchanged:" ",diff:"!"};Object.keys(t).forEach((function(n){var r=t[n],a=[];/^\w+$/.test(n)||a.push(/\w+/.exec(n)[0]),"diff"===n&&a.push("bold"),e.languages.diff[n]={pattern:RegExp("^(?:["+r+"].*(?:\r\n?|\n|(?![\\s\\S])))+","m"),alias:a,inside:{line:{pattern:/(.)(?=[\s\S]).*(?:\r\n?|\n)?/,lookbehind:!0},prefix:{pattern:/[\s\S]/,alias:/\w+/.exec(n)[0]}}}})),Object.defineProperty(e.languages.diff,"PREFIXES",{value:t})}(a),a.languages.git={comment:/^#.*/m,deleted:/^[-\u2013].*/m,inserted:/^\+.*/m,string:/("|')(?:\\.|(?!\1)[^\\\r\n])*\1/,command:{pattern:/^.*\$ git .*$/m,inside:{parameter:/\s--?\w+/}},coord:/^@@.*@@$/m,"commit-sha1":/^commit \w{40}$/m},a.languages.go=a.languages.extend("clike",{string:{pattern:/(^|[^\\])"(?:\\.|[^"\\\r\n])*"|`[^`]*`/,lookbehind:!0,greedy:!0},keyword:/\b(?:break|case|chan|const|continue|default|defer|else|fallthrough|for|func|go(?:to)?|if|import|interface|map|package|range|return|select|struct|switch|type|var)\b/,boolean:/\b(?:_|false|iota|nil|true)\b/,number:[/\b0(?:b[01_]+|o[0-7_]+)i?\b/i,/\b0x(?:[a-f\d_]+(?:\.[a-f\d_]*)?|\.[a-f\d_]+)(?:p[+-]?\d+(?:_\d+)*)?i?(?!\w)/i,/(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?[\d_]+)?i?(?!\w)/i],operator:/[*\/%^!=]=?|\+[=+]?|-[=-]?|\|[=|]?|&(?:=|&|\^=?)?|>(?:>=?|=)?|<(?:<=?|=|-)?|:=|\.\.\./,builtin:/\b(?:append|bool|byte|cap|close|complex|complex(?:64|128)|copy|delete|error|float(?:32|64)|u?int(?:8|16|32|64)?|imag|len|make|new|panic|print(?:ln)?|real|recover|rune|string|uintptr)\b/}),a.languages.insertBefore("go","string",{char:{pattern:/'(?:\\.|[^'\\\r\n]){0,10}'/,greedy:!0}}),delete a.languages.go["class-name"],function(e){function t(e,t){return"___"+e.toUpperCase()+t+"___"}Object.defineProperties(e.languages["markup-templating"]={},{buildPlaceholders:{value:function(n,r,a,o){if(n.language===r){var i=n.tokenStack=[];n.code=n.code.replace(a,(function(e){if("function"==typeof o&&!o(e))return e;for(var a,s=i.length;-1!==n.code.indexOf(a=t(r,s));)++s;return i[s]=e,a})),n.grammar=e.languages.markup}}},tokenizePlaceholders:{value:function(n,r){if(n.language===r&&n.tokenStack){n.grammar=e.languages[r];var a=0,o=Object.keys(n.tokenStack);!function i(s){for(var l=0;l=o.length);l++){var c=s[l];if("string"==typeof c||c.content&&"string"==typeof c.content){var u=o[a],d=n.tokenStack[u],f="string"==typeof c?c:c.content,p=t(r,u),m=f.indexOf(p);if(m>-1){++a;var h=f.substring(0,m),g=new e.Token(r,e.tokenize(d,n.grammar),"language-"+r,d),v=f.substring(m+p.length),b=[];h&&b.push.apply(b,i([h])),b.push(g),v&&b.push.apply(b,i([v])),"string"==typeof c?s.splice.apply(s,[l,1].concat(b)):c.content=b}}else c.content&&i(c.content)}return s}(n.tokens)}}}})}(a),function(e){e.languages.handlebars={comment:/\{\{![\s\S]*?\}\}/,delimiter:{pattern:/^\{\{\{?|\}\}\}?$/,alias:"punctuation"},string:/(["'])(?:\\.|(?!\1)[^\\\r\n])*\1/,number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[Ee][+-]?\d+)?/,boolean:/\b(?:false|true)\b/,block:{pattern:/^(\s*(?:~\s*)?)[#\/]\S+?(?=\s*(?:~\s*)?$|\s)/,lookbehind:!0,alias:"keyword"},brackets:{pattern:/\[[^\]]+\]/,inside:{punctuation:/\[|\]/,variable:/[\s\S]+/}},punctuation:/[!"#%&':()*+,.\/;<=>@\[\\\]^`{|}~]/,variable:/[^!"#%&'()*+,\/;<=>@\[\\\]^`{|}~\s]+/},e.hooks.add("before-tokenize",(function(t){e.languages["markup-templating"].buildPlaceholders(t,"handlebars",/\{\{\{[\s\S]+?\}\}\}|\{\{[\s\S]+?\}\}/g)})),e.hooks.add("after-tokenize",(function(t){e.languages["markup-templating"].tokenizePlaceholders(t,"handlebars")})),e.languages.hbs=e.languages.handlebars}(a),a.languages.json={property:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?=\s*:)/,lookbehind:!0,greedy:!0},string:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?!\s*:)/,lookbehind:!0,greedy:!0},comment:{pattern:/\/\/.*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},number:/-?\b\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,punctuation:/[{}[\],]/,operator:/:/,boolean:/\b(?:false|true)\b/,null:{pattern:/\bnull\b/,alias:"keyword"}},a.languages.webmanifest=a.languages.json,a.languages.less=a.languages.extend("css",{comment:[/\/\*[\s\S]*?\*\//,{pattern:/(^|[^\\])\/\/.*/,lookbehind:!0}],atrule:{pattern:/@[\w-](?:\((?:[^(){}]|\([^(){}]*\))*\)|[^(){};\s]|\s+(?!\s))*?(?=\s*\{)/,inside:{punctuation:/[:()]/}},selector:{pattern:/(?:@\{[\w-]+\}|[^{};\s@])(?:@\{[\w-]+\}|\((?:[^(){}]|\([^(){}]*\))*\)|[^(){};@\s]|\s+(?!\s))*?(?=\s*\{)/,inside:{variable:/@+[\w-]+/}},property:/(?:@\{[\w-]+\}|[\w-])+(?:\+_?)?(?=\s*:)/,operator:/[+\-*\/]/}),a.languages.insertBefore("less","property",{variable:[{pattern:/@[\w-]+\s*:/,inside:{punctuation:/:/}},/@@?[\w-]+/],"mixin-usage":{pattern:/([{;]\s*)[.#](?!\d)[\w-].*?(?=[(;])/,lookbehind:!0,alias:"function"}}),a.languages.makefile={comment:{pattern:/(^|[^\\])#(?:\\(?:\r\n|[\s\S])|[^\\\r\n])*/,lookbehind:!0},string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"builtin-target":{pattern:/\.[A-Z][^:#=\s]+(?=\s*:(?!=))/,alias:"builtin"},target:{pattern:/^(?:[^:=\s]|[ \t]+(?![\s:]))+(?=\s*:(?!=))/m,alias:"symbol",inside:{variable:/\$+(?:(?!\$)[^(){}:#=\s]+|(?=[({]))/}},variable:/\$+(?:(?!\$)[^(){}:#=\s]+|\([@*%<^+?][DF]\)|(?=[({]))/,keyword:/-include\b|\b(?:define|else|endef|endif|export|ifn?def|ifn?eq|include|override|private|sinclude|undefine|unexport|vpath)\b/,function:{pattern:/(\()(?:abspath|addsuffix|and|basename|call|dir|error|eval|file|filter(?:-out)?|findstring|firstword|flavor|foreach|guile|if|info|join|lastword|load|notdir|or|origin|patsubst|realpath|shell|sort|strip|subst|suffix|value|warning|wildcard|word(?:list|s)?)(?=[ \t])/,lookbehind:!0},operator:/(?:::|[?:+!])?=|[|@]/,punctuation:/[:;(){}]/},a.languages.objectivec=a.languages.extend("c",{string:{pattern:/@?"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},keyword:/\b(?:asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|in|inline|int|long|register|return|self|short|signed|sizeof|static|struct|super|switch|typedef|typeof|union|unsigned|void|volatile|while)\b|(?:@interface|@end|@implementation|@protocol|@class|@public|@protected|@private|@property|@try|@catch|@finally|@throw|@synthesize|@dynamic|@selector)\b/,operator:/-[->]?|\+\+?|!=?|<>?=?|==?|&&?|\|\|?|[~^%?*\/@]/}),delete a.languages.objectivec["class-name"],a.languages.objc=a.languages.objectivec,a.languages.ocaml={comment:{pattern:/\(\*[\s\S]*?\*\)/,greedy:!0},char:{pattern:/'(?:[^\\\r\n']|\\(?:.|[ox]?[0-9a-f]{1,3}))'/i,greedy:!0},string:[{pattern:/"(?:\\(?:[\s\S]|\r\n)|[^\\\r\n"])*"/,greedy:!0},{pattern:/\{([a-z_]*)\|[\s\S]*?\|\1\}/,greedy:!0}],number:[/\b(?:0b[01][01_]*|0o[0-7][0-7_]*)\b/i,/\b0x[a-f0-9][a-f0-9_]*(?:\.[a-f0-9_]*)?(?:p[+-]?\d[\d_]*)?(?!\w)/i,/\b\d[\d_]*(?:\.[\d_]*)?(?:e[+-]?\d[\d_]*)?(?!\w)/i],directive:{pattern:/\B#\w+/,alias:"property"},label:{pattern:/\B~\w+/,alias:"property"},"type-variable":{pattern:/\B'\w+/,alias:"function"},variant:{pattern:/`\w+/,alias:"symbol"},keyword:/\b(?:as|assert|begin|class|constraint|do|done|downto|else|end|exception|external|for|fun|function|functor|if|in|include|inherit|initializer|lazy|let|match|method|module|mutable|new|nonrec|object|of|open|private|rec|sig|struct|then|to|try|type|val|value|virtual|when|where|while|with)\b/,boolean:/\b(?:false|true)\b/,"operator-like-punctuation":{pattern:/\[[<>|]|[>|]\]|\{<|>\}/,alias:"punctuation"},operator:/\.[.~]|:[=>]|[=<>@^|&+\-*\/$%!?~][!$%&*+\-.\/:<=>?@^|~]*|\b(?:and|asr|land|lor|lsl|lsr|lxor|mod|or)\b/,punctuation:/;;|::|[(){}\[\].,:;#]|\b_\b/},a.languages.python={comment:{pattern:/(^|[^\\])#.*/,lookbehind:!0,greedy:!0},"string-interpolation":{pattern:/(?:f|fr|rf)(?:("""|''')[\s\S]*?\1|("|')(?:\\.|(?!\2)[^\\\r\n])*\2)/i,greedy:!0,inside:{interpolation:{pattern:/((?:^|[^{])(?:\{\{)*)\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}])+\})+\})+\}/,lookbehind:!0,inside:{"format-spec":{pattern:/(:)[^:(){}]+(?=\}$)/,lookbehind:!0},"conversion-option":{pattern:/![sra](?=[:}]$)/,alias:"punctuation"},rest:null}},string:/[\s\S]+/}},"triple-quoted-string":{pattern:/(?:[rub]|br|rb)?("""|''')[\s\S]*?\1/i,greedy:!0,alias:"string"},string:{pattern:/(?:[rub]|br|rb)?("|')(?:\\.|(?!\1)[^\\\r\n])*\1/i,greedy:!0},function:{pattern:/((?:^|\s)def[ \t]+)[a-zA-Z_]\w*(?=\s*\()/g,lookbehind:!0},"class-name":{pattern:/(\bclass\s+)\w+/i,lookbehind:!0},decorator:{pattern:/(^[\t ]*)@\w+(?:\.\w+)*/m,lookbehind:!0,alias:["annotation","punctuation"],inside:{punctuation:/\./}},keyword:/\b(?:_(?=\s*:)|and|as|assert|async|await|break|case|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|match|nonlocal|not|or|pass|print|raise|return|try|while|with|yield)\b/,builtin:/\b(?:__import__|abs|all|any|apply|ascii|basestring|bin|bool|buffer|bytearray|bytes|callable|chr|classmethod|cmp|coerce|compile|complex|delattr|dict|dir|divmod|enumerate|eval|execfile|file|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|intern|isinstance|issubclass|iter|len|list|locals|long|map|max|memoryview|min|next|object|oct|open|ord|pow|property|range|raw_input|reduce|reload|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unichr|unicode|vars|xrange|zip)\b/,boolean:/\b(?:False|None|True)\b/,number:/\b0(?:b(?:_?[01])+|o(?:_?[0-7])+|x(?:_?[a-f0-9])+)\b|(?:\b\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\B\.\d+(?:_\d+)*)(?:e[+-]?\d+(?:_\d+)*)?j?(?!\w)/i,operator:/[-+%=]=?|!=|:=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]/,punctuation:/[{}[\];(),.:]/},a.languages.python["string-interpolation"].inside.interpolation.inside.rest=a.languages.python,a.languages.py=a.languages.python,a.languages.reason=a.languages.extend("clike",{string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^\\\r\n"])*"/,greedy:!0},"class-name":/\b[A-Z]\w*/,keyword:/\b(?:and|as|assert|begin|class|constraint|do|done|downto|else|end|exception|external|for|fun|function|functor|if|in|include|inherit|initializer|lazy|let|method|module|mutable|new|nonrec|object|of|open|or|private|rec|sig|struct|switch|then|to|try|type|val|virtual|when|while|with)\b/,operator:/\.{3}|:[:=]|\|>|->|=(?:==?|>)?|<=?|>=?|[|^?'#!~`]|[+\-*\/]\.?|\b(?:asr|land|lor|lsl|lsr|lxor|mod)\b/}),a.languages.insertBefore("reason","class-name",{char:{pattern:/'(?:\\x[\da-f]{2}|\\o[0-3][0-7][0-7]|\\\d{3}|\\.|[^'\\\r\n])'/,greedy:!0},constructor:/\b[A-Z]\w*\b(?!\s*\.)/,label:{pattern:/\b[a-z]\w*(?=::)/,alias:"symbol"}}),delete a.languages.reason.function,function(e){e.languages.sass=e.languages.extend("css",{comment:{pattern:/^([ \t]*)\/[\/*].*(?:(?:\r?\n|\r)\1[ \t].+)*/m,lookbehind:!0,greedy:!0}}),e.languages.insertBefore("sass","atrule",{"atrule-line":{pattern:/^(?:[ \t]*)[@+=].+/m,greedy:!0,inside:{atrule:/(?:@[\w-]+|[+=])/}}}),delete e.languages.sass.atrule;var t=/\$[-\w]+|#\{\$[-\w]+\}/,n=[/[+*\/%]|[=!]=|<=?|>=?|\b(?:and|not|or)\b/,{pattern:/(\s)-(?=\s)/,lookbehind:!0}];e.languages.insertBefore("sass","property",{"variable-line":{pattern:/^[ \t]*\$.+/m,greedy:!0,inside:{punctuation:/:/,variable:t,operator:n}},"property-line":{pattern:/^[ \t]*(?:[^:\s]+ *:.*|:[^:\s].*)/m,greedy:!0,inside:{property:[/[^:\s]+(?=\s*:)/,{pattern:/(:)[^:\s]+/,lookbehind:!0}],punctuation:/:/,variable:t,operator:n,important:e.languages.sass.important}}}),delete e.languages.sass.property,delete e.languages.sass.important,e.languages.insertBefore("sass","punctuation",{selector:{pattern:/^([ \t]*)\S(?:,[^,\r\n]+|[^,\r\n]*)(?:,[^,\r\n]+)*(?:,(?:\r?\n|\r)\1[ \t]+\S(?:,[^,\r\n]+|[^,\r\n]*)(?:,[^,\r\n]+)*)*/m,lookbehind:!0,greedy:!0}})}(a),a.languages.scss=a.languages.extend("css",{comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0},atrule:{pattern:/@[\w-](?:\([^()]+\)|[^()\s]|\s+(?!\s))*?(?=\s+[{;])/,inside:{rule:/@[\w-]+/}},url:/(?:[-a-z]+-)?url(?=\()/i,selector:{pattern:/(?=\S)[^@;{}()]?(?:[^@;{}()\s]|\s+(?!\s)|#\{\$[-\w]+\})+(?=\s*\{(?:\}|\s|[^}][^:{}]*[:{][^}]))/,inside:{parent:{pattern:/&/,alias:"important"},placeholder:/%[-\w]+/,variable:/\$[-\w]+|#\{\$[-\w]+\}/}},property:{pattern:/(?:[-\w]|\$[-\w]|#\{\$[-\w]+\})+(?=\s*:)/,inside:{variable:/\$[-\w]+|#\{\$[-\w]+\}/}}}),a.languages.insertBefore("scss","atrule",{keyword:[/@(?:content|debug|each|else(?: if)?|extend|for|forward|function|if|import|include|mixin|return|use|warn|while)\b/i,{pattern:/( )(?:from|through)(?= )/,lookbehind:!0}]}),a.languages.insertBefore("scss","important",{variable:/\$[-\w]+|#\{\$[-\w]+\}/}),a.languages.insertBefore("scss","function",{"module-modifier":{pattern:/\b(?:as|hide|show|with)\b/i,alias:"keyword"},placeholder:{pattern:/%[-\w]+/,alias:"selector"},statement:{pattern:/\B!(?:default|optional)\b/i,alias:"keyword"},boolean:/\b(?:false|true)\b/,null:{pattern:/\bnull\b/,alias:"keyword"},operator:{pattern:/(\s)(?:[-+*\/%]|[=!]=|<=?|>=?|and|not|or)(?=\s)/,lookbehind:!0}}),a.languages.scss.atrule.inside.rest=a.languages.scss,function(e){var t={pattern:/(\b\d+)(?:%|[a-z]+)/,lookbehind:!0},n={pattern:/(^|[^\w.-])-?(?:\d+(?:\.\d+)?|\.\d+)/,lookbehind:!0},r={comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0},url:{pattern:/\burl\((["']?).*?\1\)/i,greedy:!0},string:{pattern:/("|')(?:(?!\1)[^\\\r\n]|\\(?:\r\n|[\s\S]))*\1/,greedy:!0},interpolation:null,func:null,important:/\B!(?:important|optional)\b/i,keyword:{pattern:/(^|\s+)(?:(?:else|for|if|return|unless)(?=\s|$)|@[\w-]+)/,lookbehind:!0},hexcode:/#[\da-f]{3,6}/i,color:[/\b(?:AliceBlue|AntiqueWhite|Aqua|Aquamarine|Azure|Beige|Bisque|Black|BlanchedAlmond|Blue|BlueViolet|Brown|BurlyWood|CadetBlue|Chartreuse|Chocolate|Coral|CornflowerBlue|Cornsilk|Crimson|Cyan|DarkBlue|DarkCyan|DarkGoldenRod|DarkGr[ae]y|DarkGreen|DarkKhaki|DarkMagenta|DarkOliveGreen|DarkOrange|DarkOrchid|DarkRed|DarkSalmon|DarkSeaGreen|DarkSlateBlue|DarkSlateGr[ae]y|DarkTurquoise|DarkViolet|DeepPink|DeepSkyBlue|DimGr[ae]y|DodgerBlue|FireBrick|FloralWhite|ForestGreen|Fuchsia|Gainsboro|GhostWhite|Gold|GoldenRod|Gr[ae]y|Green|GreenYellow|HoneyDew|HotPink|IndianRed|Indigo|Ivory|Khaki|Lavender|LavenderBlush|LawnGreen|LemonChiffon|LightBlue|LightCoral|LightCyan|LightGoldenRodYellow|LightGr[ae]y|LightGreen|LightPink|LightSalmon|LightSeaGreen|LightSkyBlue|LightSlateGr[ae]y|LightSteelBlue|LightYellow|Lime|LimeGreen|Linen|Magenta|Maroon|MediumAquaMarine|MediumBlue|MediumOrchid|MediumPurple|MediumSeaGreen|MediumSlateBlue|MediumSpringGreen|MediumTurquoise|MediumVioletRed|MidnightBlue|MintCream|MistyRose|Moccasin|NavajoWhite|Navy|OldLace|Olive|OliveDrab|Orange|OrangeRed|Orchid|PaleGoldenRod|PaleGreen|PaleTurquoise|PaleVioletRed|PapayaWhip|PeachPuff|Peru|Pink|Plum|PowderBlue|Purple|Red|RosyBrown|RoyalBlue|SaddleBrown|Salmon|SandyBrown|SeaGreen|SeaShell|Sienna|Silver|SkyBlue|SlateBlue|SlateGr[ae]y|Snow|SpringGreen|SteelBlue|Tan|Teal|Thistle|Tomato|Transparent|Turquoise|Violet|Wheat|White|WhiteSmoke|Yellow|YellowGreen)\b/i,{pattern:/\b(?:hsl|rgb)\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*\)\B|\b(?:hsl|rgb)a\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*,\s*(?:0|0?\.\d+|1)\s*\)\B/i,inside:{unit:t,number:n,function:/[\w-]+(?=\()/,punctuation:/[(),]/}}],entity:/\\[\da-f]{1,8}/i,unit:t,boolean:/\b(?:false|true)\b/,operator:[/~|[+!\/%<>?=]=?|[-:]=|\*[*=]?|\.{2,3}|&&|\|\||\B-\B|\b(?:and|in|is(?: a| defined| not|nt)?|not|or)\b/],number:n,punctuation:/[{}()\[\];:,]/};r.interpolation={pattern:/\{[^\r\n}:]+\}/,alias:"variable",inside:{delimiter:{pattern:/^\{|\}$/,alias:"punctuation"},rest:r}},r.func={pattern:/[\w-]+\([^)]*\).*/,inside:{function:/^[^(]+/,rest:r}},e.languages.stylus={"atrule-declaration":{pattern:/(^[ \t]*)@.+/m,lookbehind:!0,inside:{atrule:/^@[\w-]+/,rest:r}},"variable-declaration":{pattern:/(^[ \t]*)[\w$-]+\s*.?=[ \t]*(?:\{[^{}]*\}|\S.*|$)/m,lookbehind:!0,inside:{variable:/^\S+/,rest:r}},statement:{pattern:/(^[ \t]*)(?:else|for|if|return|unless)[ \t].+/m,lookbehind:!0,inside:{keyword:/^\S+/,rest:r}},"property-declaration":{pattern:/((?:^|\{)([ \t]*))(?:[\w-]|\{[^}\r\n]+\})+(?:\s*:\s*|[ \t]+)(?!\s)[^{\r\n]*(?:;|[^{\r\n,]$(?!(?:\r?\n|\r)(?:\{|\2[ \t])))/m,lookbehind:!0,inside:{property:{pattern:/^[^\s:]+/,inside:{interpolation:r.interpolation}},rest:r}},selector:{pattern:/(^[ \t]*)(?:(?=\S)(?:[^{}\r\n:()]|::?[\w-]+(?:\([^)\r\n]*\)|(?![\w-]))|\{[^}\r\n]+\})+)(?:(?:\r?\n|\r)(?:\1(?:(?=\S)(?:[^{}\r\n:()]|::?[\w-]+(?:\([^)\r\n]*\)|(?![\w-]))|\{[^}\r\n]+\})+)))*(?:,$|\{|(?=(?:\r?\n|\r)(?:\{|\1[ \t])))/m,lookbehind:!0,inside:{interpolation:r.interpolation,comment:r.comment,punctuation:/[{},]/}},func:r.func,string:r.string,comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0,greedy:!0},interpolation:r.interpolation,punctuation:/[{}()\[\];:.]/}}(a),function(e){var t=e.util.clone(e.languages.typescript);e.languages.tsx=e.languages.extend("jsx",t),delete e.languages.tsx.parameter,delete e.languages.tsx["literal-property"];var n=e.languages.tsx.tag;n.pattern=RegExp(/(^|[^\w$]|(?=<\/))/.source+"(?:"+n.pattern.source+")",n.pattern.flags),n.lookbehind=!0}(a),a.languages.wasm={comment:[/\(;[\s\S]*?;\)/,{pattern:/;;.*/,greedy:!0}],string:{pattern:/"(?:\\[\s\S]|[^"\\])*"/,greedy:!0},keyword:[{pattern:/\b(?:align|offset)=/,inside:{operator:/=/}},{pattern:/\b(?:(?:f32|f64|i32|i64)(?:\.(?:abs|add|and|ceil|clz|const|convert_[su]\/i(?:32|64)|copysign|ctz|demote\/f64|div(?:_[su])?|eqz?|extend_[su]\/i32|floor|ge(?:_[su])?|gt(?:_[su])?|le(?:_[su])?|load(?:(?:8|16|32)_[su])?|lt(?:_[su])?|max|min|mul|neg?|nearest|or|popcnt|promote\/f32|reinterpret\/[fi](?:32|64)|rem_[su]|rot[lr]|shl|shr_[su]|sqrt|store(?:8|16|32)?|sub|trunc(?:_[su]\/f(?:32|64))?|wrap\/i64|xor))?|memory\.(?:grow|size))\b/,inside:{punctuation:/\./}},/\b(?:anyfunc|block|br(?:_if|_table)?|call(?:_indirect)?|data|drop|elem|else|end|export|func|get_(?:global|local)|global|if|import|local|loop|memory|module|mut|nop|offset|param|result|return|select|set_(?:global|local)|start|table|tee_local|then|type|unreachable)\b/],variable:/\$[\w!#$%&'*+\-./:<=>?@\\^`|~]+/,number:/[+-]?\b(?:\d(?:_?\d)*(?:\.\d(?:_?\d)*)?(?:[eE][+-]?\d(?:_?\d)*)?|0x[\da-fA-F](?:_?[\da-fA-F])*(?:\.[\da-fA-F](?:_?[\da-fA-D])*)?(?:[pP][+-]?\d(?:_?\d)*)?)\b|\binf\b|\bnan(?::0x[\da-fA-F](?:_?[\da-fA-D])*)?\b/,punctuation:/[()]/};const o=a},7459:(e,t,n)=>{"use strict";function r(e){var t,n,a="";if("string"==typeof e||"number"==typeof e)a+=e;else if("object"==typeof e)if(Array.isArray(e))for(t=0;ta});const a=function(){for(var e,t,n=0,a="";n{"use strict";n.d(t,{Z:()=>p});var r=n(7294),a=n(7462),o=n(8356),i=n.n(o),s=n(6887);const l={"04483a11":[()=>n.e(7054).then(n.bind(n,698)),"@site/../docs/target/jvm-2.13/mdoc/04-codegen/01-customisation/10-service-product.md",698],"0e4350a3":[()=>n.e(4027).then(n.bind(n,4252)),"@site/../docs/target/jvm-2.13/mdoc/06-guides/testing.md",4252],"14fe8e4c":[()=>n.e(7464).then(n.bind(n,2175)),"@site/../docs/target/jvm-2.13/mdoc/03-protocols/alloy.md",2175],"15cc563a":[()=>n.e(6998).then(n.bind(n,3580)),"@site/../docs/target/jvm-2.13/mdoc/03-protocols/03-aws/01-aws.md",3580],17896441:[()=>Promise.all([n.e(532),n.e(4464),n.e(7918)]).then(n.bind(n,5836)),"@theme/DocItem",5836],"1a7cad31":[()=>n.e(9813).then(n.bind(n,5021)),"@site/../docs/target/jvm-2.13/mdoc/02-the-smithy-idl/03-editor-support.md",5021],"1be78505":[()=>Promise.all([n.e(532),n.e(9514)]).then(n.bind(n,9963)),"@theme/DocPage",9963],"2bac9f7a":[()=>n.e(2491).then(n.bind(n,4770)),"@site/../docs/target/jvm-2.13/mdoc/03-protocols/04-simple-rest-json/02-server.md",4770],"30eed727":[()=>n.e(814).then(n.bind(n,9599)),"@site/../docs/target/jvm-2.13/mdoc/03-protocols/04-simple-rest-json/04-openapi.md",9599],"3a5a0a55":[()=>n.e(6672).then(n.bind(n,4809)),"@site/../docs/target/jvm-2.13/mdoc/04-codegen/02-unions.md",4809],"3c362096":[()=>n.e(653).then(n.bind(n,5990)),"@site/../docs/target/jvm-2.13/mdoc/03-protocols/02-definition.md",5990],"42969e2d":[()=>n.e(5157).then(n.bind(n,7549)),"@site/../docs/target/jvm-2.13/mdoc/04-codegen/03-default-values.md",7549],"46a2298c":[()=>n.e(7176).then(n.bind(n,7807)),"@site/../docs/target/jvm-2.13/mdoc/06-guides/endpoint-middleware.md",7807],"48a411d5":[()=>n.e(3812).then(n.bind(n,1962)),"@site/../docs/target/jvm-2.13/mdoc/04-codegen/01-customisation/12-open-enums.md",1962],"49bfe7c0":[()=>n.e(2298).then(n.bind(n,9856)),"@site/../docs/target/jvm-2.13/mdoc/06-guides/extract-request-info.md",9856],"4d02aadf":[()=>n.e(4444).then(n.bind(n,674)),"@site/../docs/target/jvm-2.13/mdoc/03-protocols/05-compliance-tests.md",674],"4f61a3d4":[()=>n.e(1868).then(n.bind(n,4339)),"@site/../docs/target/jvm-2.13/mdoc/04-codegen/01-customisation/11-optics.md",4339],"5e9f5e1a":[()=>Promise.resolve().then(n.bind(n,6809)),"@generated/docusaurus.config",6809],"64302c38":[()=>n.e(1328).then(n.bind(n,5827)),"@site/../docs/target/jvm-2.13/mdoc/07-credits.md",5827],"652787d8":[()=>n.e(994).then(n.bind(n,5390)),"@site/../docs/target/jvm-2.13/mdoc/01-overview/01-intro.md",5390],"67116a44":[()=>n.e(163).then(n.bind(n,783)),"@site/../docs/target/jvm-2.13/mdoc/06-guides/model-preprocessing.md",783],"733223eb":[()=>n.e(8343).then(n.bind(n,6283)),"@site/../docs/target/jvm-2.13/mdoc/04-codegen/01-customisation/07-error-unions.md",6283],"7aa64844":[()=>n.e(771).then(n.bind(n,5302)),"@site/../docs/target/jvm-2.13/mdoc/08-known-issues.md",5302],"814869ee":[()=>n.e(9855).then(n.bind(n,6886)),"@site/../docs/target/jvm-2.13/mdoc/01-overview/03-installation.md",6886],"85c02878":[()=>n.e(1823).then(n.bind(n,1742)),"@site/../docs/target/jvm-2.13/mdoc/04-codegen/01-customisation/06-default-rendering.md",1742],"895723b7":[()=>n.e(9754).then(n.bind(n,4883)),"@site/../docs/target/jvm-2.13/mdoc/04-codegen/01-customisation/03-collections.md",4883],"8b8da138":[()=>n.e(2167).then(n.bind(n,5635)),"@site/../docs/target/jvm-2.13/mdoc/04-codegen/01-customisation/13-nullable-values.md",5635],"8bc097d6":[()=>n.e(1562).then(n.bind(n,8520)),"@site/../docs/target/jvm-2.13/mdoc/01-overview/06-stubs.md",8520],92656677:[()=>n.e(4570).then(n.bind(n,141)),"@site/../docs/target/jvm-2.13/mdoc/05-design/01-design.md",141],"935f2afb":[()=>n.e(53).then(n.t.bind(n,1109,19)),"~docs/default/version-current-metadata-prop-751.json",1109],"93fd93c7":[()=>n.e(6157).then(n.bind(n,9113)),"@site/../docs/target/jvm-2.13/mdoc/04-codegen/01-customisation/05-unwrapping.md",9113],"9bbdc9ed":[()=>n.e(3533).then(n.bind(n,3341)),"@site/../docs/target/jvm-2.13/mdoc/01-overview/02-quickstart.md",3341],abaccda9:[()=>n.e(6123).then(n.bind(n,9089)),"@site/../docs/target/jvm-2.13/mdoc/03-protocols/03-aws/02-localstack.md",9089],abe01ffb:[()=>n.e(9905).then(n.bind(n,2884)),"@site/../docs/target/jvm-2.13/mdoc/05-design/03-services.md",2884],b04b9a17:[()=>n.e(2408).then(n.bind(n,6750)),"@site/../docs/target/jvm-2.13/mdoc/03-protocols/04-simple-rest-json/01-overview.md",6750],b089836d:[()=>n.e(9478).then(n.t.bind(n,5745,19)),"/home/runner/work/smithy4s/smithy4s/modules/website/.docusaurus/docusaurus-plugin-content-pages/default/plugin-route-context-module-100.json",5745],b839affd:[()=>n.e(6213).then(n.bind(n,67)),"@site/../docs/target/jvm-2.13/mdoc/04-codegen/01-customisation/09-typeclass.md",67],bb709d94:[()=>n.e(3459).then(n.bind(n,5261)),"@site/../docs/target/jvm-2.13/mdoc/06-guides/smithy4s-transformations.md",5261],c4f5d8e4:[()=>Promise.all([n.e(532),n.e(4464),n.e(4195)]).then(n.bind(n,6650)),"@site/src/pages/index.js",6650],ca30b741:[()=>n.e(2433).then(n.bind(n,3354)),"@site/../docs/target/jvm-2.13/mdoc/01-overview/05-sharing-specs.md",3354],caf0a613:[()=>n.e(19).then(n.bind(n,9930)),"@site/../docs/target/jvm-2.13/mdoc/02-the-smithy-idl/02-traits.md",9930],d0724809:[()=>n.e(343).then(n.bind(n,6382)),"@site/../docs/target/jvm-2.13/mdoc/04-codegen/01-customisation/02-adts.md",6382],d1e88da1:[()=>n.e(2314).then(n.bind(n,2121)),"@site/../docs/target/jvm-2.13/mdoc/02-the-smithy-idl/01-smithy-idl.md",2121],d2e0906e:[()=>n.e(2419).then(n.bind(n,6701)),"@site/../docs/target/jvm-2.13/mdoc/06-guides/dynamic.md",6701],d4cb2933:[()=>n.e(620).then(n.bind(n,7981)),"@site/../docs/target/jvm-2.13/mdoc/04-codegen/01-customisation/01-packed-inputs.md",7981],d7e6b40c:[()=>n.e(1201).then(n.t.bind(n,3769,19)),"/home/runner/work/smithy4s/smithy4s/modules/website/.docusaurus/docusaurus-plugin-content-docs/default/plugin-route-context-module-100.json",3769],d9ef954b:[()=>n.e(348).then(n.bind(n,4441)),"@site/../docs/target/jvm-2.13/mdoc/04-codegen/01-customisation/08-wildcard.md",4441],e00da59c:[()=>n.e(7326).then(n.bind(n,3422)),"@site/../docs/target/jvm-2.13/mdoc/05-design/02-schemas.md",3422],e339ddb9:[()=>n.e(6880).then(n.bind(n,9091)),"@site/../docs/target/jvm-2.13/mdoc/04-codegen/01-customisation/04-refinements.md",9091],e6282eb1:[()=>n.e(719).then(n.bind(n,2831)),"@site/../docs/target/jvm-2.13/mdoc/03-protocols/04-simple-rest-json/03-client.md",2831],e7cafe5a:[()=>n.e(2712).then(n.bind(n,7622)),"@site/../docs/target/jvm-2.13/mdoc/03-protocols/01-protocols.md",7622],e83d6da6:[()=>n.e(9475).then(n.bind(n,2033)),"@site/../docs/target/jvm-2.13/mdoc/09-learning-resources.md",2033],f410dc47:[()=>n.e(6849).then(n.bind(n,4135)),"@site/../docs/target/jvm-2.13/mdoc/03-protocols/06-deriving-cli.md",4135],fef3f155:[()=>n.e(918).then(n.bind(n,6822)),"@site/../docs/target/jvm-2.13/mdoc/01-overview/04-cli.md",6822]};function c(e){let{error:t,retry:n,pastDelay:a}=e;return t?r.createElement("div",{style:{textAlign:"center",color:"#fff",backgroundColor:"#fa383e",borderColor:"#fa383e",borderStyle:"solid",borderRadius:"0.25rem",borderWidth:"1px",boxSizing:"border-box",display:"block",padding:"1rem",flex:"0 0 50%",marginLeft:"25%",marginRight:"25%",marginTop:"5rem",maxWidth:"50%",width:"100%"}},r.createElement("p",null,String(t)),r.createElement("div",null,r.createElement("button",{type:"button",onClick:n},"Retry"))):a?r.createElement("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",height:"100vh"}},r.createElement("svg",{id:"loader",style:{width:128,height:110,position:"absolute",top:"calc(100vh - 64%)"},viewBox:"0 0 45 45",xmlns:"http://www.w3.org/2000/svg",stroke:"#61dafb"},r.createElement("g",{fill:"none",fillRule:"evenodd",transform:"translate(1 1)",strokeWidth:"2"},r.createElement("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0"},r.createElement("animate",{attributeName:"r",begin:"1.5s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-opacity",begin:"1.5s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-width",begin:"1.5s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})),r.createElement("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0"},r.createElement("animate",{attributeName:"r",begin:"3s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-opacity",begin:"3s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-width",begin:"3s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})),r.createElement("circle",{cx:"22",cy:"22",r:"8"},r.createElement("animate",{attributeName:"r",begin:"0s",dur:"1.5s",values:"6;1;2;3;4;5;6",calcMode:"linear",repeatCount:"indefinite"}))))):null}var u=n(9670),d=n(226);function f(e,t){if("*"===e)return i()({loading:c,loader:()=>n.e(4972).then(n.bind(n,4972)),modules:["@theme/NotFound"],webpack:()=>[4972],render(e,t){const n=e.default;return r.createElement(d.z,{value:{plugin:{name:"native",id:"default"}}},r.createElement(n,t))}});const o=s[`${e}-${t}`],f={},p=[],m=[],h=(0,u.Z)(o);return Object.entries(h).forEach((e=>{let[t,n]=e;const r=l[n];r&&(f[t]=r[0],p.push(r[1]),m.push(r[2]))})),i().Map({loading:c,loader:f,modules:p,webpack:()=>m,render(t,n){const i=JSON.parse(JSON.stringify(o));Object.entries(t).forEach((t=>{let[n,r]=t;const a=r.default;if(!a)throw new Error(`The page component at ${e} doesn't have a default export. This makes it impossible to render anything. Consider default-exporting a React component.`);"object"!=typeof a&&"function"!=typeof a||Object.keys(r).filter((e=>"default"!==e)).forEach((e=>{a[e]=r[e]}));let o=i;const s=n.split(".");s.slice(0,-1).forEach((e=>{o=o[e]})),o[s[s.length-1]]=a}));const s=i.__comp;delete i.__comp;const l=i.__context;return delete i.__context,r.createElement(d.z,{value:l},r.createElement(s,(0,a.Z)({},i,n)))}})}const p=[{path:"/smithy4s/docs",component:f("/smithy4s/docs","6cd"),routes:[{path:"/smithy4s/docs/codegen/customisation/adts",component:f("/smithy4s/docs/codegen/customisation/adts","e4d"),exact:!0,sidebar:"tutorialSidebar"},{path:"/smithy4s/docs/codegen/customisation/collections",component:f("/smithy4s/docs/codegen/customisation/collections","13d"),exact:!0,sidebar:"tutorialSidebar"},{path:"/smithy4s/docs/codegen/customisation/default-rendering",component:f("/smithy4s/docs/codegen/customisation/default-rendering","d17"),exact:!0,sidebar:"tutorialSidebar"},{path:"/smithy4s/docs/codegen/customisation/error-unions",component:f("/smithy4s/docs/codegen/customisation/error-unions","40f"),exact:!0,sidebar:"tutorialSidebar"},{path:"/smithy4s/docs/codegen/customisation/nullable-values",component:f("/smithy4s/docs/codegen/customisation/nullable-values","e31"),exact:!0,sidebar:"tutorialSidebar"},{path:"/smithy4s/docs/codegen/customisation/open-enums",component:f("/smithy4s/docs/codegen/customisation/open-enums","945"),exact:!0,sidebar:"tutorialSidebar"},{path:"/smithy4s/docs/codegen/customisation/optics",component:f("/smithy4s/docs/codegen/customisation/optics","250"),exact:!0,sidebar:"tutorialSidebar"},{path:"/smithy4s/docs/codegen/customisation/packed-inputs",component:f("/smithy4s/docs/codegen/customisation/packed-inputs","aeb"),exact:!0,sidebar:"tutorialSidebar"},{path:"/smithy4s/docs/codegen/customisation/refinements",component:f("/smithy4s/docs/codegen/customisation/refinements","c4e"),exact:!0,sidebar:"tutorialSidebar"},{path:"/smithy4s/docs/codegen/customisation/service-product",component:f("/smithy4s/docs/codegen/customisation/service-product","432"),exact:!0,sidebar:"tutorialSidebar"},{path:"/smithy4s/docs/codegen/customisation/typeclass",component:f("/smithy4s/docs/codegen/customisation/typeclass","702"),exact:!0,sidebar:"tutorialSidebar"},{path:"/smithy4s/docs/codegen/customisation/unwrapping",component:f("/smithy4s/docs/codegen/customisation/unwrapping","eb5"),exact:!0,sidebar:"tutorialSidebar"},{path:"/smithy4s/docs/codegen/customisation/wildcard",component:f("/smithy4s/docs/codegen/customisation/wildcard","119"),exact:!0,sidebar:"tutorialSidebar"},{path:"/smithy4s/docs/codegen/default-values",component:f("/smithy4s/docs/codegen/default-values","630"),exact:!0,sidebar:"tutorialSidebar"},{path:"/smithy4s/docs/codegen/unions",component:f("/smithy4s/docs/codegen/unions","2ae"),exact:!0,sidebar:"tutorialSidebar"},{path:"/smithy4s/docs/credits",component:f("/smithy4s/docs/credits","dee"),exact:!0,sidebar:"tutorialSidebar"},{path:"/smithy4s/docs/design/design",component:f("/smithy4s/docs/design/design","b60"),exact:!0,sidebar:"tutorialSidebar"},{path:"/smithy4s/docs/design/schemas",component:f("/smithy4s/docs/design/schemas","e67"),exact:!0,sidebar:"tutorialSidebar"},{path:"/smithy4s/docs/design/services",component:f("/smithy4s/docs/design/services","fc8"),exact:!0,sidebar:"tutorialSidebar"},{path:"/smithy4s/docs/guides/dynamic",component:f("/smithy4s/docs/guides/dynamic","0f7"),exact:!0,sidebar:"tutorialSidebar"},{path:"/smithy4s/docs/guides/endpoint-middleware",component:f("/smithy4s/docs/guides/endpoint-middleware","bf3"),exact:!0,sidebar:"tutorialSidebar"},{path:"/smithy4s/docs/guides/extract-request-info",component:f("/smithy4s/docs/guides/extract-request-info","c4f"),exact:!0,sidebar:"tutorialSidebar"},{path:"/smithy4s/docs/guides/model-preprocessing",component:f("/smithy4s/docs/guides/model-preprocessing","a6b"),exact:!0,sidebar:"tutorialSidebar"},{path:"/smithy4s/docs/guides/smithy4s-transformations",component:f("/smithy4s/docs/guides/smithy4s-transformations","8d3"),exact:!0,sidebar:"tutorialSidebar"},{path:"/smithy4s/docs/guides/testing",component:f("/smithy4s/docs/guides/testing","968"),exact:!0,sidebar:"tutorialSidebar"},{path:"/smithy4s/docs/known-issues",component:f("/smithy4s/docs/known-issues","26e"),exact:!0,sidebar:"tutorialSidebar"},{path:"/smithy4s/docs/learning-resources",component:f("/smithy4s/docs/learning-resources","35a"),exact:!0,sidebar:"tutorialSidebar"},{path:"/smithy4s/docs/overview/cli",component:f("/smithy4s/docs/overview/cli","182"),exact:!0,sidebar:"tutorialSidebar"},{path:"/smithy4s/docs/overview/installation",component:f("/smithy4s/docs/overview/installation","076"),exact:!0,sidebar:"tutorialSidebar"},{path:"/smithy4s/docs/overview/intro",component:f("/smithy4s/docs/overview/intro","20d"),exact:!0,sidebar:"tutorialSidebar"},{path:"/smithy4s/docs/overview/quickstart",component:f("/smithy4s/docs/overview/quickstart","5a6"),exact:!0,sidebar:"tutorialSidebar"},{path:"/smithy4s/docs/overview/sharing-specs",component:f("/smithy4s/docs/overview/sharing-specs","6bb"),exact:!0,sidebar:"tutorialSidebar"},{path:"/smithy4s/docs/overview/stubs",component:f("/smithy4s/docs/overview/stubs","673"),exact:!0,sidebar:"tutorialSidebar"},{path:"/smithy4s/docs/protocols/alloy",component:f("/smithy4s/docs/protocols/alloy","50e"),exact:!0,sidebar:"tutorialSidebar"},{path:"/smithy4s/docs/protocols/aws/aws",component:f("/smithy4s/docs/protocols/aws/aws","d52"),exact:!0,sidebar:"tutorialSidebar"},{path:"/smithy4s/docs/protocols/aws/localstack",component:f("/smithy4s/docs/protocols/aws/localstack","8c7"),exact:!0,sidebar:"tutorialSidebar"},{path:"/smithy4s/docs/protocols/compliance-tests",component:f("/smithy4s/docs/protocols/compliance-tests","3a1"),exact:!0,sidebar:"tutorialSidebar"},{path:"/smithy4s/docs/protocols/definition",component:f("/smithy4s/docs/protocols/definition","fa7"),exact:!0,sidebar:"tutorialSidebar"},{path:"/smithy4s/docs/protocols/deriving-cli",component:f("/smithy4s/docs/protocols/deriving-cli","9dc"),exact:!0,sidebar:"tutorialSidebar"},{path:"/smithy4s/docs/protocols/protocols",component:f("/smithy4s/docs/protocols/protocols","44c"),exact:!0,sidebar:"tutorialSidebar"},{path:"/smithy4s/docs/protocols/simple-rest-json/client",component:f("/smithy4s/docs/protocols/simple-rest-json/client","cdd"),exact:!0,sidebar:"tutorialSidebar"},{path:"/smithy4s/docs/protocols/simple-rest-json/openapi",component:f("/smithy4s/docs/protocols/simple-rest-json/openapi","e37"),exact:!0,sidebar:"tutorialSidebar"},{path:"/smithy4s/docs/protocols/simple-rest-json/overview",component:f("/smithy4s/docs/protocols/simple-rest-json/overview","631"),exact:!0,sidebar:"tutorialSidebar"},{path:"/smithy4s/docs/protocols/simple-rest-json/server",component:f("/smithy4s/docs/protocols/simple-rest-json/server","eaf"),exact:!0,sidebar:"tutorialSidebar"},{path:"/smithy4s/docs/the-smithy-idl/editor-support",component:f("/smithy4s/docs/the-smithy-idl/editor-support","20c"),exact:!0,sidebar:"tutorialSidebar"},{path:"/smithy4s/docs/the-smithy-idl/smithy-idl",component:f("/smithy4s/docs/the-smithy-idl/smithy-idl","098"),exact:!0,sidebar:"tutorialSidebar"},{path:"/smithy4s/docs/the-smithy-idl/traits",component:f("/smithy4s/docs/the-smithy-idl/traits","d30"),exact:!0,sidebar:"tutorialSidebar"}]},{path:"/smithy4s/",component:f("/smithy4s/","9ac"),exact:!0},{path:"*",component:f("*")}]},8934:(e,t,n)=>{"use strict";n.d(t,{_:()=>a,t:()=>o});var r=n(7294);const a=r.createContext(!1);function o(e){let{children:t}=e;const[n,o]=(0,r.useState)(!1);return(0,r.useEffect)((()=>{o(!0)}),[]),r.createElement(a.Provider,{value:n},t)}},7221:(e,t,n)=>{"use strict";var r=n(7294),a=n(3935),o=n(3727),i=n(405),s=n(412);const l=[n(2497),n(3310),n(8320),n(2295)];var c=n(723),u=n(6550),d=n(8790);function f(e){let{children:t}=e;return r.createElement(r.Fragment,null,t)}var p=n(7462),m=n(5742),h=n(2263),g=n(4996),v=n(6668),b=n(1944),y=n(4711),w=n(9727),E=n(3320),k=n(8780),S=n(197);function x(){const{i18n:{defaultLocale:e,localeConfigs:t}}=(0,h.Z)(),n=(0,y.l)();return r.createElement(m.Z,null,Object.entries(t).map((e=>{let[t,{htmlLang:a}]=e;return r.createElement("link",{key:t,rel:"alternate",href:n.createUrl({locale:t,fullyQualified:!0}),hrefLang:a})})),r.createElement("link",{rel:"alternate",href:n.createUrl({locale:e,fullyQualified:!0}),hrefLang:"x-default"}))}function _(e){let{permalink:t}=e;const{siteConfig:{url:n}}=(0,h.Z)(),a=function(){const{siteConfig:{url:e,baseUrl:t,trailingSlash:n}}=(0,h.Z)(),{pathname:r}=(0,u.TH)();return e+(0,k.applyTrailingSlash)((0,g.Z)(r),{trailingSlash:n,baseUrl:t})}(),o=t?`${n}${t}`:a;return r.createElement(m.Z,null,r.createElement("meta",{property:"og:url",content:o}),r.createElement("link",{rel:"canonical",href:o}))}function C(){const{i18n:{currentLocale:e}}=(0,h.Z)(),{metadata:t,image:n}=(0,v.L)();return r.createElement(r.Fragment,null,r.createElement(m.Z,null,r.createElement("meta",{name:"twitter:card",content:"summary_large_image"}),r.createElement("body",{className:w.h})),n&&r.createElement(b.d,{image:n}),r.createElement(_,null),r.createElement(x,null),r.createElement(S.Z,{tag:E.HX,locale:e}),r.createElement(m.Z,null,t.map(((e,t)=>r.createElement("meta",(0,p.Z)({key:t},e))))))}const T=new Map;function N(e){if(T.has(e.pathname))return{...e,pathname:T.get(e.pathname)};if((0,d.f)(c.Z,e.pathname).some((e=>{let{route:t}=e;return!0===t.exact})))return T.set(e.pathname,e.pathname),e;const t=e.pathname.trim().replace(/(?:\/index)?\.html$/,"")||"/";return T.set(e.pathname,t),{...e,pathname:t}}var A=n(8934),O=n(8940);function L(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r(t.default?.[e]??t[e])?.(...n)));return()=>a.forEach((e=>e?.()))}const I=function(e){let{children:t,location:n,previousLocation:a}=e;return(0,r.useLayoutEffect)((()=>{a!==n&&(!function(e){let{location:t,previousLocation:n}=e;if(!n)return;const r=t.pathname===n.pathname,a=t.hash===n.hash,o=t.search===n.search;if(r&&a&&!o)return;const{hash:i}=t;if(i){const e=decodeURIComponent(i.substring(1));document.getElementById(e)?.scrollIntoView()}else window.scrollTo(0,0)}({location:n,previousLocation:a}),L("onRouteDidUpdate",{previousLocation:a,location:n}))}),[a,n]),t};function P(e){const t=Array.from(new Set([e,decodeURI(e)])).map((e=>(0,d.f)(c.Z,e))).flat();return Promise.all(t.map((e=>e.route.component.preload?.())))}class R extends r.Component{constructor(e){super(e),this.previousLocation=void 0,this.routeUpdateCleanupCb=void 0,this.previousLocation=null,this.routeUpdateCleanupCb=s.Z.canUseDOM?L("onRouteUpdate",{previousLocation:null,location:this.props.location}):()=>{},this.state={nextRouteHasLoaded:!0}}shouldComponentUpdate(e,t){if(e.location===this.props.location)return t.nextRouteHasLoaded;const n=e.location;return this.previousLocation=this.props.location,this.setState({nextRouteHasLoaded:!1}),this.routeUpdateCleanupCb=L("onRouteUpdate",{previousLocation:this.previousLocation,location:n}),P(n.pathname).then((()=>{this.routeUpdateCleanupCb(),this.setState({nextRouteHasLoaded:!0})})).catch((e=>{console.warn(e),window.location.reload()})),!1}render(){const{children:e,location:t}=this.props;return r.createElement(I,{previousLocation:this.previousLocation,location:t},r.createElement(u.AW,{location:t,render:()=>e}))}}const M=R,D="__docusaurus-base-url-issue-banner-container",F="__docusaurus-base-url-issue-banner",B="__docusaurus-base-url-issue-banner-suggestion-container",j="__DOCUSAURUS_INSERT_BASEURL_BANNER";function $(e){return`\nwindow['${j}'] = true;\n\ndocument.addEventListener('DOMContentLoaded', maybeInsertBanner);\n\nfunction maybeInsertBanner() {\n var shouldInsert = window['${j}'];\n shouldInsert && insertBanner();\n}\n\nfunction insertBanner() {\n var bannerContainer = document.getElementById('${D}');\n if (!bannerContainer) {\n return;\n }\n var bannerHtml = ${JSON.stringify(function(e){return`\n
\n

Your Docusaurus site did not load properly.

\n

A very common reason is a wrong site baseUrl configuration.

\n

Current configured baseUrl = ${e} ${"/"===e?" (default value)":""}

\n

We suggest trying baseUrl =

\n
\n`}(e)).replace(/{window[j]=!1}),[]),r.createElement(r.Fragment,null,!s.Z.canUseDOM&&r.createElement(m.Z,null,r.createElement("script",null,$(e))),r.createElement("div",{id:D}))}function U(){const{siteConfig:{baseUrl:e,baseUrlIssueBanner:t}}=(0,h.Z)(),{pathname:n}=(0,u.TH)();return t&&n===e?r.createElement(z,null):null}function Z(){const{siteConfig:{favicon:e,title:t,noIndex:n},i18n:{currentLocale:a,localeConfigs:o}}=(0,h.Z)(),i=(0,g.Z)(e),{htmlLang:s,direction:l}=o[a];return r.createElement(m.Z,null,r.createElement("html",{lang:s,dir:l}),r.createElement("title",null,t),r.createElement("meta",{property:"og:title",content:t}),r.createElement("meta",{name:"viewport",content:"width=device-width, initial-scale=1.0"}),n&&r.createElement("meta",{name:"robots",content:"noindex, nofollow"}),e&&r.createElement("link",{rel:"icon",href:i}))}var H=n(4763),V=n(2389);function W(){const e=(0,V.Z)();return r.createElement(m.Z,null,r.createElement("html",{"data-has-hydrated":e}))}function G(){const e=(0,d.H)(c.Z),t=(0,u.TH)();return r.createElement(H.Z,null,r.createElement(O.M,null,r.createElement(A.t,null,r.createElement(f,null,r.createElement(Z,null),r.createElement(C,null),r.createElement(U,null),r.createElement(M,{location:N(t)},e)),r.createElement(W,null))))}var q=n(6887);const Y=function(e){try{return document.createElement("link").relList.supports(e)}catch{return!1}}("prefetch")?function(e){return new Promise(((t,n)=>{if("undefined"==typeof document)return void n();const r=document.createElement("link");r.setAttribute("rel","prefetch"),r.setAttribute("href",e),r.onload=()=>t(),r.onerror=()=>n();(document.getElementsByTagName("head")[0]??document.getElementsByName("script")[0]?.parentNode)?.appendChild(r)}))}:function(e){return new Promise(((t,n)=>{const r=new XMLHttpRequest;r.open("GET",e,!0),r.withCredentials=!0,r.onload=()=>{200===r.status?t():n()},r.send(null)}))};var K=n(9670);const X=new Set,Q=new Set,J=()=>navigator.connection?.effectiveType.includes("2g")||navigator.connection?.saveData,ee={prefetch(e){if(!(e=>!J()&&!Q.has(e)&&!X.has(e))(e))return!1;X.add(e);const t=(0,d.f)(c.Z,e).flatMap((e=>{return t=e.route.path,Object.entries(q).filter((e=>{let[n]=e;return n.replace(/-[^-]+$/,"")===t})).flatMap((e=>{let[,t]=e;return Object.values((0,K.Z)(t))}));var t}));return Promise.all(t.map((e=>{const t=n.gca(e);return t&&!t.includes("undefined")?Y(t).catch((()=>{})):Promise.resolve()})))},preload:e=>!!(e=>!J()&&!Q.has(e))(e)&&(Q.add(e),P(e))},te=Object.freeze(ee);if(s.Z.canUseDOM){window.docusaurus=te;const e=a.hydrate;P(window.location.pathname).then((()=>{e(r.createElement(i.B6,null,r.createElement(o.VK,null,r.createElement(G,null))),document.getElementById("__docusaurus"))}))}},8940:(e,t,n)=>{"use strict";n.d(t,{_:()=>u,M:()=>d});var r=n(7294),a=n(6809);const o=JSON.parse('{"docusaurus-lunr-search":{"default":{"fileNames":{"searchDoc":"search-doc-1709043436862.json","lunrIndex":"lunr-index-1709043436862.json"}}},"docusaurus-plugin-content-docs":{"default":{"path":"/smithy4s/docs","versions":[{"name":"current","label":"Next","isLast":true,"path":"/smithy4s/docs","mainDocId":"overview/intro","docs":[{"id":"codegen/customisation/adts","path":"/smithy4s/docs/codegen/customisation/adts","sidebar":"tutorialSidebar"},{"id":"codegen/customisation/collections","path":"/smithy4s/docs/codegen/customisation/collections","sidebar":"tutorialSidebar"},{"id":"codegen/customisation/default-rendering","path":"/smithy4s/docs/codegen/customisation/default-rendering","sidebar":"tutorialSidebar"},{"id":"codegen/customisation/error-unions","path":"/smithy4s/docs/codegen/customisation/error-unions","sidebar":"tutorialSidebar"},{"id":"codegen/customisation/nullable-values","path":"/smithy4s/docs/codegen/customisation/nullable-values","sidebar":"tutorialSidebar"},{"id":"codegen/customisation/open-enums","path":"/smithy4s/docs/codegen/customisation/open-enums","sidebar":"tutorialSidebar"},{"id":"codegen/customisation/optics","path":"/smithy4s/docs/codegen/customisation/optics","sidebar":"tutorialSidebar"},{"id":"codegen/customisation/packed-inputs","path":"/smithy4s/docs/codegen/customisation/packed-inputs","sidebar":"tutorialSidebar"},{"id":"codegen/customisation/refinements","path":"/smithy4s/docs/codegen/customisation/refinements","sidebar":"tutorialSidebar"},{"id":"codegen/customisation/service-product","path":"/smithy4s/docs/codegen/customisation/service-product","sidebar":"tutorialSidebar"},{"id":"codegen/customisation/typeclass","path":"/smithy4s/docs/codegen/customisation/typeclass","sidebar":"tutorialSidebar"},{"id":"codegen/customisation/unwrapping","path":"/smithy4s/docs/codegen/customisation/unwrapping","sidebar":"tutorialSidebar"},{"id":"codegen/customisation/wildcard","path":"/smithy4s/docs/codegen/customisation/wildcard","sidebar":"tutorialSidebar"},{"id":"codegen/default-values","path":"/smithy4s/docs/codegen/default-values","sidebar":"tutorialSidebar"},{"id":"codegen/unions","path":"/smithy4s/docs/codegen/unions","sidebar":"tutorialSidebar"},{"id":"credits","path":"/smithy4s/docs/credits","sidebar":"tutorialSidebar"},{"id":"design/design","path":"/smithy4s/docs/design/design","sidebar":"tutorialSidebar"},{"id":"design/schemas","path":"/smithy4s/docs/design/schemas","sidebar":"tutorialSidebar"},{"id":"design/services","path":"/smithy4s/docs/design/services","sidebar":"tutorialSidebar"},{"id":"guides/dynamic","path":"/smithy4s/docs/guides/dynamic","sidebar":"tutorialSidebar"},{"id":"guides/endpoint-middleware","path":"/smithy4s/docs/guides/endpoint-middleware","sidebar":"tutorialSidebar"},{"id":"guides/extract-request-info","path":"/smithy4s/docs/guides/extract-request-info","sidebar":"tutorialSidebar"},{"id":"guides/model-preprocessing","path":"/smithy4s/docs/guides/model-preprocessing","sidebar":"tutorialSidebar"},{"id":"guides/smithy4s-transformations","path":"/smithy4s/docs/guides/smithy4s-transformations","sidebar":"tutorialSidebar"},{"id":"guides/testing","path":"/smithy4s/docs/guides/testing","sidebar":"tutorialSidebar"},{"id":"known-issues","path":"/smithy4s/docs/known-issues","sidebar":"tutorialSidebar"},{"id":"learning-resources","path":"/smithy4s/docs/learning-resources","sidebar":"tutorialSidebar"},{"id":"overview/cli","path":"/smithy4s/docs/overview/cli","sidebar":"tutorialSidebar"},{"id":"overview/installation","path":"/smithy4s/docs/overview/installation","sidebar":"tutorialSidebar"},{"id":"overview/intro","path":"/smithy4s/docs/overview/intro","sidebar":"tutorialSidebar"},{"id":"overview/quickstart","path":"/smithy4s/docs/overview/quickstart","sidebar":"tutorialSidebar"},{"id":"overview/sharing-specs","path":"/smithy4s/docs/overview/sharing-specs","sidebar":"tutorialSidebar"},{"id":"overview/stubs","path":"/smithy4s/docs/overview/stubs","sidebar":"tutorialSidebar"},{"id":"protocols/alloy","path":"/smithy4s/docs/protocols/alloy","sidebar":"tutorialSidebar"},{"id":"protocols/aws/aws","path":"/smithy4s/docs/protocols/aws/aws","sidebar":"tutorialSidebar"},{"id":"protocols/aws/localstack","path":"/smithy4s/docs/protocols/aws/localstack","sidebar":"tutorialSidebar"},{"id":"protocols/compliance-tests","path":"/smithy4s/docs/protocols/compliance-tests","sidebar":"tutorialSidebar"},{"id":"protocols/definition","path":"/smithy4s/docs/protocols/definition","sidebar":"tutorialSidebar"},{"id":"protocols/deriving-cli","path":"/smithy4s/docs/protocols/deriving-cli","sidebar":"tutorialSidebar"},{"id":"protocols/protocols","path":"/smithy4s/docs/protocols/protocols","sidebar":"tutorialSidebar"},{"id":"protocols/simple-rest-json/client","path":"/smithy4s/docs/protocols/simple-rest-json/client","sidebar":"tutorialSidebar"},{"id":"protocols/simple-rest-json/openapi","path":"/smithy4s/docs/protocols/simple-rest-json/openapi","sidebar":"tutorialSidebar"},{"id":"protocols/simple-rest-json/overview","path":"/smithy4s/docs/protocols/simple-rest-json/overview","sidebar":"tutorialSidebar"},{"id":"protocols/simple-rest-json/server","path":"/smithy4s/docs/protocols/simple-rest-json/server","sidebar":"tutorialSidebar"},{"id":"the-smithy-idl/editor-support","path":"/smithy4s/docs/the-smithy-idl/editor-support","sidebar":"tutorialSidebar"},{"id":"the-smithy-idl/smithy-idl","path":"/smithy4s/docs/the-smithy-idl/smithy-idl","sidebar":"tutorialSidebar"},{"id":"the-smithy-idl/traits","path":"/smithy4s/docs/the-smithy-idl/traits","sidebar":"tutorialSidebar"}],"draftIds":[],"sidebars":{"tutorialSidebar":{"link":{"path":"/smithy4s/docs/overview/intro","label":"Intro"}}}}],"breadcrumbs":true}}}'),i=JSON.parse('{"defaultLocale":"en","locales":["en"],"path":"i18n","currentLocale":"en","localeConfigs":{"en":{"label":"English","direction":"ltr","htmlLang":"en","calendar":"gregory","path":"en"}}}');var s=n(7529);const l=JSON.parse('{"docusaurusVersion":"2.4.3","siteVersion":"0.0.0","pluginVersions":{"docusaurus-plugin-content-docs":{"type":"package","name":"@docusaurus/plugin-content-docs","version":"2.4.3"},"docusaurus-plugin-content-pages":{"type":"package","name":"@docusaurus/plugin-content-pages","version":"2.4.3"},"docusaurus-plugin-sitemap":{"type":"package","name":"@docusaurus/plugin-sitemap","version":"2.4.3"},"docusaurus-theme-classic":{"type":"package","name":"@docusaurus/theme-classic","version":"2.4.3"},"docusaurus-lunr-search":{"type":"package","name":"docusaurus-lunr-search","version":"3.2.0"}}}'),c={siteConfig:a.default,siteMetadata:l,globalData:o,i18n:i,codeTranslations:s},u=r.createContext(c);function d(e){let{children:t}=e;return r.createElement(u.Provider,{value:c},t)}},4763:(e,t,n)=>{"use strict";n.d(t,{Z:()=>f});var r=n(7294),a=n(412),o=n(5742),i=n(8780),s=n(7590);function l(e){let{error:t,tryAgain:n}=e;return r.createElement("div",{style:{display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"flex-start",minHeight:"100vh",width:"100%",maxWidth:"80ch",fontSize:"20px",margin:"0 auto",padding:"1rem"}},r.createElement("h1",{style:{fontSize:"3rem"}},"This page crashed"),r.createElement("button",{type:"button",onClick:n,style:{margin:"1rem 0",fontSize:"2rem",cursor:"pointer",borderRadius:20,padding:"1rem"}},"Try again"),r.createElement(c,{error:t}))}function c(e){let{error:t}=e;const n=(0,i.getErrorCausalChain)(t).map((e=>e.message)).join("\n\nCause:\n");return r.createElement("p",{style:{whiteSpace:"pre-wrap"}},n)}function u(e){let{error:t,tryAgain:n}=e;return r.createElement(f,{fallback:()=>r.createElement(l,{error:t,tryAgain:n})},r.createElement(o.Z,null,r.createElement("title",null,"Page Error")),r.createElement(s.Z,null,r.createElement(l,{error:t,tryAgain:n})))}const d=e=>r.createElement(u,e);class f extends r.Component{constructor(e){super(e),this.state={error:null}}componentDidCatch(e){a.Z.canUseDOM&&this.setState({error:e})}render(){const{children:e}=this.props,{error:t}=this.state;if(t){const e={error:t,tryAgain:()=>this.setState({error:null})};return(this.props.fallback??d)(e)}return e??null}}},412:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});const r="undefined"!=typeof window&&"document"in window&&"createElement"in window.document,a={canUseDOM:r,canUseEventListeners:r&&("addEventListener"in window||"attachEvent"in window),canUseIntersectionObserver:r&&"IntersectionObserver"in window,canUseViewport:r&&"screen"in window}},5742:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(7294),a=n(405);function o(e){return r.createElement(a.ql,e)}},9960:(e,t,n)=>{"use strict";n.d(t,{Z:()=>h});var r=n(7462),a=n(7294),o=n(3727),i=n(8780),s=n(2263),l=n(3919),c=n(412);const u=a.createContext({collectLink:()=>{}}),d=()=>(0,a.useContext)(u);var f=n(4996);const p=e=>e.startsWith("/");function m(e,t){let{isNavLink:n,to:u,href:m,activeClassName:h,isActive:g,"data-noBrokenLinkCheck":v,autoAddBaseUrl:b=!0,...y}=e;const{siteConfig:{trailingSlash:w,baseUrl:E}}=(0,s.Z)(),{withBaseUrl:k}=(0,f.C)(),S=d(),x=(0,a.useRef)(null);(0,a.useImperativeHandle)(t,(()=>x.current));const _=u||m;const C=(0,l.Z)(_),T=_?.replace("pathname://","");let N=void 0!==T?(A=T,b&&p(A)?k(A):A):void 0;var A;N&&C&&(N=(0,i.applyTrailingSlash)(N,{trailingSlash:w,baseUrl:E}));const O=(0,a.useRef)(!1),L=n?o.OL:o.rU,I=c.Z.canUseIntersectionObserver,P=(0,a.useRef)(),R=()=>{O.current||null==N||(window.docusaurus.preload(N),O.current=!0)};(0,a.useEffect)((()=>(!I&&C&&null!=N&&window.docusaurus.prefetch(N),()=>{I&&P.current&&P.current.disconnect()})),[P,N,I,C]);const M=N?.startsWith("#")??!1,D=!N||!C||M;return D||v||S.collectLink(N),D?a.createElement("a",(0,r.Z)({ref:x,href:N},_&&!C&&{target:"_blank",rel:"noopener noreferrer"},y)):a.createElement(L,(0,r.Z)({},y,{onMouseEnter:R,onTouchStart:R,innerRef:e=>{x.current=e,I&&e&&C&&(P.current=new window.IntersectionObserver((t=>{t.forEach((t=>{e===t.target&&(t.isIntersecting||t.intersectionRatio>0)&&(P.current.unobserve(e),P.current.disconnect(),null!=N&&window.docusaurus.prefetch(N))}))})),P.current.observe(e))},to:N},n&&{isActive:g,activeClassName:h}))}const h=a.forwardRef(m)},5999:(e,t,n)=>{"use strict";n.d(t,{Z:()=>l,I:()=>s});var r=n(7294);function a(e,t){const n=e.split(/(\{\w+\})/).map(((e,n)=>{if(n%2==1){const n=t?.[e.slice(1,-1)];if(void 0!==n)return n}return e}));return n.some((e=>(0,r.isValidElement)(e)))?n.map(((e,t)=>(0,r.isValidElement)(e)?r.cloneElement(e,{key:t}):e)).filter((e=>""!==e)):n.join("")}var o=n(7529);function i(e){let{id:t,message:n}=e;if(void 0===t&&void 0===n)throw new Error("Docusaurus translation declarations must have at least a translation id or a default translation message");return o[t??n]??n??t}function s(e,t){let{message:n,id:r}=e;return a(i({message:n,id:r}),t)}function l(e){let{children:t,id:n,values:o}=e;if(t&&"string"!=typeof t)throw console.warn("Illegal children",t),new Error("The Docusaurus component only accept simple string values");const s=i({message:t,id:n});return r.createElement(r.Fragment,null,a(s,o))}},9935:(e,t,n)=>{"use strict";n.d(t,{m:()=>r});const r="default"},3919:(e,t,n)=>{"use strict";function r(e){return/^(?:\w*:|\/\/)/.test(e)}function a(e){return void 0!==e&&!r(e)}n.d(t,{Z:()=>a,b:()=>r})},4996:(e,t,n)=>{"use strict";n.d(t,{C:()=>i,Z:()=>s});var r=n(7294),a=n(2263),o=n(3919);function i(){const{siteConfig:{baseUrl:e,url:t}}=(0,a.Z)(),n=(0,r.useCallback)(((n,r)=>function(e,t,n,r){let{forcePrependBaseUrl:a=!1,absolute:i=!1}=void 0===r?{}:r;if(!n||n.startsWith("#")||(0,o.b)(n))return n;if(a)return t+n.replace(/^\//,"");if(n===t.replace(/\/$/,""))return t;const s=n.startsWith(t)?n:t+n.replace(/^\//,"");return i?e+s:s}(t,e,n,r)),[t,e]);return{withBaseUrl:n}}function s(e,t){void 0===t&&(t={});const{withBaseUrl:n}=i();return n(e,t)}},2263:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(7294),a=n(8940);function o(){return(0,r.useContext)(a._)}},8084:(e,t,n)=>{"use strict";n.d(t,{OD:()=>o,eZ:()=>i});var r=n(2263),a=n(9935);function o(e,t){void 0===t&&(t={});const n=function(){const{globalData:e}=(0,r.Z)();return e}()[e];if(!n&&t.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin.`);return n}function i(e,t,n){void 0===t&&(t=a.m),void 0===n&&(n={});const r=o(e)?.[t];if(!r&&n.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin with id "${t}".`);return r}},2389:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(7294),a=n(8934);function o(){return(0,r.useContext)(a._)}},9670:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});const r=e=>"object"==typeof e&&!!e&&Object.keys(e).length>0;function a(e){const t=".",n={};return function e(a,o){Object.entries(a).forEach((a=>{let[i,s]=a;const l=o?`${o}${t}${i}`:i;r(s)?e(s,l):n[l]=s}))}(e),n}},226:(e,t,n)=>{"use strict";n.d(t,{_:()=>a,z:()=>o});var r=n(7294);const a=r.createContext(null);function o(e){let{children:t,value:n}=e;const o=r.useContext(a),i=(0,r.useMemo)((()=>function(e){let{parent:t,value:n}=e;if(!t){if(!n)throw new Error("Unexpected: no Docusaurus route context found");if(!("plugin"in n))throw new Error("Unexpected: Docusaurus topmost route context has no `plugin` attribute");return n}const r={...t.data,...n?.data};return{plugin:t.plugin,data:r}}({parent:o,value:n})),[o,n]);return r.createElement(a.Provider,{value:i},t)}},4104:(e,t,n)=>{"use strict";n.d(t,{Iw:()=>p,gA:()=>u,_r:()=>l,Jo:()=>m,zh:()=>c,yW:()=>f,gB:()=>d});var r=n(6550),a=n(8084);const o=e=>e.versions.find((e=>e.isLast));function i(e,t){const n=function(e,t){const n=o(e);return[...e.versions.filter((e=>e!==n)),n].find((e=>!!(0,r.LX)(t,{path:e.path,exact:!1,strict:!1})))}(e,t),a=n?.docs.find((e=>!!(0,r.LX)(t,{path:e.path,exact:!0,strict:!1})));return{activeVersion:n,activeDoc:a,alternateDocVersions:a?function(t){const n={};return e.versions.forEach((e=>{e.docs.forEach((r=>{r.id===t&&(n[e.name]=r)}))})),n}(a.id):{}}}const s={},l=()=>(0,a.OD)("docusaurus-plugin-content-docs")??s,c=e=>(0,a.eZ)("docusaurus-plugin-content-docs",e,{failfast:!0});function u(e){void 0===e&&(e={});const t=l(),{pathname:n}=(0,r.TH)();return function(e,t,n){void 0===n&&(n={});const a=Object.entries(e).sort(((e,t)=>t[1].path.localeCompare(e[1].path))).find((e=>{let[,n]=e;return!!(0,r.LX)(t,{path:n.path,exact:!1,strict:!1})})),o=a?{pluginId:a[0],pluginData:a[1]}:void 0;if(!o&&n.failfast)throw new Error(`Can't find active docs plugin for "${t}" pathname, while it was expected to be found. Maybe you tried to use a docs feature that can only be used on a docs-related page? Existing docs plugin paths are: ${Object.values(e).map((e=>e.path)).join(", ")}`);return o}(t,n,e)}function d(e){return c(e).versions}function f(e){const t=c(e);return o(t)}function p(e){const t=c(e),{pathname:n}=(0,r.TH)();return i(t,n)}function m(e){const t=c(e),{pathname:n}=(0,r.TH)();return function(e,t){const n=o(e);return{latestDocSuggestion:i(e,t).alternateDocVersions[n.name],latestVersionSuggestion:n}}(t,n)}},8320:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>o});var r=n(4865),a=n.n(r);a().configure({showSpinner:!1});const o={onRouteUpdate(e){let{location:t,previousLocation:n}=e;if(n&&t.pathname!==n.pathname){const e=window.setTimeout((()=>{a().start()}),200);return()=>window.clearTimeout(e)}},onRouteDidUpdate(){a().done()}}},3310:(e,t,n)=>{"use strict";n.r(t);var r=n(1205),a=n(6809);!function(e){const{themeConfig:{prism:t}}=a.default,{additionalLanguages:r}=t;globalThis.Prism=e,r.forEach((e=>{n(8296)(`./prism-${e}`)})),delete globalThis.Prism}(r.Z)},9471:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(7294);const a={iconExternalLink:"iconExternalLink_nPIU"};function o(e){let{width:t=13.5,height:n=13.5}=e;return r.createElement("svg",{width:t,height:n,"aria-hidden":"true",viewBox:"0 0 24 24",className:a.iconExternalLink},r.createElement("path",{fill:"currentColor",d:"M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"}))}},7590:(e,t,n)=>{"use strict";n.d(t,{Z:()=>yt});var r=n(7294),a=n(4334),o=n(4763),i=n(1944),s=n(7462),l=n(6550),c=n(5999),u=n(5936);const d="__docusaurus_skipToContent_fallback";function f(e){e.setAttribute("tabindex","-1"),e.focus(),e.removeAttribute("tabindex")}function p(){const e=(0,r.useRef)(null),{action:t}=(0,l.k6)(),n=(0,r.useCallback)((e=>{e.preventDefault();const t=document.querySelector("main:first-of-type")??document.getElementById(d);t&&f(t)}),[]);return(0,u.S)((n=>{let{location:r}=n;e.current&&!r.hash&&"PUSH"===t&&f(e.current)})),{containerRef:e,onClick:n}}const m=(0,c.I)({id:"theme.common.skipToMainContent",description:"The skip to content label used for accessibility, allowing to rapidly navigate to main content with keyboard tab/enter navigation",message:"Skip to main content"});function h(e){const t=e.children??m,{containerRef:n,onClick:a}=p();return r.createElement("div",{ref:n,role:"region","aria-label":m},r.createElement("a",(0,s.Z)({},e,{href:`#${d}`,onClick:a}),t))}var g=n(5281),v=n(9727);const b={skipToContent:"skipToContent_fXgn"};function y(){return r.createElement(h,{className:b.skipToContent})}var w=n(6668),E=n(9689);function k(e){let{width:t=21,height:n=21,color:a="currentColor",strokeWidth:o=1.2,className:i,...l}=e;return r.createElement("svg",(0,s.Z)({viewBox:"0 0 15 15",width:t,height:n},l),r.createElement("g",{stroke:a,strokeWidth:o},r.createElement("path",{d:"M.75.75l13.5 13.5M14.25.75L.75 14.25"})))}const S={closeButton:"closeButton_CVFx"};function x(e){return r.createElement("button",(0,s.Z)({type:"button","aria-label":(0,c.I)({id:"theme.AnnouncementBar.closeButtonAriaLabel",message:"Close",description:"The ARIA label for close button of announcement bar"})},e,{className:(0,a.Z)("clean-btn close",S.closeButton,e.className)}),r.createElement(k,{width:14,height:14,strokeWidth:3.1}))}const _={content:"content_knG7"};function C(e){const{announcementBar:t}=(0,w.L)(),{content:n}=t;return r.createElement("div",(0,s.Z)({},e,{className:(0,a.Z)(_.content,e.className),dangerouslySetInnerHTML:{__html:n}}))}const T={announcementBar:"announcementBar_mb4j",announcementBarPlaceholder:"announcementBarPlaceholder_vyr4",announcementBarClose:"announcementBarClose_gvF7",announcementBarContent:"announcementBarContent_xLdY"};function N(){const{announcementBar:e}=(0,w.L)(),{isActive:t,close:n}=(0,E.nT)();if(!t)return null;const{backgroundColor:a,textColor:o,isCloseable:i}=e;return r.createElement("div",{className:T.announcementBar,style:{backgroundColor:a,color:o},role:"banner"},i&&r.createElement("div",{className:T.announcementBarPlaceholder}),r.createElement(C,{className:T.announcementBarContent}),i&&r.createElement(x,{onClick:n,className:T.announcementBarClose}))}var A=n(2961),O=n(2466);var L=n(902),I=n(3102);const P=r.createContext(null);function R(e){let{children:t}=e;const n=function(){const e=(0,A.e)(),t=(0,I.HY)(),[n,a]=(0,r.useState)(!1),o=null!==t.component,i=(0,L.D9)(o);return(0,r.useEffect)((()=>{o&&!i&&a(!0)}),[o,i]),(0,r.useEffect)((()=>{o?e.shown||a(!0):a(!1)}),[e.shown,o]),(0,r.useMemo)((()=>[n,a]),[n])}();return r.createElement(P.Provider,{value:n},t)}function M(e){if(e.component){const t=e.component;return r.createElement(t,e.props)}}function D(){const e=(0,r.useContext)(P);if(!e)throw new L.i6("NavbarSecondaryMenuDisplayProvider");const[t,n]=e,a=(0,r.useCallback)((()=>n(!1)),[n]),o=(0,I.HY)();return(0,r.useMemo)((()=>({shown:t,hide:a,content:M(o)})),[a,o,t])}function F(e){let{header:t,primaryMenu:n,secondaryMenu:o}=e;const{shown:i}=D();return r.createElement("div",{className:"navbar-sidebar"},t,r.createElement("div",{className:(0,a.Z)("navbar-sidebar__items",{"navbar-sidebar__items--show-secondary":i})},r.createElement("div",{className:"navbar-sidebar__item menu"},n),r.createElement("div",{className:"navbar-sidebar__item menu"},o)))}var B=n(2949),j=n(2389);function $(e){return r.createElement("svg",(0,s.Z)({viewBox:"0 0 24 24",width:24,height:24},e),r.createElement("path",{fill:"currentColor",d:"M12,9c1.65,0,3,1.35,3,3s-1.35,3-3,3s-3-1.35-3-3S10.35,9,12,9 M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5 S14.76,7,12,7L12,7z M2,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S1.45,13,2,13z M20,13l2,0c0.55,0,1-0.45,1-1 s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S19.45,13,20,13z M11,2v2c0,0.55,0.45,1,1,1s1-0.45,1-1V2c0-0.55-0.45-1-1-1S11,1.45,11,2z M11,20v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2c0-0.55-0.45-1-1-1C11.45,19,11,19.45,11,20z M5.99,4.58c-0.39-0.39-1.03-0.39-1.41,0 c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0s0.39-1.03,0-1.41L5.99,4.58z M18.36,16.95 c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0c0.39-0.39,0.39-1.03,0-1.41 L18.36,16.95z M19.42,5.99c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41 s1.03,0.39,1.41,0L19.42,5.99z M7.05,18.36c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06 c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L7.05,18.36z"}))}function z(e){return r.createElement("svg",(0,s.Z)({viewBox:"0 0 24 24",width:24,height:24},e),r.createElement("path",{fill:"currentColor",d:"M9.37,5.51C9.19,6.15,9.1,6.82,9.1,7.5c0,4.08,3.32,7.4,7.4,7.4c0.68,0,1.35-0.09,1.99-0.27C17.45,17.19,14.93,19,12,19 c-3.86,0-7-3.14-7-7C5,9.07,6.81,6.55,9.37,5.51z M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36 c-0.98,1.37-2.58,2.26-4.4,2.26c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z"}))}const U={toggle:"toggle_vylO",toggleButton:"toggleButton_gllP",darkToggleIcon:"darkToggleIcon_wfgR",lightToggleIcon:"lightToggleIcon_pyhR",toggleButtonDisabled:"toggleButtonDisabled_aARS"};function Z(e){let{className:t,buttonClassName:n,value:o,onChange:i}=e;const s=(0,j.Z)(),l=(0,c.I)({message:"Switch between dark and light mode (currently {mode})",id:"theme.colorToggle.ariaLabel",description:"The ARIA label for the navbar color mode toggle"},{mode:"dark"===o?(0,c.I)({message:"dark mode",id:"theme.colorToggle.ariaLabel.mode.dark",description:"The name for the dark color mode"}):(0,c.I)({message:"light mode",id:"theme.colorToggle.ariaLabel.mode.light",description:"The name for the light color mode"})});return r.createElement("div",{className:(0,a.Z)(U.toggle,t)},r.createElement("button",{className:(0,a.Z)("clean-btn",U.toggleButton,!s&&U.toggleButtonDisabled,n),type:"button",onClick:()=>i("dark"===o?"light":"dark"),disabled:!s,title:l,"aria-label":l,"aria-live":"polite"},r.createElement($,{className:(0,a.Z)(U.toggleIcon,U.lightToggleIcon)}),r.createElement(z,{className:(0,a.Z)(U.toggleIcon,U.darkToggleIcon)})))}const H=r.memo(Z),V={darkNavbarColorModeToggle:"darkNavbarColorModeToggle_X3D1"};function W(e){let{className:t}=e;const n=(0,w.L)().navbar.style,a=(0,w.L)().colorMode.disableSwitch,{colorMode:o,setColorMode:i}=(0,B.I)();return a?null:r.createElement(H,{className:t,buttonClassName:"dark"===n?V.darkNavbarColorModeToggle:void 0,value:o,onChange:i})}var G=n(1327);function q(){return r.createElement(G.Z,{className:"navbar__brand",imageClassName:"navbar__logo",titleClassName:"navbar__title text--truncate"})}function Y(){const e=(0,A.e)();return r.createElement("button",{type:"button","aria-label":(0,c.I)({id:"theme.docs.sidebar.closeSidebarButtonAriaLabel",message:"Close navigation bar",description:"The ARIA label for close button of mobile sidebar"}),className:"clean-btn navbar-sidebar__close",onClick:()=>e.toggle()},r.createElement(k,{color:"var(--ifm-color-emphasis-600)"}))}function K(){return r.createElement("div",{className:"navbar-sidebar__brand"},r.createElement(q,null),r.createElement(W,{className:"margin-right--md"}),r.createElement(Y,null))}var X=n(9960),Q=n(4996),J=n(3919);function ee(e,t){return void 0!==e&&void 0!==t&&new RegExp(e,"gi").test(t)}var te=n(9471);function ne(e){let{activeBasePath:t,activeBaseRegex:n,to:a,href:o,label:i,html:l,isDropdownLink:c,prependBaseUrlToHref:u,...d}=e;const f=(0,Q.Z)(a),p=(0,Q.Z)(t),m=(0,Q.Z)(o,{forcePrependBaseUrl:!0}),h=i&&o&&!(0,J.Z)(o),g=l?{dangerouslySetInnerHTML:{__html:l}}:{children:r.createElement(r.Fragment,null,i,h&&r.createElement(te.Z,c&&{width:12,height:12}))};return o?r.createElement(X.Z,(0,s.Z)({href:u?m:o},d,g)):r.createElement(X.Z,(0,s.Z)({to:f,isNavLink:!0},(t||n)&&{isActive:(e,t)=>n?ee(n,t.pathname):t.pathname.startsWith(p)},d,g))}function re(e){let{className:t,isDropdownItem:n=!1,...o}=e;const i=r.createElement(ne,(0,s.Z)({className:(0,a.Z)(n?"dropdown__link":"navbar__item navbar__link",t),isDropdownLink:n},o));return n?r.createElement("li",null,i):i}function ae(e){let{className:t,isDropdownItem:n,...o}=e;return r.createElement("li",{className:"menu__list-item"},r.createElement(ne,(0,s.Z)({className:(0,a.Z)("menu__link",t)},o)))}function oe(e){let{mobile:t=!1,position:n,...a}=e;const o=t?ae:re;return r.createElement(o,(0,s.Z)({},a,{activeClassName:a.activeClassName??(t?"menu__link--active":"navbar__link--active")}))}var ie=n(6043),se=n(8596),le=n(2263);function ce(e,t){return e.some((e=>function(e,t){return!!(0,se.Mg)(e.to,t)||!!ee(e.activeBaseRegex,t)||!(!e.activeBasePath||!t.startsWith(e.activeBasePath))}(e,t)))}function ue(e){let{items:t,position:n,className:o,onClick:i,...l}=e;const c=(0,r.useRef)(null),[u,d]=(0,r.useState)(!1);return(0,r.useEffect)((()=>{const e=e=>{c.current&&!c.current.contains(e.target)&&d(!1)};return document.addEventListener("mousedown",e),document.addEventListener("touchstart",e),document.addEventListener("focusin",e),()=>{document.removeEventListener("mousedown",e),document.removeEventListener("touchstart",e),document.removeEventListener("focusin",e)}}),[c]),r.createElement("div",{ref:c,className:(0,a.Z)("navbar__item","dropdown","dropdown--hoverable",{"dropdown--right":"right"===n,"dropdown--show":u})},r.createElement(ne,(0,s.Z)({"aria-haspopup":"true","aria-expanded":u,role:"button",href:l.to?void 0:"#",className:(0,a.Z)("navbar__link",o)},l,{onClick:l.to?void 0:e=>e.preventDefault(),onKeyDown:e=>{"Enter"===e.key&&(e.preventDefault(),d(!u))}}),l.children??l.label),r.createElement("ul",{className:"dropdown__menu"},t.map(((e,t)=>r.createElement(Ie,(0,s.Z)({isDropdownItem:!0,activeClassName:"dropdown__link--active"},e,{key:t}))))))}function de(e){let{items:t,className:n,position:o,onClick:i,...c}=e;const u=function(){const{siteConfig:{baseUrl:e}}=(0,le.Z)(),{pathname:t}=(0,l.TH)();return t.replace(e,"/")}(),d=ce(t,u),{collapsed:f,toggleCollapsed:p,setCollapsed:m}=(0,ie.u)({initialState:()=>!d});return(0,r.useEffect)((()=>{d&&m(!d)}),[u,d,m]),r.createElement("li",{className:(0,a.Z)("menu__list-item",{"menu__list-item--collapsed":f})},r.createElement(ne,(0,s.Z)({role:"button",className:(0,a.Z)("menu__link menu__link--sublist menu__link--sublist-caret",n)},c,{onClick:e=>{e.preventDefault(),p()}}),c.children??c.label),r.createElement(ie.z,{lazy:!0,as:"ul",className:"menu__list",collapsed:f},t.map(((e,t)=>r.createElement(Ie,(0,s.Z)({mobile:!0,isDropdownItem:!0,onClick:i,activeClassName:"menu__link--active"},e,{key:t}))))))}function fe(e){let{mobile:t=!1,...n}=e;const a=t?de:ue;return r.createElement(a,n)}var pe=n(4711);function me(e){let{width:t=20,height:n=20,...a}=e;return r.createElement("svg",(0,s.Z)({viewBox:"0 0 24 24",width:t,height:n,"aria-hidden":!0},a),r.createElement("path",{fill:"currentColor",d:"M12.87 15.07l-2.54-2.51.03-.03c1.74-1.94 2.98-4.17 3.71-6.53H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z"}))}const he={iconLanguage:"iconLanguage_nlXk"};function ge(e){var t,n,r="";if("string"==typeof e||"number"==typeof e)r+=e;else if("object"==typeof e)if(Array.isArray(e))for(t=0;t{if(!e.state?.highlightState||0===e.state.highlightState.wordToHighlight.length)return;o(e.state.highlightState);const{highlightState:n,...r}=e.state;t.replace({...e,state:r})}),[e.state?.highlightState,t,e]),(0,r.useEffect)((()=>{if(0===a.wordToHighlight.length)return;const e=document.getElementsByTagName("article")[0]??document.getElementsByTagName("main")[0];if(!e)return;const t=new(we())(e),n={ignoreJoiners:!0};return t.mark(a.wordToHighlight,n),()=>t.unmark(n)}),[a,n]),null}const ke=e=>{const t=(0,r.useRef)(!1),a=(0,r.useRef)(null),[o,i]=(0,r.useState)(!1),s=(0,l.k6)(),{siteConfig:c={}}=(0,le.Z)(),u=(c.plugins||[]).find((e=>Array.isArray(e)&&"string"==typeof e[0]&&e[0].includes("docusaurus-lunr-search"))),d=(0,j.Z)(),{baseUrl:f}=c,p=u&&u[1]?.assetUrl||f,m=(0,be.eZ)("docusaurus-lunr-search"),h=()=>{t.current||(Promise.all([fetch(`${p}${m.fileNames.searchDoc}`).then((e=>e.json())),fetch(`${p}${m.fileNames.lunrIndex}`).then((e=>e.json())),Promise.all([n.e(4611),n.e(5684)]).then(n.bind(n,4734)),Promise.all([n.e(532),n.e(2572)]).then(n.bind(n,2572))]).then((e=>{let[t,n,{default:r}]=e;const{searchDocs:a,options:o}=t;a&&0!==a.length&&(((e,t,n,r)=>{new n({searchDocs:e,searchIndex:t,baseUrl:f,inputSelector:"#search_input_react",handleSelected:(e,t,n)=>{const a=n.url||"/";document.createElement("a").href=a,e.setVal(""),t.target.blur();let o="";if(r.highlightResult)try{const e=(n.text||n.subcategory||n.title).match(new RegExp("\\w*","g"));if(e&&e.length>0){const t=document.createElement("div");t.innerHTML=e[0],o=t.textContent}}catch(i){console.log(i)}s.push(a,{highlightState:{wordToHighlight:o}})}})})(a,n,r,o),i(!0))})),t.current=!0)},g=(0,r.useCallback)((t=>{a.current.contains(t.target)||a.current.focus(),e.handleSearchBarToggle&&e.handleSearchBarToggle(!e.isSearchBarExpanded)}),[e.isSearchBarExpanded]);return d&&h(),r.createElement("div",{className:"navbar__search",key:"search-box"},r.createElement("span",{"aria-label":"expand searchbar",role:"button",className:ve("search-icon",{"search-icon-hidden":e.isSearchBarExpanded}),onClick:g,onKeyDown:g,tabIndex:0}),r.createElement("input",{id:"search_input_react",type:"search",placeholder:o?"Search Ctrl+K":"Loading...","aria-label":"Search",className:ve("navbar__search-input",{"search-bar-expanded":e.isSearchBarExpanded},{"search-bar":!e.isSearchBarExpanded}),onClick:h,onMouseOver:h,onFocus:g,onBlur:g,ref:a,disabled:!o}),r.createElement(Ee,null))};function Se(e){return r.createElement(r.Fragment,null,r.createElement(ke,e))}const xe={searchBox:"searchBox_ZlJk"};function _e(e){let{children:t,className:n}=e;return r.createElement("div",{className:(0,a.Z)(n,xe.searchBox)},t)}var Ce=n(4104),Te=n(2802);const Ne=e=>e.docs.find((t=>t.id===e.mainDocId));var Ae=n(373);const Oe=e=>e.docs.find((t=>t.id===e.mainDocId));const Le={default:oe,localeDropdown:function(e){let{mobile:t,dropdownItemsBefore:n,dropdownItemsAfter:a,...o}=e;const{i18n:{currentLocale:i,locales:u,localeConfigs:d}}=(0,le.Z)(),f=(0,pe.l)(),{search:p,hash:m}=(0,l.TH)(),h=[...n,...u.map((e=>{const n=`${`pathname://${f.createUrl({locale:e,fullyQualified:!1})}`}${p}${m}`;return{label:d[e].label,lang:d[e].htmlLang,to:n,target:"_self",autoAddBaseUrl:!1,className:e===i?t?"menu__link--active":"dropdown__link--active":""}})),...a],g=t?(0,c.I)({message:"Languages",id:"theme.navbar.mobileLanguageDropdown.label",description:"The label for the mobile language switcher dropdown"}):d[i].label;return r.createElement(fe,(0,s.Z)({},o,{mobile:t,label:r.createElement(r.Fragment,null,r.createElement(me,{className:he.iconLanguage}),g),items:h}))},search:function(e){let{mobile:t,className:n}=e;return t?null:r.createElement(_e,{className:n},r.createElement(Se,null))},dropdown:fe,html:function(e){let{value:t,className:n,mobile:o=!1,isDropdownItem:i=!1}=e;const s=i?"li":"div";return r.createElement(s,{className:(0,a.Z)({navbar__item:!o&&!i,"menu__list-item":o},n),dangerouslySetInnerHTML:{__html:t}})},doc:function(e){let{docId:t,label:n,docsPluginId:a,...o}=e;const{activeDoc:i}=(0,Ce.Iw)(a),l=(0,Te.vY)(t,a);return null===l?null:r.createElement(oe,(0,s.Z)({exact:!0},o,{isActive:()=>i?.path===l.path||!!i?.sidebar&&i.sidebar===l.sidebar,label:n??l.id,to:l.path}))},docSidebar:function(e){let{sidebarId:t,label:n,docsPluginId:a,...o}=e;const{activeDoc:i}=(0,Ce.Iw)(a),l=(0,Te.oz)(t,a).link;if(!l)throw new Error(`DocSidebarNavbarItem: Sidebar with ID "${t}" doesn't have anything to be linked to.`);return r.createElement(oe,(0,s.Z)({exact:!0},o,{isActive:()=>i?.sidebar===t,label:n??l.label,to:l.path}))},docsVersion:function(e){let{label:t,to:n,docsPluginId:a,...o}=e;const i=(0,Te.lO)(a)[0],l=t??i.label,c=n??Ne(i).path;return r.createElement(oe,(0,s.Z)({},o,{label:l,to:c}))},docsVersionDropdown:function(e){let{mobile:t,docsPluginId:n,dropdownActiveClassDisabled:a,dropdownItemsBefore:o,dropdownItemsAfter:i,...u}=e;const{search:d,hash:f}=(0,l.TH)(),p=(0,Ce.Iw)(n),m=(0,Ce.gB)(n),{savePreferredVersionName:h}=(0,Ae.J)(n),g=[...o,...m.map((e=>{const t=p.alternateDocVersions[e.name]??Oe(e);return{label:e.label,to:`${t.path}${d}${f}`,isActive:()=>e===p.activeVersion,onClick:()=>h(e.name)}})),...i],v=(0,Te.lO)(n)[0],b=t&&g.length>1?(0,c.I)({id:"theme.navbar.mobileVersionsDropdown.label",message:"Versions",description:"The label for the navbar versions dropdown on mobile view"}):v.label,y=t&&g.length>1?void 0:Oe(v).path;return g.length<=1?r.createElement(oe,(0,s.Z)({},u,{mobile:t,label:b,to:y,isActive:a?()=>!1:void 0})):r.createElement(fe,(0,s.Z)({},u,{mobile:t,label:b,to:y,items:g,isActive:a?()=>!1:void 0}))}};function Ie(e){let{type:t,...n}=e;const a=function(e,t){return e&&"default"!==e?e:"items"in t?"dropdown":"default"}(t,n),o=Le[a];if(!o)throw new Error(`No NavbarItem component found for type "${t}".`);return r.createElement(o,n)}function Pe(){const e=(0,A.e)(),t=(0,w.L)().navbar.items;return r.createElement("ul",{className:"menu__list"},t.map(((t,n)=>r.createElement(Ie,(0,s.Z)({mobile:!0},t,{onClick:()=>e.toggle(),key:n})))))}function Re(e){return r.createElement("button",(0,s.Z)({},e,{type:"button",className:"clean-btn navbar-sidebar__back"}),r.createElement(c.Z,{id:"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel",description:"The label of the back button to return to main menu, inside the mobile navbar sidebar secondary menu (notably used to display the docs sidebar)"},"\u2190 Back to main menu"))}function Me(){const e=0===(0,w.L)().navbar.items.length,t=D();return r.createElement(r.Fragment,null,!e&&r.createElement(Re,{onClick:()=>t.hide()}),t.content)}function De(){const e=(0,A.e)();var t;return void 0===(t=e.shown)&&(t=!0),(0,r.useEffect)((()=>(document.body.style.overflow=t?"hidden":"visible",()=>{document.body.style.overflow="visible"})),[t]),e.shouldRender?r.createElement(F,{header:r.createElement(K,null),primaryMenu:r.createElement(Pe,null),secondaryMenu:r.createElement(Me,null)}):null}const Fe={navbarHideable:"navbarHideable_m1mJ",navbarHidden:"navbarHidden_jGov"};function Be(e){return r.createElement("div",(0,s.Z)({role:"presentation"},e,{className:(0,a.Z)("navbar-sidebar__backdrop",e.className)}))}function je(e){let{children:t}=e;const{navbar:{hideOnScroll:n,style:o}}=(0,w.L)(),i=(0,A.e)(),{navbarRef:s,isNavbarVisible:l}=function(e){const[t,n]=(0,r.useState)(e),a=(0,r.useRef)(!1),o=(0,r.useRef)(0),i=(0,r.useCallback)((e=>{null!==e&&(o.current=e.getBoundingClientRect().height)}),[]);return(0,O.RF)(((t,r)=>{let{scrollY:i}=t;if(!e)return;if(i=s?n(!1):i+c{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 r.createElement("nav",{ref:s,"aria-label":(0,c.I)({id:"theme.NavBar.navAriaLabel",message:"Main",description:"The ARIA label for the main navigation"}),className:(0,a.Z)("navbar","navbar--fixed-top",n&&[Fe.navbarHideable,!l&&Fe.navbarHidden],{"navbar--dark":"dark"===o,"navbar--primary":"primary"===o,"navbar-sidebar--show":i.shown})},t,r.createElement(Be,{onClick:i.toggle}),r.createElement(De,null))}var $e=n(8780);const ze={errorBoundaryError:"errorBoundaryError_a6uf"};function Ue(e){return r.createElement("button",(0,s.Z)({type:"button"},e),r.createElement(c.Z,{id:"theme.ErrorPageContent.tryAgain",description:"The label of the button to try again rendering when the React error boundary captures an error"},"Try again"))}function Ze(e){let{error:t}=e;const n=(0,$e.getErrorCausalChain)(t).map((e=>e.message)).join("\n\nCause:\n");return r.createElement("p",{className:ze.errorBoundaryError},n)}class He extends r.Component{componentDidCatch(e,t){throw this.props.onError(e,t)}render(){return this.props.children}}const Ve="right";function We(e){let{width:t=30,height:n=30,className:a,...o}=e;return r.createElement("svg",(0,s.Z)({className:a,width:t,height:n,viewBox:"0 0 30 30","aria-hidden":"true"},o),r.createElement("path",{stroke:"currentColor",strokeLinecap:"round",strokeMiterlimit:"10",strokeWidth:"2",d:"M4 7h22M4 15h22M4 23h22"}))}function Ge(){const{toggle:e,shown:t}=(0,A.e)();return r.createElement("button",{onClick:e,"aria-label":(0,c.I)({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"},r.createElement(We,null))}const qe={colorModeToggle:"colorModeToggle_DEke"};function Ye(e){let{items:t}=e;return r.createElement(r.Fragment,null,t.map(((e,t)=>r.createElement(He,{key:t,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)}`,{cause:t})},r.createElement(Ie,e)))))}function Ke(e){let{left:t,right:n}=e;return r.createElement("div",{className:"navbar__inner"},r.createElement("div",{className:"navbar__items"},t),r.createElement("div",{className:"navbar__items navbar__items--right"},n))}function Xe(){const e=(0,A.e)(),t=(0,w.L)().navbar.items,[n,a]=function(e){function t(e){return"left"===(e.position??Ve)}return[e.filter(t),e.filter((e=>!t(e)))]}(t),o=t.find((e=>"search"===e.type));return r.createElement(Ke,{left:r.createElement(r.Fragment,null,!e.disabled&&r.createElement(Ge,null),r.createElement(q,null),r.createElement(Ye,{items:n})),right:r.createElement(r.Fragment,null,r.createElement(Ye,{items:a}),r.createElement(W,{className:qe.colorModeToggle}),!o&&r.createElement(_e,null,r.createElement(Se,null)))})}function Qe(){return r.createElement(je,null,r.createElement(Xe,null))}function Je(e){let{item:t}=e;const{to:n,href:a,label:o,prependBaseUrlToHref:i,...l}=t,c=(0,Q.Z)(n),u=(0,Q.Z)(a,{forcePrependBaseUrl:!0});return r.createElement(X.Z,(0,s.Z)({className:"footer__link-item"},a?{href:i?u:a}:{to:c},l),o,a&&!(0,J.Z)(a)&&r.createElement(te.Z,null))}function et(e){let{item:t}=e;return t.html?r.createElement("li",{className:"footer__item",dangerouslySetInnerHTML:{__html:t.html}}):r.createElement("li",{key:t.href??t.to,className:"footer__item"},r.createElement(Je,{item:t}))}function tt(e){let{column:t}=e;return r.createElement("div",{className:"col footer__col"},r.createElement("div",{className:"footer__title"},t.title),r.createElement("ul",{className:"footer__items clean-list"},t.items.map(((e,t)=>r.createElement(et,{key:t,item:e})))))}function nt(e){let{columns:t}=e;return r.createElement("div",{className:"row footer__links"},t.map(((e,t)=>r.createElement(tt,{key:t,column:e}))))}function rt(){return r.createElement("span",{className:"footer__link-separator"},"\xb7")}function at(e){let{item:t}=e;return t.html?r.createElement("span",{className:"footer__link-item",dangerouslySetInnerHTML:{__html:t.html}}):r.createElement(Je,{item:t})}function ot(e){let{links:t}=e;return r.createElement("div",{className:"footer__links text--center"},r.createElement("div",{className:"footer__links"},t.map(((e,n)=>r.createElement(r.Fragment,{key:n},r.createElement(at,{item:e}),t.length!==n+1&&r.createElement(rt,null))))))}function it(e){let{links:t}=e;return function(e){return"title"in e[0]}(t)?r.createElement(nt,{columns:t}):r.createElement(ot,{links:t})}var st=n(941);const lt={footerLogoLink:"footerLogoLink_BH7S"};function ct(e){let{logo:t}=e;const{withBaseUrl:n}=(0,Q.C)(),o={light:n(t.src),dark:n(t.srcDark??t.src)};return r.createElement(st.Z,{className:(0,a.Z)("footer__logo",t.className),alt:t.alt,sources:o,width:t.width,height:t.height,style:t.style})}function ut(e){let{logo:t}=e;return t.href?r.createElement(X.Z,{href:t.href,className:lt.footerLogoLink,target:t.target},r.createElement(ct,{logo:t})):r.createElement(ct,{logo:t})}function dt(e){let{copyright:t}=e;return r.createElement("div",{className:"footer__copyright",dangerouslySetInnerHTML:{__html:t}})}function ft(e){let{style:t,links:n,logo:o,copyright:i}=e;return r.createElement("footer",{className:(0,a.Z)("footer",{"footer--dark":"dark"===t})},r.createElement("div",{className:"container container-fluid"},n,(o||i)&&r.createElement("div",{className:"footer__bottom text--center"},o&&r.createElement("div",{className:"margin-bottom--sm"},o),i)))}function pt(){const{footer:e}=(0,w.L)();if(!e)return null;const{copyright:t,links:n,logo:a,style:o}=e;return r.createElement(ft,{style:o,links:n&&n.length>0&&r.createElement(it,{links:n}),logo:a&&r.createElement(ut,{logo:a}),copyright:t&&r.createElement(dt,{copyright:t})})}const mt=r.memo(pt),ht=(0,L.Qc)([B.S,E.pl,O.OC,Ae.L5,i.VC,function(e){let{children:t}=e;return r.createElement(I.n2,null,r.createElement(A.M,null,r.createElement(R,null,t)))}]);function gt(e){let{children:t}=e;return r.createElement(ht,null,t)}function vt(e){let{error:t,tryAgain:n}=e;return r.createElement("main",{className:"container margin-vert--xl"},r.createElement("div",{className:"row"},r.createElement("div",{className:"col col--6 col--offset-3"},r.createElement("h1",{className:"hero__title"},r.createElement(c.Z,{id:"theme.ErrorPageContent.title",description:"The title of the fallback page when the page crashed"},"This page crashed.")),r.createElement("div",{className:"margin-vert--lg"},r.createElement(Ue,{onClick:n,className:"button button--primary shadow--lw"})),r.createElement("hr",null),r.createElement("div",{className:"margin-vert--md"},r.createElement(Ze,{error:t})))))}const bt={mainWrapper:"mainWrapper_z2l0"};function yt(e){const{children:t,noFooter:n,wrapperClassName:s,title:l,description:c}=e;return(0,v.t)(),r.createElement(gt,null,r.createElement(i.d,{title:l,description:c}),r.createElement(y,null),r.createElement(N,null),r.createElement(Qe,null),r.createElement("div",{id:d,className:(0,a.Z)(g.k.wrapper.main,bt.mainWrapper,s)},r.createElement(o.Z,{fallback:e=>r.createElement(vt,e)},t)),!n&&r.createElement(mt,null))}},1327:(e,t,n)=>{"use strict";n.d(t,{Z:()=>d});var r=n(7462),a=n(7294),o=n(9960),i=n(4996),s=n(2263),l=n(6668),c=n(941);function u(e){let{logo:t,alt:n,imageClassName:r}=e;const o={light:(0,i.Z)(t.src),dark:(0,i.Z)(t.srcDark||t.src)},s=a.createElement(c.Z,{className:t.className,sources:o,height:t.height,width:t.width,alt:n,style:t.style});return r?a.createElement("div",{className:r},s):s}function d(e){const{siteConfig:{title:t}}=(0,s.Z)(),{navbar:{title:n,logo:c}}=(0,l.L)(),{imageClassName:d,titleClassName:f,...p}=e,m=(0,i.Z)(c?.href||"/"),h=n?"":t,g=c?.alt??h;return a.createElement(o.Z,(0,r.Z)({to:m},p,c?.target&&{target:c.target}),c&&a.createElement(u,{logo:c,alt:g,imageClassName:d}),null!=n&&a.createElement("b",{className:f},n))}},197:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(7294),a=n(5742);function o(e){let{locale:t,version:n,tag:o}=e;const i=t;return r.createElement(a.Z,null,t&&r.createElement("meta",{name:"docusaurus_locale",content:t}),n&&r.createElement("meta",{name:"docusaurus_version",content:n}),o&&r.createElement("meta",{name:"docusaurus_tag",content:o}),i&&r.createElement("meta",{name:"docsearch:language",content:i}),n&&r.createElement("meta",{name:"docsearch:version",content:n}),o&&r.createElement("meta",{name:"docsearch:docusaurus_tag",content:o}))}},941:(e,t,n)=>{"use strict";n.d(t,{Z:()=>c});var r=n(7462),a=n(7294),o=n(4334),i=n(2389),s=n(2949);const l={themedImage:"themedImage_ToTc","themedImage--light":"themedImage--light_HNdA","themedImage--dark":"themedImage--dark_i4oU"};function c(e){const t=(0,i.Z)(),{colorMode:n}=(0,s.I)(),{sources:c,className:u,alt:d,...f}=e,p=t?"dark"===n?["dark"]:["light"]:["light","dark"];return a.createElement(a.Fragment,null,p.map((e=>a.createElement("img",(0,r.Z)({key:e,src:c[e],alt:d,className:(0,o.Z)(l.themedImage,l[`themedImage--${e}`],u)},f)))))}},6043:(e,t,n)=>{"use strict";n.d(t,{u:()=>l,z:()=>g});var r=n(7462),a=n(7294),o=n(412),i=n(1442);const s="ease-in-out";function l(e){let{initialState:t}=e;const[n,r]=(0,a.useState)(t??!1),o=(0,a.useCallback)((()=>{r((e=>!e))}),[]);return{collapsed:n,setCollapsed:r,toggleCollapsed:o}}const c={display:"none",overflow:"hidden",height:"0px"},u={display:"block",overflow:"visible",height:"auto"};function d(e,t){const n=t?c:u;e.style.display=n.display,e.style.overflow=n.overflow,e.style.height=n.height}function f(e){let{collapsibleRef:t,collapsed:n,animation:r}=e;const o=(0,a.useRef)(!1);(0,a.useEffect)((()=>{const e=t.current;function a(){const t=e.scrollHeight,n=r?.duration??function(e){if((0,i.n)())return 1;const t=e/36;return Math.round(10*(4+15*t**.25+t/5))}(t);return{transition:`height ${n}ms ${r?.easing??s}`,height:`${t}px`}}function l(){const t=a();e.style.transition=t.transition,e.style.height=t.height}if(!o.current)return d(e,n),void(o.current=!0);return e.style.willChange="height",function(){const t=requestAnimationFrame((()=>{n?(l(),requestAnimationFrame((()=>{e.style.height=c.height,e.style.overflow=c.overflow}))):(e.style.display="block",requestAnimationFrame((()=>{l()})))}));return()=>cancelAnimationFrame(t)}()}),[t,n,r])}function p(e){if(!o.Z.canUseDOM)return e?c:u}function m(e){let{as:t="div",collapsed:n,children:r,animation:o,onCollapseTransitionEnd:i,className:s,disableSSRStyle:l}=e;const c=(0,a.useRef)(null);return f({collapsibleRef:c,collapsed:n,animation:o}),a.createElement(t,{ref:c,style:l?void 0:p(n),onTransitionEnd:e=>{"height"===e.propertyName&&(d(c.current,n),i?.(n))},className:s},r)}function h(e){let{collapsed:t,...n}=e;const[o,i]=(0,a.useState)(!t),[s,l]=(0,a.useState)(t);return(0,a.useLayoutEffect)((()=>{t||i(!0)}),[t]),(0,a.useLayoutEffect)((()=>{o&&l(t)}),[o,t]),o?a.createElement(m,(0,r.Z)({},n,{collapsed:s})):null}function g(e){let{lazy:t,...n}=e;const r=t?h:m;return a.createElement(r,n)}},9689:(e,t,n)=>{"use strict";n.d(t,{nT:()=>m,pl:()=>p});var r=n(7294),a=n(2389),o=n(12),i=n(902),s=n(6668);const l=(0,o.WA)("docusaurus.announcement.dismiss"),c=(0,o.WA)("docusaurus.announcement.id"),u=()=>"true"===l.get(),d=e=>l.set(String(e)),f=r.createContext(null);function p(e){let{children:t}=e;const n=function(){const{announcementBar:e}=(0,s.L)(),t=(0,a.Z)(),[n,o]=(0,r.useState)((()=>!!t&&u()));(0,r.useEffect)((()=>{o(u())}),[]);const i=(0,r.useCallback)((()=>{d(!0),o(!0)}),[]);return(0,r.useEffect)((()=>{if(!e)return;const{id:t}=e;let n=c.get();"annoucement-bar"===n&&(n="announcement-bar");const r=t!==n;c.set(t),r&&d(!1),!r&&u()||o(!1)}),[e]),(0,r.useMemo)((()=>({isActive:!!e&&!n,close:i})),[e,n,i])}();return r.createElement(f.Provider,{value:n},t)}function m(){const e=(0,r.useContext)(f);if(!e)throw new i.i6("AnnouncementBarProvider");return e}},2949:(e,t,n)=>{"use strict";n.d(t,{I:()=>g,S:()=>h});var r=n(7294),a=n(412),o=n(902),i=n(12),s=n(6668);const l=r.createContext(void 0),c="theme",u=(0,i.WA)(c),d={light:"light",dark:"dark"},f=e=>e===d.dark?d.dark:d.light,p=e=>a.Z.canUseDOM?f(document.documentElement.getAttribute("data-theme")):f(e),m=e=>{u.set(f(e))};function h(e){let{children:t}=e;const n=function(){const{colorMode:{defaultMode:e,disableSwitch:t,respectPrefersColorScheme:n}}=(0,s.L)(),[a,o]=(0,r.useState)(p(e));(0,r.useEffect)((()=>{t&&u.del()}),[t]);const i=(0,r.useCallback)((function(t,r){void 0===r&&(r={});const{persist:a=!0}=r;t?(o(t),a&&m(t)):(o(n?window.matchMedia("(prefers-color-scheme: dark)").matches?d.dark:d.light:e),u.del())}),[n,e]);(0,r.useEffect)((()=>{document.documentElement.setAttribute("data-theme",f(a))}),[a]),(0,r.useEffect)((()=>{if(t)return;const e=e=>{if(e.key!==c)return;const t=u.get();null!==t&&i(f(t))};return window.addEventListener("storage",e),()=>window.removeEventListener("storage",e)}),[t,i]);const l=(0,r.useRef)(!1);return(0,r.useEffect)((()=>{if(t&&!n)return;const e=window.matchMedia("(prefers-color-scheme: dark)"),r=()=>{window.matchMedia("print").matches||l.current?l.current=window.matchMedia("print").matches:i(null)};return e.addListener(r),()=>e.removeListener(r)}),[i,t,n]),(0,r.useMemo)((()=>({colorMode:a,setColorMode:i,get isDarkTheme(){return a===d.dark},setLightTheme(){i(d.light)},setDarkTheme(){i(d.dark)}})),[a,i])}();return r.createElement(l.Provider,{value:n},t)}function g(){const e=(0,r.useContext)(l);if(null==e)throw new o.i6("ColorModeProvider","Please see https://docusaurus.io/docs/api/themes/configuration#use-color-mode.");return e}},373:(e,t,n)=>{"use strict";n.d(t,{J:()=>b,L5:()=>g});var r=n(7294),a=n(4104),o=n(9935),i=n(6668),s=n(2802),l=n(902),c=n(12);const u=e=>`docs-preferred-version-${e}`,d={save:(e,t,n)=>{(0,c.WA)(u(e),{persistence:t}).set(n)},read:(e,t)=>(0,c.WA)(u(e),{persistence:t}).get(),clear:(e,t)=>{(0,c.WA)(u(e),{persistence:t}).del()}},f=e=>Object.fromEntries(e.map((e=>[e,{preferredVersionName:null}])));const p=r.createContext(null);function m(){const e=(0,a._r)(),t=(0,i.L)().docs.versionPersistence,n=(0,r.useMemo)((()=>Object.keys(e)),[e]),[o,s]=(0,r.useState)((()=>f(n)));(0,r.useEffect)((()=>{s(function(e){let{pluginIds:t,versionPersistence:n,allDocsData:r}=e;function a(e){const t=d.read(e,n);return r[e].versions.some((e=>e.name===t))?{preferredVersionName:t}:(d.clear(e,n),{preferredVersionName:null})}return Object.fromEntries(t.map((e=>[e,a(e)])))}({allDocsData:e,versionPersistence:t,pluginIds:n}))}),[e,t,n]);return[o,(0,r.useMemo)((()=>({savePreferredVersion:function(e,n){d.save(e,t,n),s((t=>({...t,[e]:{preferredVersionName:n}})))}})),[t])]}function h(e){let{children:t}=e;const n=m();return r.createElement(p.Provider,{value:n},t)}function g(e){let{children:t}=e;return s.cE?r.createElement(h,null,t):r.createElement(r.Fragment,null,t)}function v(){const e=(0,r.useContext)(p);if(!e)throw new l.i6("DocsPreferredVersionContextProvider");return e}function b(e){void 0===e&&(e=o.m);const t=(0,a.zh)(e),[n,i]=v(),{preferredVersionName:s}=n[e];return{preferredVersion:t.versions.find((e=>e.name===s))??null,savePreferredVersionName:(0,r.useCallback)((t=>{i.savePreferredVersion(e,t)}),[i,e])}}},1116:(e,t,n)=>{"use strict";n.d(t,{V:()=>l,b:()=>s});var r=n(7294),a=n(902);const o=Symbol("EmptyContext"),i=r.createContext(o);function s(e){let{children:t,name:n,items:a}=e;const o=(0,r.useMemo)((()=>n&&a?{name:n,items:a}:null),[n,a]);return r.createElement(i.Provider,{value:o},t)}function l(){const e=(0,r.useContext)(i);if(e===o)throw new a.i6("DocsSidebarProvider");return e}},2961:(e,t,n)=>{"use strict";n.d(t,{M:()=>f,e:()=>p});var r=n(7294),a=n(3102),o=n(7524),i=n(6550),s=(n(1688),n(902));function l(e){!function(e){const t=(0,i.k6)(),n=(0,s.zX)(e);(0,r.useEffect)((()=>t.block(((e,t)=>n(e,t)))),[t,n])}(((t,n)=>{if("POP"===n)return e(t,n)}))}var c=n(6668);const u=r.createContext(void 0);function d(){const e=function(){const e=(0,a.HY)(),{items:t}=(0,c.L)().navbar;return 0===t.length&&!e.component}(),t=(0,o.i)(),n=!e&&"mobile"===t,[i,s]=(0,r.useState)(!1);l((()=>{if(i)return s(!1),!1}));const u=(0,r.useCallback)((()=>{s((e=>!e))}),[]);return(0,r.useEffect)((()=>{"desktop"===t&&s(!1)}),[t]),(0,r.useMemo)((()=>({disabled:e,shouldRender:n,toggle:u,shown:i})),[e,n,u,i])}function f(e){let{children:t}=e;const n=d();return r.createElement(u.Provider,{value:n},t)}function p(){const e=r.useContext(u);if(void 0===e)throw new s.i6("NavbarMobileSidebarProvider");return e}},3102:(e,t,n)=>{"use strict";n.d(t,{HY:()=>s,Zo:()=>l,n2:()=>i});var r=n(7294),a=n(902);const o=r.createContext(null);function i(e){let{children:t}=e;const n=(0,r.useState)({component:null,props:null});return r.createElement(o.Provider,{value:n},t)}function s(){const e=(0,r.useContext)(o);if(!e)throw new a.i6("NavbarSecondaryMenuContentProvider");return e[0]}function l(e){let{component:t,props:n}=e;const i=(0,r.useContext)(o);if(!i)throw new a.i6("NavbarSecondaryMenuContentProvider");const[,s]=i,l=(0,a.Ql)(n);return(0,r.useEffect)((()=>{s({component:t,props:l})}),[s,t,l]),(0,r.useEffect)((()=>()=>s({component:null,props:null})),[s]),null}},9727:(e,t,n)=>{"use strict";n.d(t,{h:()=>a,t:()=>o});var r=n(7294);const a="navigation-with-keyboard";function o(){(0,r.useEffect)((()=>{function e(e){"keydown"===e.type&&"Tab"===e.key&&document.body.classList.add(a),"mousedown"===e.type&&document.body.classList.remove(a)}return document.addEventListener("keydown",e),document.addEventListener("mousedown",e),()=>{document.body.classList.remove(a),document.removeEventListener("keydown",e),document.removeEventListener("mousedown",e)}}),[])}},7524:(e,t,n)=>{"use strict";n.d(t,{i:()=>c});var r=n(7294),a=n(412);const o={desktop:"desktop",mobile:"mobile",ssr:"ssr"},i=996;function s(){return a.Z.canUseDOM?window.innerWidth>i?o.desktop:o.mobile:o.ssr}const l=!1;function c(){const[e,t]=(0,r.useState)((()=>l?"ssr":s()));return(0,r.useEffect)((()=>{function e(){t(s())}const n=l?window.setTimeout(e,1e3):void 0;return window.addEventListener("resize",e),()=>{window.removeEventListener("resize",e),clearTimeout(n)}}),[]),e}},5281:(e,t,n)=>{"use strict";n.d(t,{k:()=>r});const r={page:{blogListPage:"blog-list-page",blogPostPage:"blog-post-page",blogTagsListPage:"blog-tags-list-page",blogTagPostListPage:"blog-tags-post-list-page",docsDocPage:"docs-doc-page",docsTagsListPage:"docs-tags-list-page",docsTagDocListPage:"docs-tags-doc-list-page",mdxPage:"mdx-page"},wrapper:{main:"main-wrapper",blogPages:"blog-wrapper",docsPages:"docs-wrapper",mdxPages:"mdx-wrapper"},common:{editThisPage:"theme-edit-this-page",lastUpdated:"theme-last-updated",backToTopButton:"theme-back-to-top-button",codeBlock:"theme-code-block",admonition:"theme-admonition",admonitionType:e=>`theme-admonition-${e}`},layout:{},docs:{docVersionBanner:"theme-doc-version-banner",docVersionBadge:"theme-doc-version-badge",docBreadcrumbs:"theme-doc-breadcrumbs",docMarkdown:"theme-doc-markdown",docTocMobile:"theme-doc-toc-mobile",docTocDesktop:"theme-doc-toc-desktop",docFooter:"theme-doc-footer",docFooterTagsRow:"theme-doc-footer-tags-row",docFooterEditMetaRow:"theme-doc-footer-edit-meta-row",docSidebarContainer:"theme-doc-sidebar-container",docSidebarMenu:"theme-doc-sidebar-menu",docSidebarItemCategory:"theme-doc-sidebar-item-category",docSidebarItemLink:"theme-doc-sidebar-item-link",docSidebarItemCategoryLevel:e=>`theme-doc-sidebar-item-category-level-${e}`,docSidebarItemLinkLevel:e=>`theme-doc-sidebar-item-link-level-${e}`},blog:{}}},1442:(e,t,n)=>{"use strict";function r(){return window.matchMedia("(prefers-reduced-motion: reduce)").matches}n.d(t,{n:()=>r})},2802:(e,t,n)=>{"use strict";n.d(t,{Wl:()=>f,_F:()=>h,cE:()=>d,hI:()=>E,lO:()=>b,vY:()=>w,oz:()=>y,s1:()=>v});var r=n(7294),a=n(6550),o=n(8790),i=n(4104),s=n(373),l=n(1116);function c(e){return Array.from(new Set(e))}var u=n(8596);const d=!!i._r;function f(e){if(e.href)return e.href;for(const t of e.items){if("link"===t.type)return t.href;if("category"===t.type){const e=f(t);if(e)return e}}}const p=(e,t)=>void 0!==e&&(0,u.Mg)(e,t),m=(e,t)=>e.some((e=>h(e,t)));function h(e,t){return"link"===e.type?p(e.href,t):"category"===e.type&&(p(e.href,t)||m(e.items,t))}function g(e){let{sidebarItems:t,pathname:n,onlyCategories:r=!1}=e;const a=[];return function e(t){for(const o of t)if("category"===o.type&&((0,u.Mg)(o.href,n)||e(o.items))||"link"===o.type&&(0,u.Mg)(o.href,n)){return r&&"category"!==o.type||a.unshift(o),!0}return!1}(t),a}function v(){const e=(0,l.V)(),{pathname:t}=(0,a.TH)(),n=(0,i.gA)()?.pluginData.breadcrumbs;return!1!==n&&e?g({sidebarItems:e.items,pathname:t}):null}function b(e){const{activeVersion:t}=(0,i.Iw)(e),{preferredVersion:n}=(0,s.J)(e),a=(0,i.yW)(e);return(0,r.useMemo)((()=>c([t,n,a].filter(Boolean))),[t,n,a])}function y(e,t){const n=b(t);return(0,r.useMemo)((()=>{const t=n.flatMap((e=>e.sidebars?Object.entries(e.sidebars):[])),r=t.find((t=>t[0]===e));if(!r)throw new Error(`Can't find any sidebar with id "${e}" in version${n.length>1?"s":""} ${n.map((e=>e.name)).join(", ")}".\nAvailable sidebar ids are:\n- ${t.map((e=>e[0])).join("\n- ")}`);return r[1]}),[e,n])}function w(e,t){const n=b(t);return(0,r.useMemo)((()=>{const t=n.flatMap((e=>e.docs)),r=t.find((t=>t.id===e));if(!r){if(n.flatMap((e=>e.draftIds)).includes(e))return null;throw new Error(`Couldn't find any doc with id "${e}" in version${n.length>1?"s":""} "${n.map((e=>e.name)).join(", ")}".\nAvailable doc ids are:\n- ${c(t.map((e=>e.id))).join("\n- ")}`)}return r}),[e,n])}function E(e){let{route:t,versionMetadata:n}=e;const r=(0,a.TH)(),i=t.routes,s=i.find((e=>(0,a.LX)(r.pathname,e)));if(!s)return null;const l=s.sidebar,c=l?n.docsSidebars[l]:void 0;return{docElement:(0,o.H)(i),sidebarName:l,sidebarItems:c}}},1944:(e,t,n)=>{"use strict";n.d(t,{FG:()=>f,d:()=>u,VC:()=>p});var r=n(7294),a=n(7459),o=n(5742),i=n(226);function s(){const e=r.useContext(i._);if(!e)throw new Error("Unexpected: no Docusaurus route context found");return e}var l=n(4996),c=n(2263);function u(e){let{title:t,description:n,keywords:a,image:i,children:s}=e;const u=function(e){const{siteConfig:t}=(0,c.Z)(),{title:n,titleDelimiter:r}=t;return e?.trim().length?`${e.trim()} ${r} ${n}`:n}(t),{withBaseUrl:d}=(0,l.C)(),f=i?d(i,{absolute:!0}):void 0;return r.createElement(o.Z,null,t&&r.createElement("title",null,u),t&&r.createElement("meta",{property:"og:title",content:u}),n&&r.createElement("meta",{name:"description",content:n}),n&&r.createElement("meta",{property:"og:description",content:n}),a&&r.createElement("meta",{name:"keywords",content:Array.isArray(a)?a.join(","):a}),f&&r.createElement("meta",{property:"og:image",content:f}),f&&r.createElement("meta",{name:"twitter:image",content:f}),s)}const d=r.createContext(void 0);function f(e){let{className:t,children:n}=e;const i=r.useContext(d),s=(0,a.Z)(i,t);return r.createElement(d.Provider,{value:s},r.createElement(o.Z,null,r.createElement("html",{className:s})),n)}function p(e){let{children:t}=e;const n=s(),o=`plugin-${n.plugin.name.replace(/docusaurus-(?:plugin|theme)-(?:content-)?/gi,"")}`;const i=`plugin-id-${n.plugin.id}`;return r.createElement(f,{className:(0,a.Z)(o,i)},t)}},902:(e,t,n)=>{"use strict";n.d(t,{D9:()=>i,Qc:()=>c,Ql:()=>l,i6:()=>s,zX:()=>o});var r=n(7294);const a=n(412).Z.canUseDOM?r.useLayoutEffect:r.useEffect;function o(e){const t=(0,r.useRef)(e);return a((()=>{t.current=e}),[e]),(0,r.useCallback)((function(){return t.current(...arguments)}),[])}function i(e){const t=(0,r.useRef)();return a((()=>{t.current=e})),t.current}class s extends Error{constructor(e,t){super(),this.name="ReactContextError",this.message=`Hook ${this.stack?.split("\n")[1]?.match(/at (?:\w+\.)?(?\w+)/)?.groups.name??""} is called outside the <${e}>. ${t??""}`}}function l(e){const t=Object.entries(e);return t.sort(((e,t)=>e[0].localeCompare(t[0]))),(0,r.useMemo)((()=>e),t.flat())}function c(e){return t=>{let{children:n}=t;return r.createElement(r.Fragment,null,e.reduceRight(((e,t)=>r.createElement(t,null,e)),n))}}},8596:(e,t,n)=>{"use strict";n.d(t,{Mg:()=>i,Ns:()=>s});var r=n(7294),a=n(723),o=n(2263);function i(e,t){const n=e=>(!e||e.endsWith("/")?e:`${e}/`)?.toLowerCase();return n(e)===n(t)}function s(){const{baseUrl:e}=(0,o.Z)().siteConfig;return(0,r.useMemo)((()=>function(e){let{baseUrl:t,routes:n}=e;function r(e){return e.path===t&&!0===e.exact}function a(e){return e.path===t&&!e.exact}return function e(t){if(0===t.length)return;return t.find(r)||e(t.filter(a).flatMap((e=>e.routes??[])))}(n)}({routes:a.Z,baseUrl:e})),[e])}},2466:(e,t,n)=>{"use strict";n.d(t,{Ct:()=>f,OC:()=>l,RF:()=>d});var r=n(7294),a=n(412),o=n(2389),i=n(902);const s=r.createContext(void 0);function l(e){let{children:t}=e;const n=function(){const e=(0,r.useRef)(!0);return(0,r.useMemo)((()=>({scrollEventsEnabledRef:e,enableScrollEvents:()=>{e.current=!0},disableScrollEvents:()=>{e.current=!1}})),[])}();return r.createElement(s.Provider,{value:n},t)}function c(){const e=(0,r.useContext)(s);if(null==e)throw new i.i6("ScrollControllerProvider");return e}const u=()=>a.Z.canUseDOM?{scrollX:window.pageXOffset,scrollY:window.pageYOffset}:null;function d(e,t){void 0===t&&(t=[]);const{scrollEventsEnabledRef:n}=c(),a=(0,r.useRef)(u()),o=(0,i.zX)(e);(0,r.useEffect)((()=>{const e=()=>{if(!n.current)return;const e=u();o(e,a.current),a.current=e},t={passive:!0};return e(),window.addEventListener("scroll",e,t),()=>window.removeEventListener("scroll",e,t)}),[o,n,...t])}function f(){const e=(0,r.useRef)(null),t=(0,o.Z)()&&"smooth"===getComputedStyle(document.documentElement).scrollBehavior;return{startScroll:n=>{e.current=t?function(e){return window.scrollTo({top:e,behavior:"smooth"}),()=>{}}(n):function(e){let t=null;const n=document.documentElement.scrollTop>e;return function r(){const a=document.documentElement.scrollTop;(n&&a>e||!n&&at&&cancelAnimationFrame(t)}(n)},cancelScroll:()=>e.current?.()}}},3320:(e,t,n)=>{"use strict";n.d(t,{HX:()=>r,os:()=>a});n(2263);const r="default";function a(e,t){return`docs-${e}-${t}`}},12:(e,t,n)=>{"use strict";n.d(t,{WA:()=>l});n(7294),n(1688);const r="localStorage";function a(e){let{key:t,oldValue:n,newValue:r,storage:a}=e;if(n===r)return;const o=document.createEvent("StorageEvent");o.initStorageEvent("storage",!1,!1,t,n,r,window.location.href,a),window.dispatchEvent(o)}function o(e){if(void 0===e&&(e=r),"undefined"==typeof window)throw new Error("Browser storage is not available on Node.js/Docusaurus SSR process.");if("none"===e)return null;try{return window[e]}catch(n){return t=n,i||(console.warn("Docusaurus browser storage is not available.\nPossible reasons: running Docusaurus in an iframe, in an incognito browser session, or using too strict browser privacy settings.",t),i=!0),null}var t}let i=!1;const s={get:()=>null,set:()=>{},del:()=>{},listen:()=>()=>{}};function l(e,t){if("undefined"==typeof window)return function(e){function t(){throw new Error(`Illegal storage API usage for storage key "${e}".\nDocusaurus storage APIs are not supposed to be called on the server-rendering process.\nPlease only call storage APIs in effects and event handlers.`)}return{get:t,set:t,del:t,listen:t}}(e);const n=o(t?.persistence);return null===n?s:{get:()=>{try{return n.getItem(e)}catch(t){return console.error(`Docusaurus storage error, can't get key=${e}`,t),null}},set:t=>{try{const r=n.getItem(e);n.setItem(e,t),a({key:e,oldValue:r,newValue:t,storage:n})}catch(r){console.error(`Docusaurus storage error, can't set ${e}=${t}`,r)}},del:()=>{try{const t=n.getItem(e);n.removeItem(e),a({key:e,oldValue:t,newValue:null,storage:n})}catch(t){console.error(`Docusaurus storage error, can't delete key=${e}`,t)}},listen:t=>{try{const r=r=>{r.storageArea===n&&r.key===e&&t(r)};return window.addEventListener("storage",r),()=>window.removeEventListener("storage",r)}catch(r){return console.error(`Docusaurus storage error, can't listen for changes of key=${e}`,r),()=>{}}}}}},4711:(e,t,n)=>{"use strict";n.d(t,{l:()=>i});var r=n(2263),a=n(6550),o=n(8780);function i(){const{siteConfig:{baseUrl:e,url:t,trailingSlash:n},i18n:{defaultLocale:i,currentLocale:s}}=(0,r.Z)(),{pathname:l}=(0,a.TH)(),c=(0,o.applyTrailingSlash)(l,{trailingSlash:n,baseUrl:e}),u=s===i?e:e.replace(`/${s}/`,"/"),d=c.replace(e,"");return{createUrl:function(e){let{locale:n,fullyQualified:r}=e;return`${r?t:""}${function(e){return e===i?`${u}`:`${u}${e}/`}(n)}${d}`}}}},5936:(e,t,n)=>{"use strict";n.d(t,{S:()=>i});var r=n(7294),a=n(6550),o=n(902);function i(e){const t=(0,a.TH)(),n=(0,o.D9)(t),i=(0,o.zX)(e);(0,r.useEffect)((()=>{n&&t!==n&&i({location:t,previousLocation:n})}),[i,t,n])}},6668:(e,t,n)=>{"use strict";n.d(t,{L:()=>a});var r=n(2263);function a(){return(0,r.Z)().siteConfig.themeConfig}},8802:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t){const{trailingSlash:n,baseUrl:r}=t;if(e.startsWith("#"))return e;if(void 0===n)return e;const[a]=e.split(/[#?]/),o="/"===a||a===r?a:(i=a,n?function(e){return e.endsWith("/")?e:`${e}/`}(i):function(e){return e.endsWith("/")?e.slice(0,-1):e}(i));var i;return e.replace(a,o)}},4143:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getErrorCausalChain=void 0,t.getErrorCausalChain=function e(t){return t.cause?[t,...e(t.cause)]:[t]}},8780:function(e,t,n){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.getErrorCausalChain=t.applyTrailingSlash=t.blogPostContainerID=void 0,t.blogPostContainerID="__blog-post-container";var a=n(8802);Object.defineProperty(t,"applyTrailingSlash",{enumerable:!0,get:function(){return r(a).default}});var o=n(4143);Object.defineProperty(t,"getErrorCausalChain",{enumerable:!0,get:function(){return o.getErrorCausalChain}})},9318:(e,t,n)=>{"use strict";n.d(t,{lX:()=>w,q_:()=>C,ob:()=>p,PP:()=>N,Ep:()=>f});var r=n(7462);function a(e){return"/"===e.charAt(0)}function o(e,t){for(var n=t,r=n+1,a=e.length;r=0;f--){var p=i[f];"."===p?o(i,f):".."===p?(o(i,f),d++):d&&(o(i,f),d--)}if(!c)for(;d--;d)i.unshift("..");!c||""===i[0]||i[0]&&a(i[0])||i.unshift("");var m=i.join("/");return n&&"/"!==m.substr(-1)&&(m+="/"),m};var s=n(8776);function l(e){return"/"===e.charAt(0)?e:"/"+e}function c(e){return"/"===e.charAt(0)?e.substr(1):e}function u(e,t){return function(e,t){return 0===e.toLowerCase().indexOf(t.toLowerCase())&&-1!=="/?#".indexOf(e.charAt(t.length))}(e,t)?e.substr(t.length):e}function d(e){return"/"===e.charAt(e.length-1)?e.slice(0,-1):e}function f(e){var t=e.pathname,n=e.search,r=e.hash,a=t||"/";return n&&"?"!==n&&(a+="?"===n.charAt(0)?n:"?"+n),r&&"#"!==r&&(a+="#"===r.charAt(0)?r:"#"+r),a}function p(e,t,n,a){var o;"string"==typeof e?(o=function(e){var t=e||"/",n="",r="",a=t.indexOf("#");-1!==a&&(r=t.substr(a),t=t.substr(0,a));var o=t.indexOf("?");return-1!==o&&(n=t.substr(o),t=t.substr(0,o)),{pathname:t,search:"?"===n?"":n,hash:"#"===r?"":r}}(e),o.state=t):(void 0===(o=(0,r.Z)({},e)).pathname&&(o.pathname=""),o.search?"?"!==o.search.charAt(0)&&(o.search="?"+o.search):o.search="",o.hash?"#"!==o.hash.charAt(0)&&(o.hash="#"+o.hash):o.hash="",void 0!==t&&void 0===o.state&&(o.state=t));try{o.pathname=decodeURI(o.pathname)}catch(s){throw s instanceof URIError?new URIError('Pathname "'+o.pathname+'" could not be decoded. This is likely caused by an invalid percent-encoding.'):s}return n&&(o.key=n),a?o.pathname?"/"!==o.pathname.charAt(0)&&(o.pathname=i(o.pathname,a.pathname)):o.pathname=a.pathname:o.pathname||(o.pathname="/"),o}function m(){var e=null;var t=[];return{setPrompt:function(t){return e=t,function(){e===t&&(e=null)}},confirmTransitionTo:function(t,n,r,a){if(null!=e){var o="function"==typeof e?e(t,n):e;"string"==typeof o?"function"==typeof r?r(o,a):a(!0):a(!1!==o)}else a(!0)},appendListener:function(e){var n=!0;function r(){n&&e.apply(void 0,arguments)}return t.push(r),function(){n=!1,t=t.filter((function(e){return e!==r}))}},notifyListeners:function(){for(var e=arguments.length,n=new Array(e),r=0;rt?n.splice(t,n.length-t,a):n.push(a),d({action:r,location:a,index:t,entries:n})}}))},replace:function(e,t){var r="REPLACE",a=p(e,t,h(),w.location);u.confirmTransitionTo(a,r,n,(function(e){e&&(w.entries[w.index]=a,d({action:r,location:a}))}))},go:y,goBack:function(){y(-1)},goForward:function(){y(1)},canGo:function(e){var t=w.index+e;return t>=0&&t{"use strict";var r=n(9864),a={childContextTypes:!0,contextType:!0,contextTypes:!0,defaultProps:!0,displayName:!0,getDefaultProps:!0,getDerivedStateFromError:!0,getDerivedStateFromProps:!0,mixins:!0,propTypes:!0,type:!0},o={name:!0,length:!0,prototype:!0,caller:!0,callee:!0,arguments:!0,arity:!0},i={$$typeof:!0,compare:!0,defaultProps:!0,displayName:!0,propTypes:!0,type:!0},s={};function l(e){return r.isMemo(e)?i:s[e.$$typeof]||a}s[r.ForwardRef]={$$typeof:!0,render:!0,defaultProps:!0,displayName:!0,propTypes:!0},s[r.Memo]=i;var c=Object.defineProperty,u=Object.getOwnPropertyNames,d=Object.getOwnPropertySymbols,f=Object.getOwnPropertyDescriptor,p=Object.getPrototypeOf,m=Object.prototype;e.exports=function e(t,n,r){if("string"!=typeof n){if(m){var a=p(n);a&&a!==m&&e(t,a,r)}var i=u(n);d&&(i=i.concat(d(n)));for(var s=l(t),h=l(n),g=0;g{"use strict";e.exports=function(e,t,n,r,a,o,i,s){if(!e){var l;if(void 0===t)l=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var c=[n,r,a,o,i,s],u=0;(l=new Error(t.replace(/%s/g,(function(){return c[u++]})))).name="Invariant Violation"}throw l.framesToPop=1,l}}},5826:e=>{e.exports=Array.isArray||function(e){return"[object Array]"==Object.prototype.toString.call(e)}},813:function(e){e.exports=function(){"use strict";var e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},t=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")},n=function(){function e(e,t){for(var n=0;n1&&void 0!==arguments[1])||arguments[1],a=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[],o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:5e3;t(this,e),this.ctx=n,this.iframes=r,this.exclude=a,this.iframesTimeout=o}return n(e,[{key:"getContexts",value:function(){var e=[];return(void 0!==this.ctx&&this.ctx?NodeList.prototype.isPrototypeOf(this.ctx)?Array.prototype.slice.call(this.ctx):Array.isArray(this.ctx)?this.ctx:"string"==typeof this.ctx?Array.prototype.slice.call(document.querySelectorAll(this.ctx)):[this.ctx]:[]).forEach((function(t){var n=e.filter((function(e){return e.contains(t)})).length>0;-1!==e.indexOf(t)||n||e.push(t)})),e}},{key:"getIframeContents",value:function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:function(){},r=void 0;try{var a=e.contentWindow;if(r=a.document,!a||!r)throw new Error("iframe inaccessible")}catch(o){n()}r&&t(r)}},{key:"isIframeBlank",value:function(e){var t="about:blank",n=e.getAttribute("src").trim();return e.contentWindow.location.href===t&&n!==t&&n}},{key:"observeIframeLoad",value:function(e,t,n){var r=this,a=!1,o=null,i=function i(){if(!a){a=!0,clearTimeout(o);try{r.isIframeBlank(e)||(e.removeEventListener("load",i),r.getIframeContents(e,t,n))}catch(s){n()}}};e.addEventListener("load",i),o=setTimeout(i,this.iframesTimeout)}},{key:"onIframeReady",value:function(e,t,n){try{"complete"===e.contentWindow.document.readyState?this.isIframeBlank(e)?this.observeIframeLoad(e,t,n):this.getIframeContents(e,t,n):this.observeIframeLoad(e,t,n)}catch(r){n()}}},{key:"waitForIframes",value:function(e,t){var n=this,r=0;this.forEachIframe(e,(function(){return!0}),(function(e){r++,n.waitForIframes(e.querySelector("html"),(function(){--r||t()}))}),(function(e){e||t()}))}},{key:"forEachIframe",value:function(t,n,r){var a=this,o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:function(){},i=t.querySelectorAll("iframe"),s=i.length,l=0;i=Array.prototype.slice.call(i);var c=function(){--s<=0&&o(l)};s||c(),i.forEach((function(t){e.matches(t,a.exclude)?c():a.onIframeReady(t,(function(e){n(t)&&(l++,r(e)),c()}),c)}))}},{key:"createIterator",value:function(e,t,n){return document.createNodeIterator(e,t,n,!1)}},{key:"createInstanceOnIframe",value:function(t){return new e(t.querySelector("html"),this.iframes)}},{key:"compareNodeIframe",value:function(e,t,n){if(e.compareDocumentPosition(n)&Node.DOCUMENT_POSITION_PRECEDING){if(null===t)return!0;if(t.compareDocumentPosition(n)&Node.DOCUMENT_POSITION_FOLLOWING)return!0}return!1}},{key:"getIteratorNode",value:function(e){var t=e.previousNode();return{prevNode:t,node:(null===t||e.nextNode())&&e.nextNode()}}},{key:"checkIframeFilter",value:function(e,t,n,r){var a=!1,o=!1;return r.forEach((function(e,t){e.val===n&&(a=t,o=e.handled)})),this.compareNodeIframe(e,t,n)?(!1!==a||o?!1===a||o||(r[a].handled=!0):r.push({val:n,handled:!0}),!0):(!1===a&&r.push({val:n,handled:!1}),!1)}},{key:"handleOpenIframes",value:function(e,t,n,r){var a=this;e.forEach((function(e){e.handled||a.getIframeContents(e.val,(function(e){a.createInstanceOnIframe(e).forEachNode(t,n,r)}))}))}},{key:"iterateThroughNodes",value:function(e,t,n,r,a){for(var o=this,i=this.createIterator(t,e,r),s=[],l=[],c=void 0,u=void 0,d=function(){var e=o.getIteratorNode(i);return u=e.prevNode,c=e.node};d();)this.iframes&&this.forEachIframe(t,(function(e){return o.checkIframeFilter(c,u,e,s)}),(function(t){o.createInstanceOnIframe(t).forEachNode(e,(function(e){return l.push(e)}),r)})),l.push(c);l.forEach((function(e){n(e)})),this.iframes&&this.handleOpenIframes(s,e,n,r),a()}},{key:"forEachNode",value:function(e,t,n){var r=this,a=arguments.length>3&&void 0!==arguments[3]?arguments[3]:function(){},o=this.getContexts(),i=o.length;i||a(),o.forEach((function(o){var s=function(){r.iterateThroughNodes(e,o,t,n,(function(){--i<=0&&a()}))};r.iframes?r.waitForIframes(o,s):s()}))}}],[{key:"matches",value:function(e,t){var n="string"==typeof t?[t]:t,r=e.matches||e.matchesSelector||e.msMatchesSelector||e.mozMatchesSelector||e.oMatchesSelector||e.webkitMatchesSelector;if(r){var a=!1;return n.every((function(t){return!r.call(e,t)||(a=!0,!1)})),a}return!1}}]),e}(),o=function(){function o(e){t(this,o),this.ctx=e,this.ie=!1;var n=window.navigator.userAgent;(n.indexOf("MSIE")>-1||n.indexOf("Trident")>-1)&&(this.ie=!0)}return n(o,[{key:"log",value:function(t){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"debug",r=this.opt.log;this.opt.debug&&"object"===(void 0===r?"undefined":e(r))&&"function"==typeof r[n]&&r[n]("mark.js: "+t)}},{key:"escapeStr",value:function(e){return e.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")}},{key:"createRegExp",value:function(e){return"disabled"!==this.opt.wildcards&&(e=this.setupWildcardsRegExp(e)),e=this.escapeStr(e),Object.keys(this.opt.synonyms).length&&(e=this.createSynonymsRegExp(e)),(this.opt.ignoreJoiners||this.opt.ignorePunctuation.length)&&(e=this.setupIgnoreJoinersRegExp(e)),this.opt.diacritics&&(e=this.createDiacriticsRegExp(e)),e=this.createMergedBlanksRegExp(e),(this.opt.ignoreJoiners||this.opt.ignorePunctuation.length)&&(e=this.createJoinersRegExp(e)),"disabled"!==this.opt.wildcards&&(e=this.createWildcardsRegExp(e)),e=this.createAccuracyRegExp(e)}},{key:"createSynonymsRegExp",value:function(e){var t=this.opt.synonyms,n=this.opt.caseSensitive?"":"i",r=this.opt.ignoreJoiners||this.opt.ignorePunctuation.length?"\0":"";for(var a in t)if(t.hasOwnProperty(a)){var o=t[a],i="disabled"!==this.opt.wildcards?this.setupWildcardsRegExp(a):this.escapeStr(a),s="disabled"!==this.opt.wildcards?this.setupWildcardsRegExp(o):this.escapeStr(o);""!==i&&""!==s&&(e=e.replace(new RegExp("("+this.escapeStr(i)+"|"+this.escapeStr(s)+")","gm"+n),r+"("+this.processSynomyms(i)+"|"+this.processSynomyms(s)+")"+r))}return e}},{key:"processSynomyms",value:function(e){return(this.opt.ignoreJoiners||this.opt.ignorePunctuation.length)&&(e=this.setupIgnoreJoinersRegExp(e)),e}},{key:"setupWildcardsRegExp",value:function(e){return(e=e.replace(/(?:\\)*\?/g,(function(e){return"\\"===e.charAt(0)?"?":"\x01"}))).replace(/(?:\\)*\*/g,(function(e){return"\\"===e.charAt(0)?"*":"\x02"}))}},{key:"createWildcardsRegExp",value:function(e){var t="withSpaces"===this.opt.wildcards;return e.replace(/\u0001/g,t?"[\\S\\s]?":"\\S?").replace(/\u0002/g,t?"[\\S\\s]*?":"\\S*")}},{key:"setupIgnoreJoinersRegExp",value:function(e){return e.replace(/[^(|)\\]/g,(function(e,t,n){var r=n.charAt(t+1);return/[(|)\\]/.test(r)||""===r?e:e+"\0"}))}},{key:"createJoinersRegExp",value:function(e){var t=[],n=this.opt.ignorePunctuation;return Array.isArray(n)&&n.length&&t.push(this.escapeStr(n.join(""))),this.opt.ignoreJoiners&&t.push("\\u00ad\\u200b\\u200c\\u200d"),t.length?e.split(/\u0000+/).join("["+t.join("")+"]*"):e}},{key:"createDiacriticsRegExp",value:function(e){var t=this.opt.caseSensitive?"":"i",n=this.opt.caseSensitive?["a\xe0\xe1\u1ea3\xe3\u1ea1\u0103\u1eb1\u1eaf\u1eb3\u1eb5\u1eb7\xe2\u1ea7\u1ea5\u1ea9\u1eab\u1ead\xe4\xe5\u0101\u0105","A\xc0\xc1\u1ea2\xc3\u1ea0\u0102\u1eb0\u1eae\u1eb2\u1eb4\u1eb6\xc2\u1ea6\u1ea4\u1ea8\u1eaa\u1eac\xc4\xc5\u0100\u0104","c\xe7\u0107\u010d","C\xc7\u0106\u010c","d\u0111\u010f","D\u0110\u010e","e\xe8\xe9\u1ebb\u1ebd\u1eb9\xea\u1ec1\u1ebf\u1ec3\u1ec5\u1ec7\xeb\u011b\u0113\u0119","E\xc8\xc9\u1eba\u1ebc\u1eb8\xca\u1ec0\u1ebe\u1ec2\u1ec4\u1ec6\xcb\u011a\u0112\u0118","i\xec\xed\u1ec9\u0129\u1ecb\xee\xef\u012b","I\xcc\xcd\u1ec8\u0128\u1eca\xce\xcf\u012a","l\u0142","L\u0141","n\xf1\u0148\u0144","N\xd1\u0147\u0143","o\xf2\xf3\u1ecf\xf5\u1ecd\xf4\u1ed3\u1ed1\u1ed5\u1ed7\u1ed9\u01a1\u1edf\u1ee1\u1edb\u1edd\u1ee3\xf6\xf8\u014d","O\xd2\xd3\u1ece\xd5\u1ecc\xd4\u1ed2\u1ed0\u1ed4\u1ed6\u1ed8\u01a0\u1ede\u1ee0\u1eda\u1edc\u1ee2\xd6\xd8\u014c","r\u0159","R\u0158","s\u0161\u015b\u0219\u015f","S\u0160\u015a\u0218\u015e","t\u0165\u021b\u0163","T\u0164\u021a\u0162","u\xf9\xfa\u1ee7\u0169\u1ee5\u01b0\u1eeb\u1ee9\u1eed\u1eef\u1ef1\xfb\xfc\u016f\u016b","U\xd9\xda\u1ee6\u0168\u1ee4\u01af\u1eea\u1ee8\u1eec\u1eee\u1ef0\xdb\xdc\u016e\u016a","y\xfd\u1ef3\u1ef7\u1ef9\u1ef5\xff","Y\xdd\u1ef2\u1ef6\u1ef8\u1ef4\u0178","z\u017e\u017c\u017a","Z\u017d\u017b\u0179"]:["a\xe0\xe1\u1ea3\xe3\u1ea1\u0103\u1eb1\u1eaf\u1eb3\u1eb5\u1eb7\xe2\u1ea7\u1ea5\u1ea9\u1eab\u1ead\xe4\xe5\u0101\u0105A\xc0\xc1\u1ea2\xc3\u1ea0\u0102\u1eb0\u1eae\u1eb2\u1eb4\u1eb6\xc2\u1ea6\u1ea4\u1ea8\u1eaa\u1eac\xc4\xc5\u0100\u0104","c\xe7\u0107\u010dC\xc7\u0106\u010c","d\u0111\u010fD\u0110\u010e","e\xe8\xe9\u1ebb\u1ebd\u1eb9\xea\u1ec1\u1ebf\u1ec3\u1ec5\u1ec7\xeb\u011b\u0113\u0119E\xc8\xc9\u1eba\u1ebc\u1eb8\xca\u1ec0\u1ebe\u1ec2\u1ec4\u1ec6\xcb\u011a\u0112\u0118","i\xec\xed\u1ec9\u0129\u1ecb\xee\xef\u012bI\xcc\xcd\u1ec8\u0128\u1eca\xce\xcf\u012a","l\u0142L\u0141","n\xf1\u0148\u0144N\xd1\u0147\u0143","o\xf2\xf3\u1ecf\xf5\u1ecd\xf4\u1ed3\u1ed1\u1ed5\u1ed7\u1ed9\u01a1\u1edf\u1ee1\u1edb\u1edd\u1ee3\xf6\xf8\u014dO\xd2\xd3\u1ece\xd5\u1ecc\xd4\u1ed2\u1ed0\u1ed4\u1ed6\u1ed8\u01a0\u1ede\u1ee0\u1eda\u1edc\u1ee2\xd6\xd8\u014c","r\u0159R\u0158","s\u0161\u015b\u0219\u015fS\u0160\u015a\u0218\u015e","t\u0165\u021b\u0163T\u0164\u021a\u0162","u\xf9\xfa\u1ee7\u0169\u1ee5\u01b0\u1eeb\u1ee9\u1eed\u1eef\u1ef1\xfb\xfc\u016f\u016bU\xd9\xda\u1ee6\u0168\u1ee4\u01af\u1eea\u1ee8\u1eec\u1eee\u1ef0\xdb\xdc\u016e\u016a","y\xfd\u1ef3\u1ef7\u1ef9\u1ef5\xffY\xdd\u1ef2\u1ef6\u1ef8\u1ef4\u0178","z\u017e\u017c\u017aZ\u017d\u017b\u0179"],r=[];return e.split("").forEach((function(a){n.every((function(n){if(-1!==n.indexOf(a)){if(r.indexOf(n)>-1)return!1;e=e.replace(new RegExp("["+n+"]","gm"+t),"["+n+"]"),r.push(n)}return!0}))})),e}},{key:"createMergedBlanksRegExp",value:function(e){return e.replace(/[\s]+/gim,"[\\s]+")}},{key:"createAccuracyRegExp",value:function(e){var t=this,n="!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~\xa1\xbf",r=this.opt.accuracy,a="string"==typeof r?r:r.value,o="string"==typeof r?[]:r.limiters,i="";switch(o.forEach((function(e){i+="|"+t.escapeStr(e)})),a){case"partially":default:return"()("+e+")";case"complementary":return"()([^"+(i="\\s"+(i||this.escapeStr(n)))+"]*"+e+"[^"+i+"]*)";case"exactly":return"(^|\\s"+i+")("+e+")(?=$|\\s"+i+")"}}},{key:"getSeparatedKeywords",value:function(e){var t=this,n=[];return e.forEach((function(e){t.opt.separateWordSearch?e.split(" ").forEach((function(e){e.trim()&&-1===n.indexOf(e)&&n.push(e)})):e.trim()&&-1===n.indexOf(e)&&n.push(e)})),{keywords:n.sort((function(e,t){return t.length-e.length})),length:n.length}}},{key:"isNumeric",value:function(e){return Number(parseFloat(e))==e}},{key:"checkRanges",value:function(e){var t=this;if(!Array.isArray(e)||"[object Object]"!==Object.prototype.toString.call(e[0]))return this.log("markRanges() will only accept an array of objects"),this.opt.noMatch(e),[];var n=[],r=0;return e.sort((function(e,t){return e.start-t.start})).forEach((function(e){var a=t.callNoMatchOnInvalidRanges(e,r),o=a.start,i=a.end;a.valid&&(e.start=o,e.length=i-o,n.push(e),r=i)})),n}},{key:"callNoMatchOnInvalidRanges",value:function(e,t){var n=void 0,r=void 0,a=!1;return e&&void 0!==e.start?(r=(n=parseInt(e.start,10))+parseInt(e.length,10),this.isNumeric(e.start)&&this.isNumeric(e.length)&&r-t>0&&r-n>0?a=!0:(this.log("Ignoring invalid or overlapping range: "+JSON.stringify(e)),this.opt.noMatch(e))):(this.log("Ignoring invalid range: "+JSON.stringify(e)),this.opt.noMatch(e)),{start:n,end:r,valid:a}}},{key:"checkWhitespaceRanges",value:function(e,t,n){var r=void 0,a=!0,o=n.length,i=t-o,s=parseInt(e.start,10)-i;return(r=(s=s>o?o:s)+parseInt(e.length,10))>o&&(r=o,this.log("End range automatically set to the max value of "+o)),s<0||r-s<0||s>o||r>o?(a=!1,this.log("Invalid range: "+JSON.stringify(e)),this.opt.noMatch(e)):""===n.substring(s,r).replace(/\s+/g,"")&&(a=!1,this.log("Skipping whitespace only range: "+JSON.stringify(e)),this.opt.noMatch(e)),{start:s,end:r,valid:a}}},{key:"getTextNodes",value:function(e){var t=this,n="",r=[];this.iterator.forEachNode(NodeFilter.SHOW_TEXT,(function(e){r.push({start:n.length,end:(n+=e.textContent).length,node:e})}),(function(e){return t.matchesExclude(e.parentNode)?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT}),(function(){e({value:n,nodes:r})}))}},{key:"matchesExclude",value:function(e){return a.matches(e,this.opt.exclude.concat(["script","style","title","head","html"]))}},{key:"wrapRangeInTextNode",value:function(e,t,n){var r=this.opt.element?this.opt.element:"mark",a=e.splitText(t),o=a.splitText(n-t),i=document.createElement(r);return i.setAttribute("data-markjs","true"),this.opt.className&&i.setAttribute("class",this.opt.className),i.textContent=a.textContent,a.parentNode.replaceChild(i,a),o}},{key:"wrapRangeInMappedTextNode",value:function(e,t,n,r,a){var o=this;e.nodes.every((function(i,s){var l=e.nodes[s+1];if(void 0===l||l.start>t){if(!r(i.node))return!1;var c=t-i.start,u=(n>i.end?i.end:n)-i.start,d=e.value.substr(0,i.start),f=e.value.substr(u+i.start);if(i.node=o.wrapRangeInTextNode(i.node,c,u),e.value=d+f,e.nodes.forEach((function(t,n){n>=s&&(e.nodes[n].start>0&&n!==s&&(e.nodes[n].start-=u),e.nodes[n].end-=u)})),n-=u,a(i.node.previousSibling,i.start),!(n>i.end))return!1;t=i.end}return!0}))}},{key:"wrapMatches",value:function(e,t,n,r,a){var o=this,i=0===t?0:t+1;this.getTextNodes((function(t){t.nodes.forEach((function(t){t=t.node;for(var a=void 0;null!==(a=e.exec(t.textContent))&&""!==a[i];)if(n(a[i],t)){var s=a.index;if(0!==i)for(var l=1;l{"use strict";n.r(t)},2295:(e,t,n)=>{"use strict";n.r(t)},4865:function(e,t,n){var r,a;r=function(){var e,t,n={version:"0.2.0"},r=n.settings={minimum:.08,easing:"ease",positionUsing:"",speed:200,trickle:!0,trickleRate:.02,trickleSpeed:800,showSpinner:!0,barSelector:'[role="bar"]',spinnerSelector:'[role="spinner"]',parent:"body",template:'
'};function a(e,t,n){return en?n:e}function o(e){return 100*(-1+e)}function i(e,t,n){var a;return(a="translate3d"===r.positionUsing?{transform:"translate3d("+o(e)+"%,0,0)"}:"translate"===r.positionUsing?{transform:"translate("+o(e)+"%,0)"}:{"margin-left":o(e)+"%"}).transition="all "+t+"ms "+n,a}n.configure=function(e){var t,n;for(t in e)void 0!==(n=e[t])&&e.hasOwnProperty(t)&&(r[t]=n);return this},n.status=null,n.set=function(e){var t=n.isStarted();e=a(e,r.minimum,1),n.status=1===e?null:e;var o=n.render(!t),c=o.querySelector(r.barSelector),u=r.speed,d=r.easing;return o.offsetWidth,s((function(t){""===r.positionUsing&&(r.positionUsing=n.getPositioningCSS()),l(c,i(e,u,d)),1===e?(l(o,{transition:"none",opacity:1}),o.offsetWidth,setTimeout((function(){l(o,{transition:"all "+u+"ms linear",opacity:0}),setTimeout((function(){n.remove(),t()}),u)}),u)):setTimeout(t,u)})),this},n.isStarted=function(){return"number"==typeof n.status},n.start=function(){n.status||n.set(0);var e=function(){setTimeout((function(){n.status&&(n.trickle(),e())}),r.trickleSpeed)};return r.trickle&&e(),this},n.done=function(e){return e||n.status?n.inc(.3+.5*Math.random()).set(1):this},n.inc=function(e){var t=n.status;return t?("number"!=typeof e&&(e=(1-t)*a(Math.random()*t,.1,.95)),t=a(t+e,0,.994),n.set(t)):n.start()},n.trickle=function(){return n.inc(Math.random()*r.trickleRate)},e=0,t=0,n.promise=function(r){return r&&"resolved"!==r.state()?(0===t&&n.start(),e++,t++,r.always((function(){0==--t?(e=0,n.done()):n.set((e-t)/e)})),this):this},n.render=function(e){if(n.isRendered())return document.getElementById("nprogress");u(document.documentElement,"nprogress-busy");var t=document.createElement("div");t.id="nprogress",t.innerHTML=r.template;var a,i=t.querySelector(r.barSelector),s=e?"-100":o(n.status||0),c=document.querySelector(r.parent);return l(i,{transition:"all 0 linear",transform:"translate3d("+s+"%,0,0)"}),r.showSpinner||(a=t.querySelector(r.spinnerSelector))&&p(a),c!=document.body&&u(c,"nprogress-custom-parent"),c.appendChild(t),t},n.remove=function(){d(document.documentElement,"nprogress-busy"),d(document.querySelector(r.parent),"nprogress-custom-parent");var e=document.getElementById("nprogress");e&&p(e)},n.isRendered=function(){return!!document.getElementById("nprogress")},n.getPositioningCSS=function(){var e=document.body.style,t="WebkitTransform"in e?"Webkit":"MozTransform"in e?"Moz":"msTransform"in e?"ms":"OTransform"in e?"O":"";return t+"Perspective"in e?"translate3d":t+"Transform"in e?"translate":"margin"};var s=function(){var e=[];function t(){var n=e.shift();n&&n(t)}return function(n){e.push(n),1==e.length&&t()}}(),l=function(){var e=["Webkit","O","Moz","ms"],t={};function n(e){return e.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,(function(e,t){return t.toUpperCase()}))}function r(t){var n=document.body.style;if(t in n)return t;for(var r,a=e.length,o=t.charAt(0).toUpperCase()+t.slice(1);a--;)if((r=e[a]+o)in n)return r;return t}function a(e){return e=n(e),t[e]||(t[e]=r(e))}function o(e,t,n){t=a(t),e.style[t]=n}return function(e,t){var n,r,a=arguments;if(2==a.length)for(n in t)void 0!==(r=t[n])&&t.hasOwnProperty(n)&&o(e,n,r);else o(e,a[1],a[2])}}();function c(e,t){return("string"==typeof e?e:f(e)).indexOf(" "+t+" ")>=0}function u(e,t){var n=f(e),r=n+t;c(n,t)||(e.className=r.substring(1))}function d(e,t){var n,r=f(e);c(e,t)&&(n=r.replace(" "+t+" "," "),e.className=n.substring(1,n.length-1))}function f(e){return(" "+(e.className||"")+" ").replace(/\s+/gi," ")}function p(e){e&&e.parentNode&&e.parentNode.removeChild(e)}return n},void 0===(a="function"==typeof r?r.call(t,n,t,e):r)||(e.exports=a)},7418:e=>{"use strict";var t=Object.getOwnPropertySymbols,n=Object.prototype.hasOwnProperty,r=Object.prototype.propertyIsEnumerable;e.exports=function(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var t={},n=0;n<10;n++)t["_"+String.fromCharCode(n)]=n;if("0123456789"!==Object.getOwnPropertyNames(t).map((function(e){return t[e]})).join(""))return!1;var r={};return"abcdefghijklmnopqrst".split("").forEach((function(e){r[e]=e})),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},r)).join("")}catch(a){return!1}}()?Object.assign:function(e,a){for(var o,i,s=function(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}(e),l=1;l{!function(e){var t=/\b(?:abstract|assert|boolean|break|byte|case|catch|char|class|const|continue|default|do|double|else|enum|exports|extends|final|finally|float|for|goto|if|implements|import|instanceof|int|interface|long|module|native|new|non-sealed|null|open|opens|package|permits|private|protected|provides|public|record(?!\s*[(){}[\]<>=%~.:,;?+\-*/&|^])|requires|return|sealed|short|static|strictfp|super|switch|synchronized|this|throw|throws|to|transient|transitive|try|uses|var|void|volatile|while|with|yield)\b/,n=/(?:[a-z]\w*\s*\.\s*)*(?:[A-Z]\w*\s*\.\s*)*/.source,r={pattern:RegExp(/(^|[^\w.])/.source+n+/[A-Z](?:[\d_A-Z]*[a-z]\w*)?\b/.source),lookbehind:!0,inside:{namespace:{pattern:/^[a-z]\w*(?:\s*\.\s*[a-z]\w*)*(?:\s*\.)?/,inside:{punctuation:/\./}},punctuation:/\./}};e.languages.java=e.languages.extend("clike",{string:{pattern:/(^|[^\\])"(?:\\.|[^"\\\r\n])*"/,lookbehind:!0,greedy:!0},"class-name":[r,{pattern:RegExp(/(^|[^\w.])/.source+n+/[A-Z]\w*(?=\s+\w+\s*[;,=()]|\s*(?:\[[\s,]*\]\s*)?::\s*new\b)/.source),lookbehind:!0,inside:r.inside},{pattern:RegExp(/(\b(?:class|enum|extends|implements|instanceof|interface|new|record|throws)\s+)/.source+n+/[A-Z]\w*\b/.source),lookbehind:!0,inside:r.inside}],keyword:t,function:[e.languages.clike.function,{pattern:/(::\s*)[a-z_]\w*/,lookbehind:!0}],number:/\b0b[01][01_]*L?\b|\b0x(?:\.[\da-f_p+-]+|[\da-f_]+(?:\.[\da-f_p+-]+)?)\b|(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?\d[\d_]*)?[dfl]?/i,operator:{pattern:/(^|[^.])(?:<<=?|>>>?=?|->|--|\+\+|&&|\|\||::|[?:~]|[-+*/%&|^!=<>]=?)/m,lookbehind:!0},constant:/\b[A-Z][A-Z_\d]+\b/}),e.languages.insertBefore("java","string",{"triple-quoted-string":{pattern:/"""[ \t]*[\r\n](?:(?:"|"")?(?:\\.|[^"\\]))*"""/,greedy:!0,alias:"string"},char:{pattern:/'(?:\\.|[^'\\\r\n]){1,6}'/,greedy:!0}}),e.languages.insertBefore("java","class-name",{annotation:{pattern:/(^|[^.])@\w+(?:\s*\.\s*\w+)*/,lookbehind:!0,alias:"punctuation"},generics:{pattern:/<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&))*>)*>)*>)*>/,inside:{"class-name":r,keyword:t,punctuation:/[<>(),.:]/,operator:/[?&|]/}},import:[{pattern:RegExp(/(\bimport\s+)/.source+n+/(?:[A-Z]\w*|\*)(?=\s*;)/.source),lookbehind:!0,inside:{namespace:r.inside.namespace,punctuation:/\./,operator:/\*/,"class-name":/\w+/}},{pattern:RegExp(/(\bimport\s+static\s+)/.source+n+/(?:\w+|\*)(?=\s*;)/.source),lookbehind:!0,alias:"static",inside:{namespace:r.inside.namespace,static:/\b\w+$/,punctuation:/\./,operator:/\*/,"class-name":/\w+/}}],namespace:{pattern:RegExp(/(\b(?:exports|import(?:\s+static)?|module|open|opens|package|provides|requires|to|transitive|uses|with)\s+)(?!)[a-z]\w*(?:\.[a-z]\w*)*\.?/.source.replace(//g,(function(){return t.source}))),lookbehind:!0,inside:{punctuation:/\./}}})}(Prism)},2334:()=>{!function(e){e.languages.kotlin=e.languages.extend("clike",{keyword:{pattern:/(^|[^.])\b(?:abstract|actual|annotation|as|break|by|catch|class|companion|const|constructor|continue|crossinline|data|do|dynamic|else|enum|expect|external|final|finally|for|fun|get|if|import|in|infix|init|inline|inner|interface|internal|is|lateinit|noinline|null|object|open|operator|out|override|package|private|protected|public|reified|return|sealed|set|super|suspend|tailrec|this|throw|to|try|typealias|val|var|vararg|when|where|while)\b/,lookbehind:!0},function:[{pattern:/(?:`[^\r\n`]+`|\b\w+)(?=\s*\()/,greedy:!0},{pattern:/(\.)(?:`[^\r\n`]+`|\w+)(?=\s*\{)/,lookbehind:!0,greedy:!0}],number:/\b(?:0[xX][\da-fA-F]+(?:_[\da-fA-F]+)*|0[bB][01]+(?:_[01]+)*|\d+(?:_\d+)*(?:\.\d+(?:_\d+)*)?(?:[eE][+-]?\d+(?:_\d+)*)?[fFL]?)\b/,operator:/\+[+=]?|-[-=>]?|==?=?|!(?:!|==?)?|[\/*%<>]=?|[?:]:?|\.\.|&&|\|\||\b(?:and|inv|or|shl|shr|ushr|xor)\b/}),delete e.languages.kotlin["class-name"];var t={"interpolation-punctuation":{pattern:/^\$\{?|\}$/,alias:"punctuation"},expression:{pattern:/[\s\S]+/,inside:e.languages.kotlin}};e.languages.insertBefore("kotlin","string",{"string-literal":[{pattern:/"""(?:[^$]|\$(?:(?!\{)|\{[^{}]*\}))*?"""/,alias:"multiline",inside:{interpolation:{pattern:/\$(?:[a-z_]\w*|\{[^{}]*\})/i,inside:t},string:/[\s\S]+/}},{pattern:/"(?:[^"\\\r\n$]|\\.|\$(?:(?!\{)|\{[^{}]*\}))*"/,alias:"singleline",inside:{interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$(?:[a-z_]\w*|\{[^{}]*\})/i,lookbehind:!0,inside:t},string:/[\s\S]+/}}],char:{pattern:/'(?:[^'\\\r\n]|\\(?:.|u[a-fA-F0-9]{0,4}))'/,greedy:!0}}),delete e.languages.kotlin.string,e.languages.insertBefore("kotlin","keyword",{annotation:{pattern:/\B@(?:\w+:)?(?:[A-Z]\w*|\[[^\]]+\])/,alias:"builtin"}}),e.languages.insertBefore("kotlin","function",{label:{pattern:/\b\w+@|@\w+\b/,alias:"symbol"}}),e.languages.kt=e.languages.kotlin,e.languages.kts=e.languages.kotlin}(Prism)},2886:()=>{Prism.languages.scala=Prism.languages.extend("java",{"triple-quoted-string":{pattern:/"""[\s\S]*?"""/,greedy:!0,alias:"string"},string:{pattern:/("|')(?:\\.|(?!\1)[^\\\r\n])*\1/,greedy:!0},keyword:/<-|=>|\b(?:abstract|case|catch|class|def|derives|do|else|enum|extends|extension|final|finally|for|forSome|given|if|implicit|import|infix|inline|lazy|match|new|null|object|opaque|open|override|package|private|protected|return|sealed|self|super|this|throw|trait|transparent|try|type|using|val|var|while|with|yield)\b/,number:/\b0x(?:[\da-f]*\.)?[\da-f]+|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e\d+)?[dfl]?/i,builtin:/\b(?:Any|AnyRef|AnyVal|Boolean|Byte|Char|Double|Float|Int|Long|Nothing|Short|String|Unit)\b/,symbol:/'[^\d\s\\]\w*/}),Prism.languages.insertBefore("scala","triple-quoted-string",{"string-interpolation":{pattern:/\b[a-z]\w*(?:"""(?:[^$]|\$(?:[^{]|\{(?:[^{}]|\{[^{}]*\})*\}))*?"""|"(?:[^$"\r\n]|\$(?:[^{]|\{(?:[^{}]|\{[^{}]*\})*\}))*")/i,greedy:!0,inside:{id:{pattern:/^\w+/,greedy:!0,alias:"function"},escape:{pattern:/\\\$"|\$[$"]/,greedy:!0,alias:"symbol"},interpolation:{pattern:/\$(?:\w+|\{(?:[^{}]|\{[^{}]*\})*\})/,greedy:!0,inside:{punctuation:/^\$\{?|\}$/,expression:{pattern:/[\s\S]+/,inside:Prism.languages.scala}}},string:/[\s\S]+/}}}),delete Prism.languages.scala["class-name"],delete Prism.languages.scala.function,delete Prism.languages.scala.constant},8296:(e,t,n)=>{var r={"./prism-java":2503,"./prism-kotlin":2334,"./prism-scala":2886};function a(e){var t=o(e);return n(t)}function o(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}a.keys=function(){return Object.keys(r)},a.resolve=o,e.exports=a,a.id=8296},2703:(e,t,n)=>{"use strict";var r=n(414);function a(){}function o(){}o.resetWarningCache=a,e.exports=function(){function e(e,t,n,a,o,i){if(i!==r){var s=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw s.name="Invariant Violation",s}}function t(){return e}e.isRequired=e;var n={array:e,bigint:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:o,resetWarningCache:a};return n.PropTypes=n,n}},5697:(e,t,n)=>{e.exports=n(2703)()},414:e=>{"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},4448:(e,t,n)=>{"use strict";var r=n(7294),a=n(7418),o=n(3840);function i(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n