From 4ed2b4719c8da65b64596d9f87832afce013fb17 Mon Sep 17 00:00:00 2001 From: EwenQuim Date: Thu, 5 Dec 2024 07:22:58 +0100 Subject: [PATCH 001/138] demo: Updated example --- examples/full-app-gourmet/views/views.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/examples/full-app-gourmet/views/views.go b/examples/full-app-gourmet/views/views.go index 90b6e1c4..d583f907 100644 --- a/examples/full-app-gourmet/views/views.go +++ b/examples/full-app-gourmet/views/views.go @@ -31,8 +31,12 @@ func (rs Resource) Routes(s *fuego.Server) { fuego.Get(s, "/healthy", rs.healthyRecipes) // Public Chunks - fuego.Get(s, "/recipes-list", rs.showRecipesList) - fuego.Get(s, "/search", rs.searchRecipes).AddError(http.StatusUnauthorized, "Authorization Error", + fuego.Get(s, "/recipes-list", rs.showRecipesList, + option.Query("search", "Search query", param.Example("example", "Galette des Rois")), + ) + fuego.Get(s, "/search", rs.searchRecipes, + option.Query("q", "Search query", param.Required(), param.Example("example", "Galette des Rois")), + option.AddError(http.StatusUnauthorized, "Authorization Error"), option.AddError(500, "My Server Error"), ) fuego.Get(s, "/ingredients/preselect-unit", rs.unitPreselected, From 4deaaae1b8b53c68cc0c49c452c4f992dc068210 Mon Sep 17 00:00:00 2001 From: EwenQuim Date: Thu, 5 Dec 2024 07:23:57 +0100 Subject: [PATCH 002/138] docs: Rename controllers to controller --- documentation/docs/tutorials/02-crud.md | 28 ++++++++++++------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/documentation/docs/tutorials/02-crud.md b/documentation/docs/tutorials/02-crud.md index 918af6cb..cf1ea514 100644 --- a/documentation/docs/tutorials/02-crud.md +++ b/documentation/docs/tutorials/02-crud.md @@ -21,9 +21,9 @@ to play with data. It's a form of **dependency injection** that we chose to use for the code generator of Fuego, but you can implement it in any way you want. To implement the service, you need to slightly modify the -generated `controllers/books.go` and `main.go` files. +generated `controller/books.go` and `main.go` files. -```go title="controllers/books.go" {8-9,28-42} showLineNumbers +```go title="controller/books.go" {8-9,28-42} showLineNumbers package controller import ( @@ -79,7 +79,7 @@ import ( "github.com/go-fuego/fuego" // ADD NEXT LINE - "hello-fuego/controllers" + "hello-fuego/controller" ) func main() { @@ -87,8 +87,8 @@ func main() { // .... // Declare the resource - booksResources := controllers.BooksResources{ - BooksService: controllers.RealBooksService{}, + booksResources := controller.BooksResources{ + BooksService: controller.RealBooksService{}, // Other services & dependencies, like a DB etc. } @@ -125,36 +125,36 @@ package main import ( "github.com/go-fuego/fuego" - "hello-fuego/controllers" + "hello-fuego/controller" ) func main() { s := fuego.NewServer() // List all books - fuego.Get(s, "/books", controllers.GetBooks) + fuego.Get(s, "/books", controller.GetBooks) // Create a new book - fuego.Post(s, "/books", controllers.CreateBook) + fuego.Post(s, "/books", controller.CreateBook) // Get a book by id - fuego.Get(s, "/books/:id", controllers.GetBook) + fuego.Get(s, "/books/:id", controller.GetBook) // Update a book by id - fuego.Put(s, "/books/:id", controllers.UpdateBook) + fuego.Put(s, "/books/:id", controller.UpdateBook) // Update a book by id - fuego.Patch(s, "/books/:id", controllers.UpdateBook) + fuego.Patch(s, "/books/:id", controller.UpdateBook) // Delete a book by id - fuego.Delete(s, "/books/:id", controllers.DeleteBook) + fuego.Delete(s, "/books/:id", controller.DeleteBook) s.Run() } ``` -```go title="controllers/books.go" -package controllers +```go title="controller/books.go" +package controller import ( "github.com/go-fuego/fuego" From 57f1083dfa29b5b4f4c98f859918d606f59abf52 Mon Sep 17 00:00:00 2001 From: EwenQuim Date: Thu, 5 Dec 2024 07:26:47 +0100 Subject: [PATCH 003/138] docs: Fixed DeleteBook signature in CRUD tutorial --- documentation/docs/tutorials/02-crud.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/documentation/docs/tutorials/02-crud.md b/documentation/docs/tutorials/02-crud.md index cf1ea514..74c7b202 100644 --- a/documentation/docs/tutorials/02-crud.md +++ b/documentation/docs/tutorials/02-crud.md @@ -189,9 +189,9 @@ func UpdateBook(c *fuego.ContextWithBody[Book]) (Book, error) { return Book{}, nil } -func DeleteBook(c *fuego.ContextNoBody) error { +func DeleteBook(c *fuego.ContextNoBody) (any, error) { // Your code here - return nil + return nil, nil } ``` From 6e366c084b80d9f174f0344533d1070d86b0234e Mon Sep 17 00:00:00 2001 From: EwenQuim Date: Thu, 5 Dec 2024 18:01:22 +0100 Subject: [PATCH 004/138] Adds Path parameter declaration with start-time safety checks --- openapi.go | 12 +++++++++++- openapi_operations.go | 1 + option.go | 15 +++++++++++++++ option/option.go | 11 +++++++++++ option_test.go | 33 +++++++++++++++++++++++++++++++++ 5 files changed, 71 insertions(+), 1 deletion(-) diff --git a/openapi.go b/openapi.go index f8673f01..5974ef1d 100644 --- a/openapi.go +++ b/openapi.go @@ -191,8 +191,11 @@ func RegisterOpenAPIOperation[T, B any](s *Server, route Route[T, B]) (*openapi3 response := openapi3.NewResponse().WithDescription("OK").WithContent(content) route.Operation.AddResponse(200, response) - // Path parameters + // Automatically add non-declared Path parameters for _, pathParam := range parsePathParams(route.Path) { + if exists := route.Operation.Parameters.GetByInAndName("path", pathParam); exists != nil { + continue + } parameter := openapi3.NewPathParameter(pathParam) parameter.Schema = openapi3.NewStringSchema().NewRef() if strings.HasSuffix(pathParam, "...") { @@ -201,6 +204,13 @@ func RegisterOpenAPIOperation[T, B any](s *Server, route Route[T, B]) (*openapi3 route.Operation.AddParameter(parameter) } + for _, params := range route.Operation.Parameters { + if params.Value.In == "path" { + if !strings.Contains(route.Path, "{"+params.Value.Name) { + return nil, fmt.Errorf("path parameter '%s' is not declared in the path", params.Value.Name) + } + } + } s.OpenApiSpec.AddOperation(route.Path, route.Method, route.Operation) diff --git a/openapi_operations.go b/openapi_operations.go index 99db4145..43087a11 100644 --- a/openapi_operations.go +++ b/openapi_operations.go @@ -9,6 +9,7 @@ import ( type ParamType string // Query, Header, Cookie const ( + PathParamType ParamType = "path" QueryParamType ParamType = "query" HeaderParamType ParamType = "header" CookieParamType ParamType = "cookie" diff --git a/option.go b/option.go index 04ef7d20..9dabaa43 100644 --- a/option.go +++ b/option.go @@ -101,6 +101,21 @@ func OptionCookie(name, description string, options ...func(*OpenAPIParam)) func } } +// Declare a path parameter for the route. +// This will be added to the OpenAPI spec. +// It will be marked as required by default by Fuego. +// Example: +// +// Path("id", "ID of the item") +// +// The list of options is in the param package. +func OptionPath(name, description string, options ...func(*OpenAPIParam)) func(*BaseRoute) { + options = append(options, ParamDescription(description), paramType(PathParamType), ParamRequired()) + return func(r *BaseRoute) { + OptionParam(name, options...)(r) + } +} + func paramType(paramType ParamType) func(*OpenAPIParam) { return func(param *OpenAPIParam) { param.Type = paramType diff --git a/option/option.go b/option/option.go index 487b4f6d..59c9ea57 100644 --- a/option/option.go +++ b/option/option.go @@ -64,6 +64,17 @@ var Header = fuego.OptionHeader // The list of options is in the param package. var Cookie = fuego.OptionCookie +// Declare a path parameter for the route. +// This will be added to the OpenAPI spec. +// It will be marked as required by default by Fuego. +// If not set explicitly, the parameter will still be declared on the spec. +// Example: +// +// Path("id", "ID of the item", param.Required()) +// +// The list of options is in the param package. +var Path = fuego.OptionPath + // Registers a parameter for the route. Prefer using the [Query], [QueryInt], [Header], [Cookie] shortcuts. var Param = fuego.OptionParam diff --git a/option_test.go b/option_test.go index 9053813a..9733ba0c 100644 --- a/option_test.go +++ b/option_test.go @@ -292,6 +292,39 @@ func TestQuery(t *testing.T) { }) } +func TestPath(t *testing.T) { + t.Run("Path parameter is automatically declared for the route", func(t *testing.T) { + s := fuego.NewServer() + + fuego.Get(s, "/test/{id}", helloWorld) + + require.Equal(t, "id", s.OpenApiSpec.Paths.Find("/test/{id}").Get.Parameters.GetByInAndName("path", "id").Name) + require.Equal(t, "", s.OpenApiSpec.Paths.Find("/test/{id}").Get.Parameters.GetByInAndName("path", "id").Description) + }) + + t.Run("Declare explicitely an existing path parameter for the route", func(t *testing.T) { + s := fuego.NewServer() + + fuego.Get(s, "/test/{id}", helloWorld, + fuego.OptionPath("id", "some id", param.Example("123", "123"), param.Nullable()), + ) + + require.Equal(t, "id", s.OpenApiSpec.Paths.Find("/test/{id}").Get.Parameters.GetByInAndName("path", "id").Name) + require.Equal(t, "some id", s.OpenApiSpec.Paths.Find("/test/{id}").Get.Parameters.GetByInAndName("path", "id").Description) + require.Equal(t, true, s.OpenApiSpec.Paths.Find("/test/{id}").Get.Parameters.GetByInAndName("path", "id").Required, "path parameter is forced to be required") + }) + + t.Run("Declare explicitely a non-existing path parameter for the route panics", func(t *testing.T) { + s := fuego.NewServer() + + require.Panics(t, func() { + fuego.Get(s, "/test/{id}", helloWorld, + fuego.OptionPath("not-existing-in-url", "some id"), + ) + }) + }) +} + func TestRequestContentType(t *testing.T) { t.Run("Declare a request content type for the route", func(t *testing.T) { s := fuego.NewServer() From ab3153df4f5531fbd022cce58fc97bfe4e219ce3 Mon Sep 17 00:00:00 2001 From: EwenQuim Date: Thu, 5 Dec 2024 18:24:02 +0100 Subject: [PATCH 005/138] Updated golden file to include path parameter example --- examples/petstore/controllers/pets.go | 4 +++- .../lib/testdata/doc/openapi.golden.json | 18 ++++++++++++------ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/examples/petstore/controllers/pets.go b/examples/petstore/controllers/pets.go index 9b7dd7cb..e5103d49 100644 --- a/examples/petstore/controllers/pets.go +++ b/examples/petstore/controllers/pets.go @@ -40,7 +40,9 @@ func (rs PetsResources) Routes(s *fuego.Server) { option.AddError(409, "Conflict: Pet with the same name already exists"), ) - fuego.Get(petsGroup, "/{id}", rs.getPets) + fuego.Get(petsGroup, "/{id}", rs.getPets, + option.Path("id", "Pet ID", param.Example("example", "123")), + ) fuego.Get(petsGroup, "/by-name/{name...}", rs.getPetByName) fuego.Put(petsGroup, "/{id}", rs.putPets) fuego.Put(petsGroup, "/{id}/json", rs.putPets, diff --git a/examples/petstore/lib/testdata/doc/openapi.golden.json b/examples/petstore/lib/testdata/doc/openapi.golden.json index 45af95ea..f57b45a5 100644 --- a/examples/petstore/lib/testdata/doc/openapi.golden.json +++ b/examples/petstore/lib/testdata/doc/openapi.golden.json @@ -696,17 +696,23 @@ } }, { - "description": "header description", - "in": "header", - "name": "X-Header", + "description": "Pet ID", + "examples": { + "example": { + "value": "123" + } + }, + "in": "path", + "name": "id", + "required": true, "schema": { "type": "string" } }, { - "in": "path", - "name": "id", - "required": true, + "description": "header description", + "in": "header", + "name": "X-Header", "schema": { "type": "string" } From a91d92b41a0aba483fd5dd79de2f312457f1111f Mon Sep 17 00:00:00 2001 From: EwenQuim Date: Thu, 5 Dec 2024 18:24:49 +0100 Subject: [PATCH 006/138] Fix typos in test names --- option_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/option_test.go b/option_test.go index 9733ba0c..da0afb69 100644 --- a/option_test.go +++ b/option_test.go @@ -302,7 +302,7 @@ func TestPath(t *testing.T) { require.Equal(t, "", s.OpenApiSpec.Paths.Find("/test/{id}").Get.Parameters.GetByInAndName("path", "id").Description) }) - t.Run("Declare explicitely an existing path parameter for the route", func(t *testing.T) { + t.Run("Declare explicitly an existing path parameter for the route", func(t *testing.T) { s := fuego.NewServer() fuego.Get(s, "/test/{id}", helloWorld, @@ -314,7 +314,7 @@ func TestPath(t *testing.T) { require.Equal(t, true, s.OpenApiSpec.Paths.Find("/test/{id}").Get.Parameters.GetByInAndName("path", "id").Required, "path parameter is forced to be required") }) - t.Run("Declare explicitely a non-existing path parameter for the route panics", func(t *testing.T) { + t.Run("Declare explicitly a non-existing path parameter for the route panics", func(t *testing.T) { s := fuego.NewServer() require.Panics(t, func() { From bb60ad5c37a2adaea4e941b0ce26ed601a94735c Mon Sep 17 00:00:00 2001 From: EwenQuim Date: Thu, 5 Dec 2024 18:09:40 +0100 Subject: [PATCH 007/138] Declare custom 200 response --- openapi.go | 12 +++++++----- openapi_test.go | 24 ++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/openapi.go b/openapi.go index 5974ef1d..e8c260e3 100644 --- a/openapi.go +++ b/openapi.go @@ -185,11 +185,13 @@ func RegisterOpenAPIOperation[T, B any](s *Server, route Route[T, B]) (*openapi3 addResponse(s, route.Operation, openAPIGlobalResponse.Code, openAPIGlobalResponse.Description, openAPIGlobalResponse.ErrorType) } - // Response - 200 - responseSchema := SchemaTagFromType(s, *new(T)) - content := openapi3.NewContentWithSchemaRef(&responseSchema.SchemaRef, []string{"application/json", "application/xml"}) - response := openapi3.NewResponse().WithDescription("OK").WithContent(content) - route.Operation.AddResponse(200, response) + // Automatically add non-declared 200 Response + if route.Operation.Responses.Value("200") == nil { + responseSchema := SchemaTagFromType(s, *new(T)) + content := openapi3.NewContentWithSchemaRef(&responseSchema.SchemaRef, []string{"application/json", "application/xml"}) + response := openapi3.NewResponse().WithDescription("OK").WithContent(content) + route.Operation.AddResponse(200, response) + } // Automatically add non-declared Path parameters for _, pathParam := range parsePathParams(route.Path) { diff --git a/openapi_test.go b/openapi_test.go index d9720049..3828a875 100644 --- a/openapi_test.go +++ b/openapi_test.go @@ -4,6 +4,7 @@ import ( "bytes" "fmt" "io" + "net/http" "net/http/httptest" "os" "testing" @@ -526,3 +527,26 @@ func TestEmbeddedStructHandling(t *testing.T) { require.Equal(t, 100, outerSchema.Properties["field_b"].Value.Example) require.Equal(t, "B field in the outer struct", outerSchema.Properties["field_b"].Value.Description) } + +func TestDeclareCustom200Response(t *testing.T) { + // A custom option to add a custom response to the OpenAPI spec. + // The route returns a PNG image. + optionReturnsPNG := func(br *BaseRoute) { + response := openapi3.NewResponse() + response.WithDescription("Generated image") + response.WithContent(openapi3.NewContentWithSchema(nil, []string{"image/png"})) + br.Operation.AddResponse(200, response) + } + + s := NewServer() + + GetStd(s, "/image", func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "image/png") + w.Write([]byte("PNG image")) + }, optionReturnsPNG) + + openAPIResponse := s.OpenApiSpec.Paths.Find("/image").Get.Responses.Value("200") + require.Nil(t, openAPIResponse.Value.Content.Get("application/json")) + require.NotNil(t, openAPIResponse.Value.Content.Get("image/png")) + require.Equal(t, "Generated image", *openAPIResponse.Value.Description) +} From a8a8bb1fc9d2b26ad2083e0ed9d54d1f623a8e96 Mon Sep 17 00:00:00 2001 From: EwenQuim Date: Thu, 5 Dec 2024 18:18:34 +0100 Subject: [PATCH 008/138] Adds example to generate an image with a title for Opengraph --- .../Raleway-Regular.ttf | Bin 0 -> 130128 bytes examples/generate-opengraph-image/go.mod | 34 +++++ examples/generate-opengraph-image/go.sum | 73 +++++++++++ examples/generate-opengraph-image/main.go | 119 ++++++++++++++++++ go.work | 3 +- 5 files changed, 228 insertions(+), 1 deletion(-) create mode 100644 examples/generate-opengraph-image/Raleway-Regular.ttf create mode 100644 examples/generate-opengraph-image/go.mod create mode 100644 examples/generate-opengraph-image/go.sum create mode 100644 examples/generate-opengraph-image/main.go diff --git a/examples/generate-opengraph-image/Raleway-Regular.ttf b/examples/generate-opengraph-image/Raleway-Regular.ttf new file mode 100644 index 0000000000000000000000000000000000000000..252cad14a6c1179cf373ed30d79ece6510743ae1 GIT binary patch literal 130128 zcmeFa2bfgl-SB&a#!I><(q=BGm{Q6%iXKiY8)WEJ;j4G{%^yiI1tq zJSpah8pI@GH)u?ZH7Y2Gq9DEFg1a-{?|;sj-C5WL%$x7~uJ^hgxMpW}_MH3v_kN#M zS}B#v7pF>@H1qU1kIcBxt(4AJYS@F5=FA)Swcp;bMX82=DCL-O`kY~n-+ud&45ga+ zy*h8vWecyk`%Aw}AmoGMhcN-te__2tS7mG~Eln7`4oKc7J^^W{{A`R-M^zTUj@K0QkGOxliSOkh?Q)dEV`Lcjeuix7t6#KhFQQf49FUKQ4bn z{7|~Zff1_b+6T@sB|?Y@}W8}(yJCn-d8IlAE{d+2h=^0 z4eDNA_eHwZ{gHQcb7YTR5_w-=8QH9tM?TOiBOCOp$Vd8-$cK7$WQ$(I_m6Y0TfMEE zI#D@viMm8D<@?Kct%>xgAp7iNkNxcN9_#O9{T-~om-RQR2O^)UCn5*cdidYXt0!_; z7jb7mxpcWo)RlbS9*O8KUMnKK`a0fkj2r}x!}^xUC;HY%x4u1cMBl^btN8g5K3~oI zW03>wei+ye>*pe2RR9Es)e^A!Iy12kcv2?I?J z(0G9+5oof2#$!Vh?t^A!+CcW;yt;;QE!3clDk89EIvJXt9RRA2*>3D?ju&2owj|=?FV*2k%|%v=hAd z>MSVekL!_-@+lnI14s5kg99cv?%{n^WIJ@&1}Ap2<5qUu zsx*?3##gwdT9t#{rbKRl7LNnP9_aA`kbDdz&jLv|TyU%BxbiJza((0jwV79US~RSA<;*cK1cz&}rbG1w`5W>}Tf!AS_fqpihB&={l&~U{DGM^(z@5g=L}ImD_5S@nR* zfi{PrON3QkQ_mum&%?(6cbCJFX7F0X9m4l3c`fIz74Y{)Ww3G&D@R!Q6JS2V%12oF zC@^=kdN-?g1M^`hy@b`DMSgE()zx6UhS%fhNs=uYAH#!gpg#=s-L`JVLqCzTqtNV# zO{=5aX-U4{*806b-@_`0ZTb3yRSvRBza(4Q?g5)5Q`>7K{l(+IsY_8)@x=;x*~pX^nHmP$Jx9Va_>@ja~ZE|SmQcgH((uafwQ+_$HZFP#qaJxb5>zfAHmkHj%t1ym@^nw+E_H9@2Uv?+!037;;|?U_H(()p{4rSU z28%;r@G6i$0WG)b`H>&!1(EOTOH51geI(`wNX%V8xE%=hBKe=_m0)@czrPg<+!^^E z5FP@;)j;?V5IzNj4+7!;s05%n3^Z$iqz6cPfTRZ~_KLk?r)|jOK6cp04(Ja&i9=I& z>DtJ8v~HI^ojq^Fd)x%(w?{VV?;)*svFF{$hi2XT)F|+O9}D^^7W7jr=OO5@1&;Q> zQ8ygzfhLE5;?G>Y7Mg4ZlD`4T3qbNHobFa@u$)gsZU?F-uqKCr>{+<2;kLHvv`6hS zt?NE$wI7bVO^*A4x)%9rMi086#r(+Y(Cwda)eY^o!dVSxH5fhyhHJp^F_VUtHXH!2 zkM+%_P22_@_k#VCaN7Yb#Wrq&mK&g@SPtR#J8*lCsshs^V0z>jU$F%Z+6AWKD>j0u z_=>GyxyAMsZ>k6Qy=B2)0n?*kxfkw>zv#C8#iz)q!}b?0G)w%&el%+r7#y+f#sPF$ ze8xJUwfw1gvd7>EUK}Vz)56Nz$L;&z$^Aepmil>CUx?h?iAL3;`46hak*DC+E?`du zc3|eJdwJc5cfFt2Ls-T2k@Zl&NA2d-9eEoLe2P7PPdnJp7g?p_A}^qCZtP78x@Mqj zRp5~g{M&UW)a!zBB1tQt=*{5s4PGlF_aRMNk)-WVdk56s3$^z`?Y-dA11|f(WiPlK zf$Hz-zd`wv<5X&D;*`iw!Ru9UdJ$d-9}dEYgYaPwl-LU&#J-57+X8L}!D$=#2re6u zD)FX!ZQJ1kk2KR}i2v^5cMG}B@M5f}=zWVk^Os)x}okz(YT@&F57PthMY|$7k*Q z+=caC$aPmDXIA8}8%rZT3VX=w9<0wQetv}4YF?Jy^{5gclju=mHi=O8LG^u5{S&Az zk}sZd6Of2+J=7N=6{4R-;2yy4SdpX$X!?E2e6&L%${S5;_u7{E6QBqKg~Tu0fnqmO z^9hh_M{2g2zGkc~3wHw5pP|=#$iuV9xbXhRSR9F6lCd^x)nBp3Z(+IDVU5>Een<@S zE9CtMkp3D-KOm0TKpeAyIOa92kXZwH_hG5iklQRQMt0;SX!$s?%u)0p&W>d=&;^NQ z#P75qLlVpU3VnD1`reH``~w0_|`Fa2d?@4Cp3^jENEH)3^ehF2>i zzXofGp^u_7|FmPASE0bqpuj39unG$N5eobT3ao|#e}n=LqBk$HLl+WI1}*TlM2w5U zS7hfJxUeGfCe}FuJzj?vPW3WedW);q@tOG7k4(8)4-F33aoaX?o3X0Lk0|&WGUne(*g4e-9&}N70X?wk`0&$7ItM zSh{i)8XScNhuC>HxbKH=cx7VTThOCh+3_A|Wko*Z6>wlfpO2gp`JJ6%{0(l1=Xe^t z_W;RDNajwU*#k%7kk0i;=K<`t+w_NTp-)!a@GMfg4k_IO#E%29Sg?&i{WP4~j#T~& zPJKu;LM9*@NOvw|P!Ke<567ipc%{ruWGZ;OCbnZqvC1QP4FGGf| z#72Dq?n?Zz0tvhhiM<&su`==-TQVj3-i~CtvFJO%d_9~Oy6=PYd!T}3dHbRLJ~+P{ z$=swS4?&R^Y>GV9N0CRNfJGIF2YpawT_07Da42ISw^7PG6GNFbF_d}Arpy~QW!y28 zNwF!DYg48L%1HhZOBu;So;LlMSn5US*)p+_yuJX{EXw=?{rv>${B;QGcx>vdJBB*@ z2T*4%vLh5~hC=U~TKW)Pmn<2%IAF`gR%F5j*1gDsWaV#}nb$6?S~uB;Xsm%u_~3mS zbk8D#%7!17JbYwZDv^f-TOQ(&hkCHC0qX>0;R9r09~l1&jE~r|@DiBr0aM9b-UQ1x z!SWOMABOjbZQhGr{t)b<-r-YQ1H_B(GGl)6U7PKA---Q^c>f5J-vf4HljFe5gO@Z+ zFS!nVTu(f;8BDve;eweDf0c$u$U>5GkvKm)7VvW+HrA>FMEN+<#z-<@(bac}`#&M> z{{)P@ef+z|)ZHCmA{m}k2;%X+8ceo>$p=XB`$+L-c(fS_-UKEG)pU5XK1QGKv-SB= zuzL%hJq}je!Ri6^C|8qP$LRD6Nbi0dODh(54V`}ri?|L9*JB$tN1jw4L$B?8zALf~ z%>NtAH^9?3;OQe^zX|N0fTyoP0S^>d0|gF4fmA3E4^Q)u zn#GP1(OVILRCB~im4HDt7zhu$fqu6wff1nFZ(AR!o$Lb&i3WB6#SS3Y0R-FO)e)?{ zMC%jrGfQ}vD0d|}*=<<+{ygLX{EJB73qO>TEJ#@-OaAM*mWPf?qS!R#AOm&J}(v#?x*n6KUi1%)<)Jl%6f-bZzt>RW<9|| zJcg_%RST&th{u#Fka){|DwjOjtrn|9b&ZNw*YaA4@4f|(c^gpQLza0julv~PetiA| zaPll(XA4*1z;ZaTg6~(Vd{*COL%W|iHGv&=vcnGjoN^-ZC2A~{k%w4gedPO4;8lF! zR(#;cL}Xiu54XYt@eq$AA%6qvcYu1Mt?`Fg_YhDYL<07*u2e-1ApyIn=}o{^O(B|E zOnxUkSV`n{3p?I}^}ZL2eji$YKd*;OZGRn!c!}L5nlg~*R3t&7DJRm9j5IVN4XHr! zK2YpNE`LS@o}gD@2_8WgR`dQC7R1ADl6AfSecpjS?+9(6$42O}k%*{;-%iBhOo1

Ju+^~#WURT46(-s?)n|Fu>&671rOhVhY}I>nlbx)U|ay-t@uOux*xti%P!Be z%cH;-0Y0%TA}`(W_q_q~@)+D$0}hY#{v47*H3qx47;1^GT!S24YsUD`!RwcROe&$z z0@>40%n4*qu+szV^jl)Z{rYC0`UbC+#Gn$d_h+zMponA>8`)_CI?+o$wI2$d#_F@p zh}D3`Zus8`eWjY)iHzL~ckTn8`|)uWCqyR`xXK4761Y-wBOm*@k<7(hZSm9KF2^8u zMQf9CSG;*w5H3ia^(gp$YIERc;Mr|!=HK9e)GJoO0m&XDZ{7_DK14pnZXCf19>iws zK^lbmN1*;5Xd<-?$r_~U*#ifpwzdm;NNw#CWK?QvlDA0R`4dy_-O!w95jr1bZ!2@T zpM4yB@&Xvg0dpMsC3)Bqu93Xbg0sJ-@&vk3j-9%N{iL3^3SaUFv|i1-)Y~4%hq=IF zD>ChZk`hs-u&#^RyMr3u8frDqs$qDBY1GLo@PSkCfs@rbc-^hC)lpTfdeD|$=pE)2 zfn#)%bQ+Oe4mo!|uUc$n9q;p1KrbNDTc{@MOL$+VMq}Yadbt{|uR#`WQMqVMq5iHa z!;(+aYq8Io-3`_=pp_4qiZeaN7Cgm4EdE~PW*2gE1f7&z>~{1=`1c7~bObHh10VOp zL!r%&Y}!1JtgeNJ+u`B8@K7rEYvJLC@bFzzgTxw2jpGt5-7>07S7K|Hn~|khS+RS#=o@Udd}Y)^8>Lg6teDdcZ=m=4jpcFj$Dc5c_@rERI6e0DPh1Y-VeFfa9;g zu?{#s0uHK5SciLn^Il%}sY>*#3`_6DW=hnQfYf9mFd> z?{D0g9?axX=SdE$bqcx%=Uz zX!ttTd<)5xe$tch@(4O!W=o0q!GYh4oF7CwK7lLUaOI$B1HR54(igf7tnT6cUS5{0 zzrl)!kPfM2N)=r?30|U!qe#amNXKDQIxO#S5D5|Qa0CgF7-kQ0z8g80I+*0k5>f1i z14m2?^%C|-0InywavN8^!If_S*KV$U!h}nD16LB8 zEC-$yd~Zpq)E5r2|5o<@i2Zl6zf?ZAu>Xhbzl|uwqNCKe#ZQV({Dam1&g#9a{zq2t zM#Jv~^NnEs9=@>~&6e2dRd#%x9Uli_k29tVdo zyV&uKiSZhCksSRf^0EhA-i9tqZSe@){{Ve{7ks44WkqPWlfm4@_jdzHf456$`#w8v zV@K%+eSpqLZ$

{{TT*% zF+H_s(U%vv*3we3+Xi;qh25t9hF;b2KA*K0u(nibFERJX6 zJ$b?0F9DrTz&kiu(anlpR`jx>j}?(R-WTB07ozu<@V<=KmAsboyIbkF-N`y4@d2RW zD>i{joC)jmSeX}D`5$=eh5Tj-cP!)kD|s!)bKNPk0o+riGP%AGh+2Utj(e)OrvivP zK$8eGi9nMGG>JAeQtccLG)~rZv!yr)kkY#D0XaY<~iR{XignnQcI@2MDC6ycGzxu)AamJJFs4ie2K(o7x~!s9~tPza9;;cZ zy_HxhOwQs$B7ImYt4}2r(=Awl5Af*kY3Wnlja|x#v04(B9BZ{6v8|T$Y$dkbgvB}x zO{FKcADYViLeyeOJ>W2~$n1ht6D58;i0-eXJ{k1@_YhM4}n0WFo}-L>%{1r?xVYXMy#7)_Vt9_2_2k zB$igP5G#(_4D277yIVeHJ2*&>Trv=`x{|T(1c!atL5ZbyfyYkl-~p`Exk#Vod!<(= zzD9iII{dF>950)@ZX&Du1e-0=*ve{DH}Szc*l{2D(iOp;#<7y%ydO&JC6<({#p560 zYA09kM*69svQf;>RvB?|JQBT@yG z8bUAo95Uk+tM{9xgUDwIQc|jlv{k?LqCb0ef36fy{wls9TBkl>=St#@_7n5&GjpX( zpx6ah9)l*kpvj}qWHt17$c(jmkj7<^YoYpeVD(LCu*udyiT!$6{WU25G8BIYYQMtD zFR|(Y^ho*)yP=8no@PKJ@ntgCa1;LNb}0Kj_;MHU-Oa8^wj`f0j=^3z!T22Pku}?M z10F}TYnItb+KII7q?5E8Ya|_k4~Q6~E3lKbcOZF!;~Ko~2JqYgp8o{Tew4s-n~H?MW*}KUvUka{vie|^)l*pA zZ?4`6UAnL#i;yYu5q9_~Qt=5=c?kLGHh0?&C#8e(2X=fNJG0)(7Krue)4{#NaBnl* zlNm1Qphy)t3^YP1;o=5%f166;e)N+$GH?@|tUl)}>?%35R9U2#v=GinY#`Z&3!mV` zCpfYD8k;XZU3|F1DqM#D4_Cz3jRdP5OYH-(u%&a8UZ0QWdaf^CXtEeB>6mxD`CMn;k!? zr7vKIh2XUa54D1KnST;_D>N;mwWCalY(RgdWBjgdT~@Jkw7>s8JHKu3EOR`vvj+=v z#FkK*J`nl&$dsLC=q~cI0O_!%TV7^o>7MRk=YL2|0S>HyQ(}jscvv{>V>&C77IxWB=SL6AgIF%?pk1VN5HIes? zP$QWso1i8V1)fISGEbeU&Qj;9^N0qQ5DBgz68y6Iin>94op|uubP~R!ZX+tZSN)jP z?pF_}ht$LBkK{0qt0&;`b80PC=LPjQ^>_8MdR@ImjI>_8qc*Ddu;m}9kJK);TOCr& zJgQHru=c7jsg0qj7V0>isFQTEPSL44O=szBoumCaUl-^?U8DoLSeNKhU8c)*g|5`p zUv-@xrWUY<-SCPcPDo^+oz(eW_lem+H&(GJU09uCLNp z>o4dP`UZWYzDa*g->ko_Z_&5v@95j~clGW1d-^VYx4uXJxBiX(y?#hD^`Tem$MhQg zxPDH*p#KIXWnRBt{p7fLeILKkM1c;|nz`YKSNRq$Tza({alz6{E>a=BEL0PhUjBv4 z)bwTYb@o;A+cU4aY|$0!oU5*C7_KhhYoof9m8>~`SjDTR*Fi{l46OzrudM9Qb9;8}0Z1u|I## zet#2-avpM&j~DQ>SG8(aqt$pdNzGxm`RaUifm*7r!?xb2ZbojttNsgW{Zjo({T?U; z8m+IuQW*NHz&i?QdRV;!U+du3tx)@Met#oZdBHFN50+0ozLHA3L-pXbBIbK7(qr&5 zbV5p?x)~kK1)mJ44pB=Zc-68kmEmcT_MyHhy=50q_tf;bexUd z8G@M(sipdKumd+F=o?7P-6n>=RKFML075T3uwbrdwqPW5Hu(8rzLuj6hMJ=*_&OiY zYpCn>#eDrX-qlb)p{Hi3UkUzD_aU_DW%TDGuuMc7^3ed1`xfNA3kkmnSzdwc-ebzB zNT~29PVGXYd}zcBB>ZM1`Y!!~`T1_a1U)%D3biTAalm&kd#z{nTGqS;d0)fz8vPVm z#%GxCqUjpi$khUu=yH#_lLcFq30J47gXfr#MRynY9uwW+eyZrl?8Ffo{j$DYWZ76_ zd>gsD)q2+(R3q_c-M3X!|pDKPzt6M~xhN#kI!UtT>_Y#=4BU;ejs43*lwK#G#W}&V z`c_o-iYyxWB41SGj_~gzC1F!ed-uyH1OILM`}@tCHf(z4eN%JZyJgc=^85En-@E6% zyM13#%6%2mKT{`=87Si!&3MlC#~U#Nemzfbnvrq3l_3hG&U zfzH(P^lbeDBsmfJ^C7wD6tW*c5^IpjVMwASku7N1a#Je5q^{H>(2gINviW`W-|9PX z;V18qJOFz4V;D!PDcNxsQ1yHpP`3np?-oG<|*Pxnag;D zXzy_%>R0ieZ&3aG7uNeVx&<5YrSD-|_fv7+sv6V|eAHo8r#@C4I$4d;NouT4Wj-NA zb?H1cfw`yIx*Yi^rF&gSKeLROVl&&KdOGN|4f{8MEzDj zqkgBKHLZ-qiIN)yzI$nG9H}%)m9z9l{p?|~~ z%saG`c&1l^8)B8n|5}v)wJ1bnwuk*+i}Jq~h3Mt~%%Tvv6lB4kO-M6ADRQLM)AxMos>`en0$0 zJvaP-{(iVB-20vB`mK$Qiqy})+!5&rAL!V)k)-8}@NZ@7;l@(6%2*EoIU%6aK$jpf zb|KM1k}5ISDV?3pVO3*k>gV~?fge-GJ>crWh9{|UA>xyy#5mwq7K+-#DwPTGhH`l| zgDpW~H&+{m-_TA&8C5KjQ0!(i@~09PJ2c_KODck%bVty^X34s$T~|#zJN)!nJ$LB9 zw`A|Ny(2enG_DT++(-k8fiUE$IidW7c%^c(Gt-lk;`0*nVxbX=4--Ii5c;{?ZE@NK ztS*m+#sh)!*+99E0jjaJttlhPC@C&)Y0Aht2EN-egN~|Xe`!Ybi0a}PKs(CwGt2xb zBWv<1!5CWC7++9(pmnmU3?*rmm=Nc6f{9Lc0b!aGW$&eg^h zItb2g{FgD=G2c(k=LR z3|>1XjjoNs>&DNg9%~bbo4_FfQ#F8LEHzy2UC$l;HsL0lPg6oU!lUE4<72HVi#sBL zgR{mnxM|QW!DHDHejnlLHw|Nk4HG?UHSX4*qt4(^!I0DuOino1IT-;o`M`&a@tVes zMO#_qZn+hHCP!u&_i(RR@wQMxR%V~==Khil4JU)?Ni122>5w9p*fWPCp;%a(s7!O_ zs@E;et!-k_O0aB6Ix{0%JA%d~W#y$6d1BV4nij6EtU0_61NR4SMP6>BANvL>`88Q( z9-}w>bHHJPw#Y2%U#TqZ2|3+LC)Q+Jt7n_bdcIm#-q4!GO6jsn!N@?Wxj;E$IKWP4 zk!^e~l%JEWRAGL0aZWLoa)8YiE7=s~OdKZMvX5Rg*UOmgQ0jB6rEG3(YRt;aaAPXl zirtwRSxt?tEzRY}h~2vCK%iP)Q&Y3EQ&VztVwl)jP+D40SXw$EGc`3UD>XIKKvBA42ETQxmciv$3FtSkD|dLLCj`>C{N7#%-c$Mu|iG*AOr@9tXsa2HBd0 zEq`|xRf%l!wJD*D+?=9ZW)dbi@!&ev*AvkGfC)vX*EX+m;hQfji{DhlK#rX(h%@oixsSM;{l z_@cfPc`Z`k3Z-e~&&$ey%5iQdb2vrBM;3MSl+$nI`!Y-ui@8if=pnJ!-V@<_{ZLqnWu;DNEW=((t*%yL zjzAz#8>lG>=I7;R`#f%^#DX;`+HmTi1X~V*09EDIE*Hvb$F>eB`-;M1KSeLfB-9F~ z24RrsN1^sK!#DY$!_cWF&*TGRS)g@tRrp~&uWWR6c5B0!NfXn8b$Q{v+UIX5&Io_; zU|wA?Ew!j7_tDDn!~MqEK-1V@>-?;=^IP(Umt}_!WR(rqo5Dx4N{8k78%o5^IOw)1 zBi$%9@u^nvA#WgMrR5<)>rIYiIMKFA5#+Es)I#M#p$(`O`|%K{biY( z)@N1Zr-s-3Ewd~yxw-l~Ma^ZIMrlrEV_x-y)TC*Z>81H8e@*e1>WiL8&MQf;YBgmj za@6>q@gk&Y3B{Eb=Vm7-x}8qwSyEWw!|-WH3KcEdr4^GehycOzbcgAO(oHGP%J$Sd zOsUVX1imdhiJ$9@+PX8YpLy;#f+JEJMvN{9oj<;~YSO~?!p>2RsUuT6rq8RI@})C} z>x)A-T+n$&S8+*0VPf;#OIk-QoijW+IJ~5=a!hqr=%TN&J?G|)Mx%nQ@lnoVeAG#H zt}CB>>4ceA<~Jr));H#~%x=pMj+!+rw|RI~QcH64*vZ8m7f!9xS;Nnt(J;Ox;4jVg zRdmd#tew?S8lO|1S5VjxNF6?NvFR6xKB(H3nsJ9O~9_@0@w)u^$dgv#;)e|l=1*I{~;Iu_EZIGC6~ zT7*Fd&o;@(EUAUs4hPP^f^t&2)0A3C$n=RRuD?nu6P|l2beD9k_w|#}z8?oSmCOmD zgqo^AVOBe|BX|^ z<<8E|j5E&Y-Fh-~pmBe`kQ;KkoDzE`_5-i#&6v#sai#@=vEE$Wl*5_E9q7wg^_x&y z=a}}k>dHW2HW8f9<23Nl(;oEUl*SLM&&y@$7MfS_NP!-!J<7?m3RuAndnG+3lO>dZ zx3)sTZkG!R(jPPujS_s*|LH2}tRmjYRj8X9#c&k6J#F=lmZ8a>tUI{Wj;$(mZBj#C zyFWX#KC!mz>N)i%;6uuYiKkcO`!c;HRn3hBjTzT_;!848e6HEfaTne&ZYZ9VjjGCV z)H{u$!s60+tBai#nMs8@jUMQvP+U${T8hwB>`_aS*7O6RWu7M3MrRB|9G9q&Nl??m z6O+{#rxJ+TN@^x@YYEIA(dOA<%Kz&4~F7~0eWE92D4)`wG4XDcN= znI0%BWj%TV`uEvVN65@;!()b`dDNuF*rp146q7?~m6eq>l{M8>Q7<4~wZ7jA5FWUc zlU}Wa2asKy=`jvL$bAyCtVu~v%_%f=oYXHEDGL_@NuzPCx`H_9gt=HuN{lnTmK*tJ zn6brAh%FN6`VS8!DMh%Q%1`kQldFD|(Z-bmnKYwSg_8u2qLLG2n}`%7fFPF8gbOuR z44qWkb-~!*{chai2_?qb5$D}BW!Bd|-=r@HEtyf%ySnc5B_<3K z4~)UT2n_g_)C|kN^sk-XzxJ$`CM}&@S~cy`vF{bM&uP8wwzfGV3XIa4sf*e>7f-Ix z=?$lk41}i#N6{^h#!f%M|G3FE11c0s@puaSc{!eRPg&K)!6I7lsC z>8Y)H;y`wVyIaEtg=5;3nKs~zSDjM-;=RB0YStxr6bzbT)>_4#M+>YHk#e~mg-TJV zER%@Sei?1y68%Q_N_}?tmmM9(+Kz}C72YS#6#38}As_J)`@kLIMC%^2GOIrdFV(k( z|ENpC8%B&UN=H1_{8x6dWxLIcJ(AUFp$wMGh1_Zs4y`>sob2b zjFjXAf1-aN1*N*y>eC*aRXo)jDmY#-@Pm?+GHVP;1+-X_rVp%a#!~o?u~p7~ayv2y z)I0m(ma}CuLKz;9C(RR6Z+AI`hK>Ci^cjelZt0Sap<|DwKzd;eDQ&fRyq}t}ycM`+ z9uF5qcHnBZe9~uTZ@T4|Vj+9e@XqJf zZ%msawt7hwAk>78#5>|Jxkx*#W_Zr$As(nwZi<{pq05y}oS=O^R+4Bq(TaxC?eb=< zByOkFd3_9w%~JL3jq3+7Mla&2y37vcB_N9l$q8u2Ksk&9vIgZw61CeSzziyZ-T@M5 zrj{`b6%b>^?)x46vSu7Molw7w2|VbjRMZDTV(Mvfl1xhyLu$9#%Q@b@PzySdGEh#9 z1?3D%tNp+@J|{)iC@eRz|NjTH2@ar5i4MlVlVR0a7euBRzrxn$sga?C%=DxL(tZ4Z zL|o;0QUGUWlqXAT%HNXvOBGyIN(mNsU?%(Grqfd~`1s~jtG`mwCLv*mF-HHit3|&$ z(O)y7ATTn!IH@8%E$B}%#`iu>0cMpkt+%+Oy(&8`vpy*r#lol*G`KTxBMP_g)dit^$>fj^sAKcObEW}xIJMXOk&<24Nmx6f>-#d#AAw~jMQ z#)B#)Rl8VCuSKI5WI>IB12u`=9mRg|cPeBx8lCc4>IixK0W*pY8n1?Wcbl& z?6#iR4KWE(%OQ4a5(PK^&(bTyt95pG8$sI>t=%R(Qs?@i@plRX-wdTxR+N{OmRQvm zheVds9;~OjFgz{Qa2eF%fK2+{PKQg{`Vwji-8nEUsS3zdNZ6K6!P6gVIfZ-Z`$umC z7Va~v2W9kG>J6)CP-wtK-CyWyZEKMLyTmwq(T$U@o!>b8bJtF4o;SWRwYB7mNu$mk zUs^SJVf&cNn|{1*^hHZMF1%^Nq^~X-m0i_dTsp3!an6$V(MxAFw2!%_HGH4YN^pM` z-0Ou_KB1MXZ|6So$&6MQOIm{Y+MSV^5PEn#x17Ydekj!~{pj z@-rAjwP5KnTBtXc2`uqu%pF4qfhL9wHWhSa){@Z|POYw*x_I=Nmlq7rKWAjajJCq! zQ8Vi=oc*;ww@#ngFk^8`+oI`p<644^^<^D1tLtWtDLHd?gT(oUiT@9Ykt;c!@kl7Y zx~jFMX?R_2)rjg510{h7*^-2Dv0SC~;qekOdw3XuhZ<$osfY#!ZQ{SP$Z@jblSb^KopfeiAuy%!v))`)Mju!S{vIhSk^A)>K!N75FpAe@%aFQL-Z%D$^%) zJE}Ye`CHJ+iD)1@B@C4wEP<-zL@1b(GJvY^5NV{76Zu2qKI;M=587s}g37XpS11?_ zy<>!JD5X1MhvZ{Us(W@(sCV?qbWrGZmT7;yOs*aYWesl-id9t<6=Y>FN!)2kKp$(qBM2!`)Ih~Nr?Pi4vA1OKw1TT(R z4BEJ37vh?h&$v=(;=i+q&j%AMnBXoTS#H_YI7T-~hgqKjAM}*Wk+mf{{iJO8T3RSn zl&KR=#s#rIRgtqe)Ah0tft=riEzFL>R3+P4Yl*Gum+?xvWA}%0s;a7LtB~@6HpAqa z5PNj2x+@HY7tbQneF~058m6D^_T%h?DdnePC!|t%3VtPgq~l~Jq1nu{EMNa^vu@Kg zc--(Y)X*%F(uw#iyNfV|);XGVT%{FTJ7 zXyDupeWDA6bQqHZ@zq%P4Hhc%_n>NHAvH;4}L1WMyJ zbKNYWVj@9u%|tIJkL(GnX%A+hI|0bbk!fff#6+>59dkM1gjo~zhf0sVgleV6$QX2| zO(U4)q*rdkXD6a9(bTkJLD!90T{W#^i{mCHH=I3VK}g`ApPW@Oec2>^arlR`Za$|O zanUM`)1P+&ZGXeS*TLe|m{6Ww2aESo zD~_#y`Pk2o%rFZ@%x+~GLPgqyB2i*_M3Nn-t*GvTu5ZgQpKNB9woKV&ubs$#>NH!~~+=ggDCppFn%3SzqF0 zw$e$Cn^?!A{%u%;kl|ql>SW#7R-LGX88)#CDcA+Kq;LjwMK7ch(_ah{bnV$TG2~X= z<#MU8WOPO6+nAD*g`*>Gif4WUbG}K367_H>Ph_>IFfT{ufSC;|afwwSGBiD`%rliz zh~onnCV~p4(?@;XjTTy>>$OGKu1VA|og-5>Ed%c1q#zSs$K2xbhlVkth06uYNtmH7HCYqzDQ-2=^CG%~I~&ctFN#P5C0j2D;&1WNim zUfNJr^)V;T=O+JFIw*Ak94-?a;&G!IrJH=ZM0=1_{ms+D8+GGp;l1B9{u;hO|2X_Y zc)4DD%X+cn5-*fT;{}|j)CZbUbrTbN4o~K+PCa4bL9HfiUS^bp|E^p2gcjJG3oET|Q!SEi>WCy>!#&k#)s(}jW(oI8oc>F~G> zmn+d#f{0ZOxRe3BmZ7dSM+>4sX@v>3g|g0-2=&QW#I11k{^Ri%8Z-5bC|8OV=H2Y` z3E!o>iid^i%BXNy@l2GuVgdAj5q+)b;3|ubTIwuJ-N*R%pipqCQ5wz|0lwy5rXEYR zCy9QT&uLbBtZAG8oiMy7!X<4`(`Yd5#NI+9yP;?f;DBl{Q_FFM@UMWvY<4Z_gT>y* z>_-o|58;9czBxl@MiE2r^A*|Wn}RK8BYMmG_K7`L0nSJwGg0{3m}3-zGcqFd^>T`0 zX($aDN%EOzMXX%TtSLz@M{RqcV4zU|<`geT87V3qWpdd7p&0DC<0J!e<%>)_0~%3L zi1IE_&l=Opfr*_&hSe-+~lLYh$T#BM-BH`O8#fbu6?@ zR4t~gCeo;h$2b99(2N*x0<@$&aqp!g!CW74^iYi4W;^lUfTPv1*`EpVD+hrka-44Iy6F+OoRvO z1_6p#R3c`kFNLsu4VjXkcD3p^yG9!mde^|Nhm08#uG{cT0v@w&YWBSQ@43Bmxc)|G ztNufH7Enylt0jbICv%1xIONQbSEJFfyr7cyWZxtnf+@giplkgt~ z(8JOZ+0RXc(;7;U179+9;4)|MiW59+6+3}*J0CNm+hcb>QrE*nedBPZT zA_WLZQEg&fNKxM=6a|I7L+t4z%zH7E7avzv8YuMVW@e-$#Z|>uiJK9v-~@yY1=&k5T z->!q-=`mx+ex-8^89~}A{J@FA$Qbo@3>{7)G13Ego*qCtxia%u%Ji4Ybs0I&4L!0uGJAN_+)GXU zuZ#2;=g=PzIGNch&hg1i@JaWd*m?1ks+wsRjqbc?YGuu|3&Yz3?K6ir&TKCXj6A)8 z_af)885gv)E}mZBaQX#JZ5NzYr?YBijwvheJiUtdQr_+TKXsl3odT*^JrpV|Mv`l* zgU!Xwd=e-sEHEdh(o=mHhQ4k=bG9b9Vz36Ird1Q?)9(GEZ0ajYEoMrQ1{`))B z{?LpQ-DVcUWesXiG8Uc?UBYUWCE7nqtsGB4l{-!po3>|*H6Y&CSE3+g{!ew$6O8gp znmx|5!j-8l6K2)Hy5YjQ`q>kRkY5g8qvwQwAATs7c`&o1V^zh3#{4K33mPYsuQHFM zI-BM$8PN_ad54vAhC@e(C2yu3&t?j;GnC?TR+bm$Cnq|yUD=ketuU>*hQj7>k4Y^P zZCe(lzyo6DcpUMUC`uG7nG8Hm25-XFfBvL$XhxM6M$tHdF!tjhve?FyQeIUhcD1>& zp|+;7t*WhGgJhzmmPFI(YJ+8%J~{FsZ4H|}wn`a{&{=)MQ&FjbwU<-SFzt=4&YWD| z^q*r}Ix#$RQ$?!hY;cO#Q&SZzN=xzNdGoCEkbODhsjd6y zdF2%N=d@+enwj#`r#d}U$k7V|-P-EnKzgdz@AJo2jPM~L9E9>Yy!{hX;z49i%51Sn zr4g$xrv^;Nk0X=X(McsUozl|9Cr8dKJoP+(3b+lFO;f)RxXONsl&GwtrkZdOM&Z?% zY&u35W&HG%g)yC)(3m#H6OE&S~8RO7B=6JpUJJW_mQc-s5(?zN0iT#{lRdV|+D4$DG z#H!?1eWBJMl%c{alo4@F#}%ARRCnm$9Ve#;wZWd>oPwB|amNfZ?kM7EHI1RThWhf- zyxi1e$zlRUl)HKSjWtq%M3`pMHkp)Y1!ns=ZuD@46@7Tj`l935801{)jpbce%&d*Z zA;acgHNLjAIdW_$@~}1KnZfrCnnQ;C29ZtWT-_?7Lk4tQQBQEeGcundSiGCaE zON;s0pOeKC6c`b(X9pVcXwTHv1d5V1Gdw(y!AV`sI)NgBVD-48kpROW)P_cIizDV1 zPAUf_uqWB=JGugK%zg*u4d@u(>6L<7&&pYYWDei{tOzUsJBz3&xho560Sg zE#I9cFZTQDymQ{zV(laH9>$sv?znz|G#c^5{pa|p1ZI16JSs^$G zkh4lZNorfh_;AH(`fbStxhK{(SoCgFKbNvqTkAlYn{_zpy^d^YHVpT1gm*I4X)x7k z5s{uW0~RZZ&mAZBzcRrkgL>5w}sx{ic4U>8G2pkdNgi6SSMP^uFaYTg1Rv%g^er z7&pwHTi;pnNQ+MLx!X<=hWpty5*!SfOMAg3mfZmu28Nwe|&H-*x2bC@5> z&l#3GEITVH!70Aq8e^#|^k-s4%}~b0OrE0!jkf(nnppu6lSt%7)+jT1!%uiUDMn)7 zO~BDNkH<--0fDO9lU-6l6kgGk-GNcHGF{1>jL}sKN5p!`mSJ4DZ`|<70(_P zn*`UEPwIHNv?Fg?$FPFFB$%YQAtygJ6CSa+d`3%V+MJfajB3e;D>`OY%DeDhYH=4M zhpF`X%o90<`59^aWIh(joSO`lCG?#Rm*)c^j|>P~{^^*<1oa7|C%wc`GEgRK>Sv57 z%B~(+`iIkh{o1yuSZ=n&vSLzug(tjQyG_}w9~lUYs?Cearjded3VhHkpR@V{WK;N8 zGC(}T6=R3_(@Po(?wEYb@1M%8E=)}i)Z{*9NoYZ9O_BTc=MmCiO-@dA5FxeBU0m$A zo9{AJv6?2QeToA)S`DD`2m*)(hi9zy7~Dq+UFlQ^`2UP)YiEl&W+u+H(8H1K>Fvu_HT{rOSf z>@t-UGiQ|`kY~Fv{8;F)!ba=Z22XmaH!7lmHqqjzg^N4SJtKSgw5Ik2q2lrh=d}Iz z7mF*tK5O22{?=J7Bj&ajl#T!Vh>6SUjIqVllg0$93bW!93hKr-44>SPeNlT=`jr`2CIO|Q-iG}UDnW~KPzvPv4uD%#7^W;6$C zYU^@>xoLbB99CRDsxpJ8Tp1QU9rvT(&5Gv;G&Tg7K=2Z%OI1{!Bj8lc`F=S}E{ZMl zSDKs}*)gXs`vzBIlF#&0rtmm4e9@^=+0jP#;@(rHbS!Q>)0Ye~p{1#WC!@sstlmaL zTT!8moyIEuiO`GD`BUUrR`yo=*xkreM)H2sB!nOQPvAM={5Yst_?`+IqjPkp%E_ng ziQ$Y>#*^nCWOjBQ{S0WLJ2)g`4tCI^%0qGXi2CGc!2L-f$TSVvy(d_!;1JHr`z=Lm6T5)3S6-(>0f z#2j>$#tWvDOrB_rQ7d!=D=TLsm{XQ>D&((bcS>3ax+K#Ymy}USfoXB?yYEhX_gxdN z0~O&r^yL)?1UAFM)9lG5VdWB{k6^UqHs)~{@D%wKD=+HEW~Og7OC8n`P?wF;CR+}F zWRk%?Fnz=(h85?8z%PZYH5AH9OVuhrFSQ`8z{J&uTTc-z2^yKB;P@F~w})LN^0CUi z(XCB9`vYTIT$$;8v2m)tjLLIVGpSHbY?4{(kv?#l>`DXFJeNoDRlY4W z^tI#Xw`5KXOjj%=E9X{)|4e9z>Y&L27Ef*U8u_aiQy-6(rcA|{pd z^Zb=|WF!F@8DibBZBuGfJN={2?V5Dn$h^+9+DR?tV`fz8%B8Oo4%+;zOSBP z#g!&bX5FtqwM%CpCp#@AKF(R-DzG{OLF_IK?w|-m8-gVrcrZo2#An-2$dUZnF*u$# zN+;krT+Pb={X-&bShNPNTtbD(p*(*cG%YVJE-c8a@>lg!UaI}&$5s0+R!D)L2*YND zh~nTRJLUxSAe~O?wG1PwCCKi z6ynjy3gYW@w>6L*t;Y{86;g%2&!YpNgUkWY z2(Z8tQ+6ug$>5U|s0RVjVb`pO1k>1M6|+s7Zt?sk6V{GURvx;QSCB_LwI5p3lkfyi zo(%3}W~wR{(x`D03p=<*IjC+A0_ABsI3$3M9Ban)^vDd;#+LDvMYtO%%F9jUJT!k@ zybSJIPag88rx`|}44Q~765?5{T{#Qj4-NHO!a}Fnm+hBGt9Z>ZH+jq?;r0O2TsVHo zbSl1zbmxp%VYZtcE3Exa~6lI=^?VC#Dvxbg*6hGlWP>C$^!!rmBp25FVz~-Y-XemCM=zb;th7r6pKWtnBxieX}4Z zu2~LttIUF&yjnTfoz^VK;PO25Wbq(Ue$xqxkwc2V5gD=ushL+(#*c_Q-1hvan?Zi! zJu})w32@F-)9rCVJKFRcO_cKIg?pxk-yRc|V*dAxWmZ97Q=^f2)KbvA;E=2LSHB!qiCJluh`ME)TDc2kIs!4Hk{RVDY%?zNI;;^G3&=cXfpS zHB}qmG@kD13BMYC()a>LX3pgq)@yrj(POb`W<2gp22OLfPonM`?U2hI*A-S&ncCzB%K}*eX*k3#G_0 zCyAeBzS``jS{2nYvs{&#!TA<9Lr;3}MM}lKS*NfWTIM<`U$NKGfVEmvRv*W{ z);xJ55t-{ax*91`$m$)GxDt}RF$8`4agqAf7eXm=dft2hHqADp|J1g9KuYt#h%_D- zcOrCZt=Na>rN>@+B8elcN!@tnA;Wzm6V;74K^Kg0g@?#Us=TebwGJkFws}lOV>5e&1KRxlIja`rZW#UF2 zUbSsoczbyN`|tClY98z*e+^6-R{^J&d2E^c_cHwmlw!BD0Map}<)%`g=Wg3RJ-o9k zyc@{As;>`^3wQJ9&DO}e;B4dplX-5|gh}joW=V@<_S4UFecZ7H8?;duhky0r-}%d@ zh6M+9$cwa(5Q_24VjC8rSaF<>2S8W=89}PzLN#(bL{uu}&`u&f@hAdU8HS|~Ha!Y^ zG7!Lp*4Z}`cXQ8V=H1ydJ}!38G7&!?b@@}>mM1#PL-YG~{Ro-?8@+qmAgh&Fl8kpRw-6*!1l?_^nou)+dTXHjVoTq?ex{8XHKttA>cc zC_tfaGtpx?=`vvUzm)8Q|3qInZN4-0#VkPC1wi{mO`GP=iezeLKlAnGaG6od!@J(? zeW}fu)zQ}b2MTTU68IuDKkm(0FG_O`Bc@7tA`oJV+KxUb4p`N~hX#OQKP_%`6cRx#N(&zrdrBxR zE-o%Hj#w)?lP=l!uo!NUQrVg9kc^YQU_TFJP<{aObYe%8e-88Ty`ch;!+M{Q#efl)kJK~ja4J7N0tN&3v#8d=2Mlr5_@CK$4|nGY9oEo;C)Z{ds z*L?03Io>2!M$j;dmsQry&-26;Pc4~pR!XoTF1L1MpmbDqc2eT7u33S?y5i!?7w*U( zt#wXLRee))MX@i_H!m@1RC8u!K#s~8sv>gO2twlwq*!JkN{*RH2VTya@F3mv*oSqu zw&|j_v&NN{k3F+#+~R@>6AI41A-=S}t*~ZdqraeOVs+<&?6}&g=kws2sWs!9FYW#G zlIBjmpkR1uM%n1;<<-;Mi>LA^arPG;uVepWl!^T-8~qOY+)R2yljvmaK$|u4ewWErwMwh3h`G!rH4XFw$3frdFhabNxGi@HeG_R_VA&*pFnjbK!M_IDC z-ju}-^}0N1N2`u8gUMr`2beW_6bI}F6D8_;gNc&Y%i+El$&8CiCIN*hOa9QjA=h-B z+M1?}Mi=&3GHO1D=iil4DWiQxIh~3r{A{vnjFT|v7(Ptp??sf49wnTZJgIAZXUC|i zqo)qWk>sd_ICF4j^y_t!_Nq9Cm--1$ERGrr9{uJU$QYj5W|@oxi!nZb=@&}pHYGG` z?5y@SW?d^}&Lbm@=%`b7V*5g;P?f~f zfLw0={+j%$Kg$J4(J`|)(Q8B)p+7pexGlF`Y6irtti;w39H0`Mr{f1&l`erj4$cQ=7B++_7h82QTVuKewww zhetVzTPIfJHr51vqY`RIPAuhBhcJcSvjG( z$binHii<~9XUF@}D^puXjBSIPZ+}&R%f( zX%psk%^NdH&QQ@=&Cki=MA&%Oc!z|tU-17Ik zuCCOTa}HghtE;OzRd-kC=?T(kqBPRXC?G%*2!#Br0VH@_r4p>J@ECQ1JO9*}Gzg%;kI-oTfa(G;Sr!lx3mXoKA4JUWhzE05@IWCHD z>JVf_U@w)~DVrHk?{SxjfqfVb`LxB(U`?p+VQxU0t8e!h z8hB;MidW+tg;`+_qXSQd_1n8l4jBHEh#@p1hEOe_mJ(o^SP|T2Ak+Zecv9pPw90Db z{rSWt+!fOie7_^7N;>$8aD(vuW@2rXw7=uWR&Q9l0UF>yeY~UnT{@7%m;l8wkvN1= z%9bJvGa6yaAzrh;4ruf?uMB!Y53f1O3kFH7CPG|vOJ7H^CaLxSIvkM`>G}Z>N90TQ z^@AfQgA><5R4 zmOwMqd~>gwKg>+D_ppQYY5NxCRvD6R6_dC5!aZNbulZ;FD!%8+`-Y^O#{69NoUAjt zAJ4v%)#jI<+ylxx;3?PCH z&d1y*8hInE-9dk(%h z6>y_qER6o($n!Ar1Z?`mZ{fJ2&lo~j3-lzIGi8&c)HC}x(9(9*c${iiAx~n>JO_Go z!35i)E0st%Y#ysFYx3km?o2W^IyyG2%YH`_j`>HOR6`o2%A)k;r~}wHKBqa+j6kG6 zB^C+Hs)qO`EWJ{pS6VEX>WPD5d3ZItTC(O!R&>Z5MV`KM*=5tRDyLdDwNM8$D@Nv= zG0*zCC+3`UE-av#D3rJFRgH)jg>%C5g-4qKCft43ZEIA1LgL@&KK? z(54vF$yQ8Nf7!b?9>2YzGTK7Lh&wo{7k%fdt0%(M#c*!XYVsB1sa5}I>{MZDA!4vb zg6T0s`TVt&C>6b$FJ6B?|SWPGOnSeq8EALXU5$n@nY?cpS;O3 zJ~5f|4tv6*{>eDUe^*sF3=*|}Bk+AD6EtXz2c#_FTDRPCc7 zyM5}8*PpuSbyup_ziFTJr9`{I8TDo=l%p2Q*KL2kz+TbJNOsRNH=R0hY-444VSf6; z%!NVPj#aVH+&1WP>XEO_#t~7kGUK-Ey8plpP1q-x4otoGA40$-8>mI%ibgpy_6399 z!!JRUutchu>JAScVS3|XU&lG4@=l<|NoX{CoA*7pw+#(pQql}Tki8Qe^u{5c;po|3 zzwvQL~h_~_SJ>0b52kX!qnvm1%podpAolXZ6LIFqGnKttX4Z+Ur9jzf7 zkHO2YMywr9G}f_`$HLJO^clol+BNvA$M=4k{NbG@1m#tf0}XNjP)cm8Y+(ZaKiPHk zb&i0Ft<65qKii64S)4pK8%``;Y-Lv~es8Ij4o(*0W_7eYWt=PBA%3y_(dt5B>vE-b zWj#9+o!(5Pk4;A%sJHtI-th<=V}L<}A^LD19USA2;4^kN`|YjvF%E;H5P!74Vfz)r zPpNche}vqDF3j$R>Bm&Bd*)&4qq_Z7;V;CmfvMl$qA%GeLHi8WDTa2`|%qZgG zL|Szq4@IF$W+J-2pbpzfY$jU~{sCXbvM2i<<|D-uJl~qqN=`Lxv+@$h4#auDJ6W|N z-$IomeJ3WTnd9e8BO|8TCH=77W*j!EM>UtkUu!>Yj#(^mQ~O`*LssU7gL1+=V$(8< z%~a=a%40r%(mNjlhM7>rYiB+lGXeErnWUg-6`v25f;1k?rxTNg%+xfWzK5~eBHe?0 zK1wTPJ_zMTMR9T$!r_W9v{@*WRst%ssx^N}GpaUNOg7uF{!-02GGY{et!}cl|4nNf zF;9qLd;9Cwp*kBe#VwW?Dh2WRoZkK$;m=KGFd>wVW^_r^w&5L5sJk=~8|>8@4YO)n$hUfPfb0Xs*68gf9Buu zm?)eEZNHJzwvLebgz)P|^nge`(39%_t!NKV6-yfcVt6dA-&d;z2?i(bq$ z5sz0b?(pbnc+A2sBqk;jqanA&;to+e@HP!>>2U$ErjZb;@tWis);{m98rF_3udI?X zSe8e6YPxh4CQ2;d*4Vh$x9B`xOf6UZfr;g$yOarN7fqS^a=d=qN)jd6uB>O4>W)-C zR6CZ>9j}Kmv{Abc#^~(k6={sBJH&4aX9+*MIsptzTuy*SB`T$;eJQwfk5MQ>69?pT zvpf+Kmx5}lJG9O~!r@E>tZQp(M=m*0w7WgpMfZtfu2pmgDk~|+cs8P4H0K+w$nC&=)*tfMggCy$@J(L*p=d^B>(WEoG6K?k4q&+%U@XX~rjap&Ikx#{DjwQ*} zZ+3+p_Fyq=Eo@${RIhC2T@LqbboNAK=El-w`yHrm4GIEXNqa)}^|XL^)kKVPL-f|Y z4h1`PuPG63CjuBdB$>$(EQe(Iof!1}cZn6r%KgrR_lgYG?cDzRwKIM#sxu%aHJzlK z0-c)I(a8QauluIZ4d2;+7N3(aJx?BD8d6E>c60xk(Ai6EpA@y^Yhq$^bauK{Ete=m zlgrUlvwAh3L(OWn%FMKyic+_Fo*_{r;0-Dmvhq;qV95e>iM$zLkR&GP0^jU&@jYg#!!ee~B8D-2|uM2BJ+8*;!AlH=rd zYEAE&FDYp6l^oE&x##pcEKhumRA~AwgQui$zHVL+2QS!YjwTX`bRwNfDx8||XT=Vu zrd-o9_6{>r?ggQbZSxbg|5365m6kks9$%X~fO)fDyL=hT3!YZkei9kpUjuwoUN}XW zweVFW93n(KL3U{#D8B`bE9LW!T46{>%&$s?y}_Ian4Q{}$7!lkQUij|1{f6>OIqht zygHtP8^^7vbmpp@nT>{L&P>KPZ}%;@*0T0|ItadAY&5-pGM1Z(CTB9vYxk*38#fm# zw`>$O4?G|)OgYjiv3)DEI72pjs1zExm%TK;T#IYj+trE28lT$={(Ys0L}xhIlY`{| z-_D&c4D(wQ_djF<%8kzNe+--)=_~bmoxS_YmG;e7uAo;0Y;1o(c&%^+IPqK)c=(i^wNhy0QWle0XuT55AHDvIEz%i@gCV3qK zG({MQL7ZK=2T@OffjD+1oz#ZGL zV_-5|8|>J391%SgNkV*iQjLnIk~+BgR2a;EcBdUBn(1#xa%!g)!a*cQh|&p4(lt8m zQCVkTdmtbvnBLZDjoXMu(4SJvNqQJ?nIuila#$t=JDfCy*|YHE%}epv{Mm`cI|HpT ztI-__-JSK+OEI-ES*m$6%SCTsV%3=6xXb~N%Oy5<{T03$mET^g%*@!MhowgiU zjGLm<6==TM+lyweUJyw{iC%4;KB%G$p+~rQLqPRz{K)>)FTRL`=8K0q0us=phxQI} z4q%`Get(K-nxS}%Q7+1<_*B5>anr3S6*mLViLxli4$xlAWYXawwa(~;+fEF3Qwo+4 zI|6tR?FeIz2(NWUoJ5Z(5pGQ>88=^wpmfnh{s^L@M9cMNy4WE!NG#Q%4;`td!V4Qx?qT}AuAIh!OF#Gv`Bv^ zhK7blZ9`_W*=`dbi;j;+W5wd)(C8?>Z?RfYY8|I@QP^OgW8c76#HUW~Un8r)^T$eo zgh(a>4#k7-`|K^qf=PB4&N)Z`BzYtWfX2VTCh>LlX7ztHh!9c>dJF==e;SQ83m(cugm1&^ zi8Ydf(&0G4NvEiLxiqL0%3AGjj(nd04on@;xVdoXcHmfKDjdRuHr{RoGQlxZ`{`NsGybICK^3K!L1gP7vY!$S#J78Ew2j7XN+ep9pvnmA(^T#9dN#Xp+oXP^7beLvndP$2S6(4~9;;3| zXMx|F37m+t&9P)sqfVBRs0&W@*>P(oGzk^l^3ZemWd-O9#V}D^n@Wu!cTA37nw@08 z(AuQgQk`7fQ6xt5d^jCGNQj`pvmD3Obnfsom9D2lPIqUnw12b0^O}+I0`1{+V`{Qo zD$I`0_U|TnN$2FoOA=kVP+riDGp zfK~#b!Y*Aj*_(5JASHZOvWdO&2(%#C#;z9+w*=j^zwf+7#^)_X=ZgZL|53?b$yanR zA^fIfi#dOUc}q5#>#sfRyw&oV|2)5gGsq?Rf@UI{m8uV9tJ!L4JRJ0TP=g?2$aMP! zs0Qt9A}*3HJ;V%9rVUyge;(`)W+r91#bMCv>0*Sq3QnLSB|8b&16g%B36S_hm-NAF z@lhb{Z$H99JVG%0>yI9G9d_uR_(6$m2?fp%3Z(){VE6L^ZcC7Pfk9ya1h&^98xN+d z)ehtX;1^s)Jsg`S@#QG2{y)zhlG(HKmoNA5duh(#_rw9g2m9_Z&hJY_q~+pMCW7C& z%=Vb7tc~wBn+!bRylle}_}s08X+GTEvOkn^P*t{nAcn+GU~{I06UfqGIkvIboSH1; zJYzDB$N(8H8y%)Py)by=wx&WalqXoet$9>1#0L_ErToo@eVY8_JiC&T<_?C-en@OU zrR&PvOxA$@x-nuX)w)=&URa2^Qx(rxCS*&^pGc)n%%><1uzw=yS`Jm3!SH-J5UR|F zLi6Qd`*(f0Nw24d^s6Y#8K`C4e>}c9=?~YBWh0Gz*kJT03ZC3jVQehl%6bY(ztI>i zH2kqz!tO{;MWXz(#_sgzgCirMg5QTvYY>t++1|R>)6~>&G;@<u1r&(Dwg zV%AaM&#eBK%^vlQ+~>*iEYf2(B$w5i(!sHW$71os$ATHt&;$TZc9Y5BA074CjV8PA zW5ccyyZm<0cTT#cE6|+zcY_C$sjcJ!G8Fx`e47O^s&CZiF^~I zILXNN&w!Jn?A_L3RD(~mG`u{UPkC@xLww0*b2OjN zBeJAY3i{n+)?s8`fZSJ#MY&F!gBlzl*Vf*OEw+RpUnKB!5(#pzUBBALq;!KF6*nGF zgyWMJ7g3gPpqlHrI*vXIkmHd2P6LM%$v`j8QciDNK?h#(}G$zhX+o1HsOI+qBRl5WCi7P`UMB}?HjXG5ld$6wrcg}l~i)^d}Zk#uW@SrKIh$2XK$<%vK5pUIUW2z=HkWknT5NLr4x(iDy4IaiG_*zm(Q&P7mDR@vephJ7R$aM zpfK@f(Tgg3SV6^pK=R}ki!~FHPQAX?TAZJ)Pfe5yTjN{((q$*2V?`FI1*6^~YMGIo zb3+PsVJ&pXIwvIM`2F3?Ob)L%$QIx&r8m8n6!ofL1QK8WEIUOw$f?8i$8o39NTtw& zJqK#y=K4dJd-evJ9)%nKXg`$cA=&h$z2K#w@pGW`w~L?Q=jagrV=2@RmtvRym`Wq- za2cL!wOU_e|I~JUjTc@<-`j2U{b&33jiUnl6Yq{vEb>!Ik~)evDcH0c?4EB&-|Xvc z7yBpPIj{f3UI^@+OIV@GP59)Fi4hC1F)-Yb4KIVRU7+>xPZ%A8Nt3w_mqQ2oVh6@m zs~ytv(@7atfal`z(;UjB^}~rBwcfF|cEehr;c!^e_G0BtZ(?tm+`R3c(czNGys@%1 z*`~6hSVuqpxeenLFR{NyQtoNphj)FY*w_)yS+&y)dDJy^yHHP8 zkBt$?0x@rg>)v4&P3i(;CRKRIjO?%|d8+JCH+;4eqJWId6b6s&qUqcCZuQTXyu*GL z#ziatw(%^uO!_{yQl7SJrR*6`28^MRxj6KrA*OD97|ZhY&JuLb*=Vt9OBN?zlJcT2ZH&cxU6B?_H)y3vS1*?&ahIw(*?ht4t=mJgHR=<1w5X zJs2s4)*SEcPB5!XDzmBD=@t;*eYyn@zo%FD({9-5P>t~&u|w1>RU^m*-D2b@@4Gj!@Y{=>jx1XoeTN9)Hl-I1CO0a*hC4+WvZqm23L+X{(O2t273`Sg;dZe9qq)l*w zA`J8|mtB)qv(6bWj8R}H&O7@Z?6n^#!%?YfFUgt`jdSi}2ICo0xDQwl7|<^6gIraT zR@F_;GLW=G#~@orex*2d+#0lkT=RYl)3iR)B1RP3Xv8B!rC~=GapEmBKGbp9#Q4UA zKWsY33wdNiP(}&V(~wrpedt7YDR}h3SM&-!zyw6K73}a+>-Dr-kcnxxC_Nq#7V1Z# zfT=-WmD-_rxI{;tb}$}xH3LMva$pNi8&Wfj9xszK7sGYQaqoT9L5!M?KBQ5ZCd5r< z^+c@2DgwKLfvk7v-g}7(@~wij|F$HK54Lglrca*Ctycq`&8D?WY`*|#rfJluz1RdU zDVs^B!Xd(u!ar1C1=`*D9I(|RWI=%3hYJVtABu(n&d6&slNF89Es{}zJdK2uR$#K^ zoQ-h?E*Em(@l}edAcs~(0U(>KA-A4x4tc{$r{`nIr3;nBa$|fr@4MU}(alqsjTLY7 z%rm{&qO;l&boX~9&nBA+&)it9o}G=@V&!0@G~+Hb6Y<&HSURcAG*)A$@0#EC1u@4w zWLqulYB|C+CwN}q&Ukh-mqEh`mQK&bl8YBA$F2o;1~V5coZdB2p!ABfAru!gbSY96PE3sDEX7EhI|ULi-FMLpP~1FqeU; zmY$2HsQpA}D(#|-9;FlZ!03FcxL^;a?18C~jC#as5&!-J;h2hzvEe9Ex_?g?>Wn$}>cI8CWT)B1K>OF*@5Z8sVShS{{Y?UWiStB` zdcV&z#&ZWk9-{M9P2fCPhI-CZ&nZ$+4O%S$onV!+XgR{%cJSJM=-_1$*Y}+ceATJ# zXW0GXr$DVZFW{F$*(Bexzv(QfcW26&a|rgwGq69VfUWAEGx8s zZZpYX0UWpePj@-@A&##Grb!%k6w7aVQ?HTaw|ZssQ_*@__WL`wUj^IHv|yBSX(B?` zgs*w#QzY1+Y~RiCAsR3_$f3%M3~9&_&NT(t7RmR7eFM}?5P=V&|B5m0^{J;a&=a-iwGwxaKfW`5j1|MAf{DcScm*RafT_7s zMfH)ucEETX$x8K^ul-xFUjOR*@5;2F$=&tl51|dck8QFmII~B8AH4|oACap?dY^6J z``9Mlcs+a9fBZ1LFSQ*OgRo!4AU*$Gb1V^OLTNl+Pt^UqY71`O7>j|{BpY5Wn~4mm zHCp!=Lhi6#T3!MXrv%_K1(r(e!$#&)tOVg}tSTPkKp|n%ea(R@>56~ew+jINrute_ zUS+(4!&CO|Mv-ZDEC)QTC%2||F5H1gSKs9Mg;=zCesbwbbT++wY2y67kxcN;Mq;@V z2;P+lG{!?3Q?gj|@tC2BRUK?;mC36cxuwcI*S|Y?&)AXO*d!{R##e!bF+>0>Gj>afjd~*jkVqdLGo87b|IfmlGf z1lGPA*bfXj>V7u6(IH3OT=C8>m`K+?Yms%R$uvz*KBw1BP3D^UCNu=E(*dMNR-c71 zrR;7?flZW4X}emh3k6ACAgY10T!PucYC$+#7*pt;B3vtWw!`YJKn=({yS86nDiv10 z8@Ic6e^5u4_vi}w4(N_aN#onMPX&9s3)*qWlldtL=#e|(`IIAYuD|ZNoKu`w;GdqM zjLaH!wSuCRv*93Fn}GI8X;Lyqn*1FL9P%|@NLaCXC?xf)H*a~*j`m&UUP{2uEe`7E zS!`P`AnlNQ#*P7=_S&QF7(x%P2amp8UFVJX>MS!gLk-SX8?%ksnd#j;l~?1SU2F9+ zEfW|if@erE$EoY)r%-D-KLxwpi=X!K=ia{hdFej=ftN1#4y(gJkI?6{=cBMOv!gQ4 z(A<$Z=IZ6kU>*=y*SCKJnekIX8F@ZO$|amHw|x|m|Bx)WH?e?y%4SHv4?}_hRfGGH zd09gOhek6RK`$ik%AyzLT-f(%ZUrH@G@A3Gb37p%vXM*0&k;N?D~?E`0t2UF0)Ysj z3m_L8KK}WZ7melS;-l8d7Nyw^m&4YDKy^KrYL)#~f5N$WLu&1gxjH+x6>X$lbMqB% z+Gla4CxdOBsDd5DKbDz}ddn%lX5yTART&5wP2{TW&}5jKTIECuBe;7nk&pcF zOF#JVhkwBA@0)(|wbQ>5mp;(GiS~}2_GVzw&_1rK){<4%FykMhgW7)S2Os&!55D~y z)31GU`h9Wf1LMW}S)8}Wc%koi-pyaCypP7p=v{0|c~+X6^d2_V)wlF4aL%BIFT&R_ z(KOothBqT#9X18%4xwRWJ7g@3-N*Ta#7%oh$wFcK!76YMLl|4eljLznu#!T9ZMSBp z{q=I(&}xP5ozKrFM_KgzIag|ue7#?6|G{)CJbfdtmx+2S{QW`H{;(sPk`jm^j|0+i zGv|`V0g?lxUa#i1IVj6CCMaPP;?NlrDKI@_BK=EJ3*_`3U1OV_ZN2PeyT^Ao1uXov zGDPg1vPN2D$^h!dGe(0PLVYNyI%Hb9wKam%3J^UxX1Ey9{ipX@N5UH1@$9e$Q3-3n=LzgO#VYAQ4FmHpc*t9W z1H^MaL_k8r+`%Q+o}t(*6_$G)o-G2zix1s?JJzp-=RPU-n{S%ch-;$cv{Ho~H}Mz& zRK^#LvEc|wUQ{BGRtphCDs=i{TyU>waaeUiLfX@rG@#9Ac)vE(?R07o&4tQcX1z{r z)7UTz*=H7j(oQ%i>`R)455l2wL$0Guq1W(nBfV2a(p;()yK}u2=@wD>Y<{*|>=eZ9 ze?>oE$NRO=D2q+APNy^KpnXf(#e5P~>^U_#DYp%?8ehQUx^YX z)&%PF==GErLvKRxs-YVNODDw-P!DJgO_Fp*F;PNukn#wVyb>16QLcEa8Zg$^w?qk@ z`h@gG5jnsF;iq@@3Z_ix6SR^P!Qj>*)sBe0;#dG$M47TXi-?@C>#bK(wHw<0FB0BS zjXP(PU6uRvA`b3SGv@P2xL#k-7Yz8F4!Cf<25>1c#4tZwb>mGP!!&sO1u`u7Yw@Ue4MPYRNl<)@Z+c0KaZCXY~ zMr>3Zk7~8h{SX{B;a%CGHKGSa13E z0YdPtc*Pzl2g;$91+V@KzVEQTsgc*4L4xMIP%!Es=Ci(rblZs_`vkrZJS;>WPYtfI5A4}ADVz*EGxKKCVN zdfvMrWsI=E=h~m4`+NH$e}^6!$6nF28-PGC@CfrEx+`Gjg5`SiDGTT#XQP_h5O(oG zoL82owZr?x6gVjcpwSFRzyl>n97+cEJdTbii{qZp^K_eKo<=|$t#u9kD~?7k`lZhB zUp?Av1|7fHI|~ekgmy1F&tvh`p!C0nB;!zWN3d?S|=tPgKjX) z&wIY9r@Tc{ZUjFL4~$<}h0Z07uSo)+QoZONR43*B;pq_*)nl!Y-xL@!+iLdlN%4!< z-|i1Zm5U zv|z?yhG2&Wk)k`Qmc@w!f&+0_xz;()P}(=Ldmu+V+&wy##(K-o^$t+v>#)GbX9HFC zygvjO3kZ;2E{5r*?Rzm_4hSvLz88NJFaB=#i@7Y*voQ4Di+ug{u#CU7X+dT0Au{F@ zh4MURM4@>r0>Vcrfi_4KZli7z<(CWP%9Db!HI&M%(EB_tq%IoW-Jpj?Reh6qDbZ=6 zdlnL@s$SW>g3|h>I33x9W)s(jbZxtRh4-SNF+%i%oRyJ@aHmN3dDt>!Dm9^DK;Ly0Q%r?O9nJoxGHLA+OJ_R{FkTZ z@Vpi@9Kss7aC7QWP2P;|&{uqfZcoAt!M0(gse*+2r_G575K3@1#HIC~ty`L|v#s;4 z7j>O5c4IlY%(mM9Yc+Yk{jI*U2A-ih2_HmUxVt$ThM$X|I#yInrPIy%9$99>fiatr zGY=BzNY@9KBWA||xlL!V5H_~WtcFs9XVY0@ZxP(3)yY-)wKqg`PLRcv8Rqs_bms%Ayy~02v%^f0RXUIeo(tM+na>ZOptj zG<{=*_G1Nd;TPBv-G9)B1>zwb@A_tDnwrATPj2VLBzR>=_-b>6{ClL^BHs(n61Q_u zgiSKwG~oZkAV4upn<>e&=nmLDZn)5Dtw7R2XrN>O2Rsh*aOZK7F$&bXO70!w1mj>; z=`A2~V_6Ul?Jxe8JuwkxYwZ)h8Ik!MYu-ZCKAvcQRXP)k!VB3?viIY@ z!5TxrCVK@zdy)Sabjf})_sC1Lk6g=LyOzE7*6bsXfNgcg{-bX?)om#L(q0|8c_!GoIK2m9gl zvckmi^knR{^%w#aBt6UHzIge7c}Obo9<#xGwx5>gqlT^G#bm1>tS0hPgZ*^oL&_mI zu6_8x3BhMV)k1ro+;2uayMC{2Lzz+vIrrI544%?-r5qqUcxHbg#RRj{gC-|O|276skISa~ zoalv!@Vm`XWWu8iUY&b?M=~9=k#IgpE>*bjaD=QINPwjU!=g3GceTMG>$>>WsH-Wl z?yg47(w@(2wK#<^+n^Dw^$z7lauz#9ri~Az98jJigrZ%DUs4h`vQlxQ67BxLXXzOU}EAUmoHy`V(^xO=Oni8MEvJ8c6^d@x5c7`Ty!!v8T7kg2hpm@ics@H#IucJ zQp9m!KG2ZW9TA|IHr-)+VDQNNVe7J?(+!}&@TAn`HK2)=+LmO3Pb8Oau1;NAN+gzV zn_hX5KWD#rDz{egJ73VMoL@}*D6xbjqhna!Md z$;R|beBsxBHtK2KvzZQZ+k4~=m?S(!I8#jl?tOiG{^ysiRYO_Z?!^574-4^u%=Y)B&MRpHlP@32K2hMBrDI@WT z?#Xpg7)iLY@d`IOKUA>1fVtSwXuP|TIN(v`{E@UsJn4w9ktCb{D~l+e^z%i$_Fy97 z!y+ETA{rfWWf8qt#Hh^{^Ne5(75TsoTzjbruzMBRC$i~y3~>;3Z+%Cy>3BJ-iezKZ znQ&H72M?!JO9?uZx`YEn9?Dee$EwzQ8mk91=6>nj0uiARNa}1V9q2S_jSgickY!(^ zJA6OzWw-X}!f1qwCQSy~1HRs4IDoBa6xSK2Uah+dfvZfjpLN z?O`^!0?tNj{BN~VgYybiR`_2XzA3)u zvGLcwx!kCHpxl^v@uS68zp23BPGL==KxP9&qt4O z_rfUl7&|3tzWJc>%c*=0F^Qcy&|24o<4sRG1*vO->Ncio>Dtc9!)o0`rY<#I?2tIp zvY~qSR)A^HR&ZD*4oxRQV8B-NBeD+MnGbaPw+`MW_WUmI*UntEuqPLU#pZ}!he*;O zkX9bONAini6g1PJwrm$*Y4EPeiD=FoxNn{GGl$qZ_^70FBKg_8h%h%lnFbSrI-;(-UKNUP3m;Af{wGKB?AjMekX4@xpuhk?SPG>^fGrHI6Wn)%)zrG z9OU;@-vSRP!V`Of>6(${<#LG$%O{pkY_88VO09AW5)Y5624^U;BF}$F*HI1mbaaRc z2BJ_z1sLPh@PiwauAg&9gf!z*{1sJr z0-4d4N~kBBS-Ub-zkNM({@C%e$(7q@QA9SqIuVeH$QC0uS9T_T?CeYkTrXGf1{m(vLFa3WiISh3Np|=ylbF!QAL-Kq!|;RtL4N>Wr8XS0UY5&F>42f|>H`YoKab<39 zj{UmXH#V~9i3BulupGP^Vzj{i1L}?1$sRe%?U7ymsHva-(0>0D`gp!*x5lGExTBWQ zleld5dqfqU}IzB=8c;#UO02p=^Kx4 z9oy`V<X*iQ8^Hp)yDzSyyfmA$No!`RS2~jRptQ6l@Ln%4`yKa7XLllkJYh;<9sh z5EkVfdrm=EarhlN%ZRV!h^wjR6mj+0Po2^@y?*mZ*f(0(=!612x7e!rJg{|I>#!+5 zVjpGgpG7oCCzy)wZG^1|Kf->D0?9);qIc02*_?>BddP~XLXe!Za#%*+iu|a1GVCRN zqd;e+?PpXCyf=xgt4-8H3Z$SRq#CIPazs?hr5pk!@iPQ{yImGDbiC%Vx!Jr*r?)|R z8wGS=8Z@pBH>r>x_M9OH9j64c*5E6X0rp^oR>8}O_&mALC(bvrjFO>_2p|j{s5Yn6 znneLRkxVJ*3g%2!yFR2rR&r$L%=nOh$QKF?<#w&ouDyz3*)Or5!MaRx zpM7V2NTUdm)k?rd(a!KifYeUd7c%k7+4(E`%{lCd4Tr`k6O*Uo2qH=W;n#)xm9$vl4N? zl`u~Q(3J~xMX^R9gvwrPMl8TqSwbipiQJWA+|SS(??myR$74|&I1B=VANoaA^w&eFV#NXO*PdH)hKaP z;l2aZO&WBTp5|w1Tv!y=gx5AB#Uiq7FBTUUnlsalI-RFTh^%UqH$fO@<22)&SC*@o zaR7R?ADP%wi1MQAL|j_}6=^wt)kypmCkYw_PL;F*Dv7^#_yN)gKn}o71M;9`6Nqx9 z^CcxM!l44rI6K$ z7@o?wE*5K^e4~A`d+pA4)=o2?@ga=Vk_<&tsc>Y(V>1Tb5r4$$Pq~)ux_ZKs@(r_V z`>ZU{att=g%Q$o6!WQL$>Rm^=dm&U}T(NV4E-&3yB!zbt0d8Fo>TA1{f#MP)|v0czqnnYEizhHm;KrHvRMf+l2^9zQC@*rj&pzai!@= z!B9~ePgYY^_}jfML?1z`O0WcJ{Y|7G2k@IAaWWFt>ihr-s3D9anUz{gDHwEW{769h zULfp5083$hCH4uD##)$VX|^N9B0hxN>$)UmctOol7b?)f+Ds+8No$!!qHQ?eQJ(ad z+_})GGc_6ZRUMW5#GHL)dF7-{XVTc+jJel6j&#`JD7p&uJiA~Gq+DYuKT_@avgLHV zu-ZWW|g6zmh8_UN}z%Jo{*HGI7s5+3@V6VAaKwes+V! z3JcydWX&5tpdy_d()myO;&r?yn{WNo2Y=&dlwH9lf3Y9PFE06 zQd)hol|imR$g;e8(&{e`=mp$wuU_~a|L_kV~zmS9dH1+^0cypb0^* zH39OVr|TEGHh2_L1;_wc>QSM)zO?$J6_GCk|m%J-L^w0!$MaU$Ke%@t``nOMle=?1 z09J({NN0y`e4vIH1GEaRxSl$>aC~=JPX@K%UT_kmIJ$VBI=QD8?+mtPLwC+ly2Qx* z+0{&|wBeN9Y zVdK?hl@wY9RZXrd0mwon_A{^j&dSWj^vrFo*mS72p1yJyJHCN(Aoss=@_LBX+JDMw zEIfC%KHkcYiR>lp>h0~HBAF})^!-1J|9~;V9-$c~3>qmmD6oYqmr|AGoQaBm!jX@= zTho>KEq0-D_44JCJ8%YtSRU^Cku+}?efaJTr=jToh&pYzb;AGlGk$b^fYHTc33p!%n;SnEl z2GgfE%5LvGAV27Ur+dU3v(aZAaeGQ481`GvB>A9{E|>J_Oj`YMhcn?Dp-)G`Khh33 zlT~`e$sesIohhp?!GA=LOE0IbFH;wq3<4*|D2~Rs#N-~8b!a&KU zyNC?BRG6}~{XMn0vnMBntH=cOC{XC-J8nO9QrVmP?z#QpJ08Ax{^ZqDSFukgW>4(i zr%}AC^|F^@pB}x&_X(LXpyo*Xgv9SA*dBK6l+`$_lJ;suZ$TMtB)fm^yA=@o-Gcol za%nq1scfUNYtlAixA=C(*j42R%7gv;{h;y#<-xulp83ZguXydEG zhk>!s0wY=FcB@^r&Ac#wk{OiZ3CJ|W^>fIR!;Dujg3bvG53CFD4zYV4oqP1rIrhq_ zC!W9`JTD5%h_HTAbb#K5g;zE`;O2sQ7)TT)`6A#NgoNU8FlpQaaikoClB}e`g>jNN zA(y`8asU8h0L?qz`-Tf}*7c*CYm(R3)1a;&Iho)$!vJK*Qg_-D++I|P7gl7o8rc^h zHA{v0It}}SzV~UYCv3tF5ldnAE(alXst8mfa_*_iXRDr_i=gcL#Oz&x*)hwoC!V+? z8LZ}`7Imc5@MTsjK3{3snBTlyg?OBsFW!0mQ6HOD#XL;aKw-Xc-u+H*DdFrC<|Ds+ zRt(5@J8)4!hhYS`sJ<~p4;)PEz=1^A!oVSbwxS^5--A7!YN4(+?FnqUR1Fp1i9?s< zRYbGa5pK_esR=Y9st83$JA{7_42~@U@1yWGn48GeQbTr5vSt$Nr#lRm1&QO6Ig>J~ zzAc@z7c+iWqU4#p$vJMx)#k(Tm0B3zaF2#O!}aM;Egtun-LY~!Tnvv)X9HB>*;QOC zrfMm_#pnnZW1o7#3+QabwzKT_*^l`6AK7F4k_<|dfHg8q_A(q7oZ6j%L;UH?NRp1y z{ZC_lXe9+6cR$Nd1*(J7+_=eMl9x!8??PG!%Ja&adrrCNk*3Uwhn@4BxFvi+{4};g zC*%gl=#FY&LF1>GfW9OF(WRugpXVTNiCeG4FMd|39_rJ$*G%wD!J3PFk0Zod$j(Oo z!Vu!YP#BeLkt7fx_yG%#-6v|m=dRkQyUV0L*k3MnqN{G||E+qgqRXwO?)`>;N9&zRn#It<8ux^Hj?i3t{iJL^EQNVI3U8dUB^PRy4@7?y|6j zi9w=bz5<;8OHrO6ckE~<=%m41Y-{;WN2}>QS22ue*k{DG`Su@)hDU4bAZ+KyS&aQ@!ceg;~4rt8gwCTjoh z?zhukOY@{Sa);1tn(aIbgPs6IOy6bUvexfCFzMZBZMg|u(=G*F-nXMQ4l8$d%}0Whi}&}< zN8MAKxh6D)=QktuDXPvqKReZ|H>qG`rA!EzoeIt5?QNDQTYDJB9jyo=U za`Hp|Qp`S8xUcd2hbBIh&Xf{Q>?+9|DxP^{gGw=%&po`ddhL8!%(~MRPif2W-uJxc zuWRW{l@jAoUfu7pk3kke&OQqCpJt;9-1e=)yL4Y>>8dK?2fX&^P2dgxl{Km~Uk z35f9G`CO6($N*9%YdQ5VU63v+7NGsX>;su#?&8G!rad{G%r9mg!Rl&i=1L&!zcEh{ zNS073T0U0s+-poF3b9ya-062(4JM~A9Zb$7?a5Fo5HO9!-42g!SZ^K+6~b$$X&y1) zoWkNag}a5nZhG#xdfTm+ZaIJU_^}4E{f7dh9I2pHcW}CAPlCbTU7PfIp*x|qRz)*} z>PrblkdPWE5^yJo$;4Pt=M^_z=f6m(O4A38Q+^^Dz9j9s$=f`AV9#Vf%e-(fV3^;l+u-xyxhalshy&>5MN; z1S7RpG_>R%vRf1L;}g?<-9rz>JwtBCh{~-pnslWKdvJ1U9TJ!~?(kL89#twjW^~5A zfvDY}(pUnOOuCV<=0fAEMpxYHkJ$Ap^>DD9%FHCJ(Ef{2A0%gg{ifPv`yGBSs($d> zRH9kp*;OEFfEJBM13t4+UDZ@2v}ggG9m;wL@v}UkF=yPJ#EINk2^z*0c0i+Kf>rHc z^~v_K4;4QH)_&p8lq|tWk3!Di!^#}BsMWDf2+LF=92_3fP3fn2S~4{dHe63gpMsq=vY`fr9D(+i#_*_1KEIMLkMOkv&n(H_GMBEhO>v?I|Vm;#JwwR zzlZ$=;(VI0I-YKhoY-1!HR{DeI%yr|{zE(>wtR7ljSS5R^p8wY+1z!c23bhBbL zATAS#3V$fyLg%s>RdK~Kt~j;GB-+K=U?in_5PRM>apH=yDHU~xQA+q-E>~iDJrZh^ z)5E#7W1doS%$>;DF5NL~asU?*>AL8#lG48x#OaK{(1vHV?qdmtO@pdDVMYwHf$z6`d_3+ zx5Ou;N4cH)X;le2Mi{(%9oZmm67Fo;0lB;3)X8qd9c47yI0hul79!1g8uSwzutC5b zhXHH!h;0D_fR%^H1^_FhtEaEDS{)5pb_?MVS|3>&drn|GgNW@yO@lDJ*QMu#u=8}R zmVfj^w(!l$bA#5kzuqxai|@;|UySKu)?VZ~z8Pz*5unHMR0doZwMqNSx0g&f7D2K? z@@X+UACCB&ychI=$8JV`W({oKU42;5J?UH$+Z z6y?~8C-#eS#E+#Y$8QV>a(rNYcaURZ5kZcwY)IHrik#m17(q_m{dt9B+H?#bo=^G9b=#WviOO)?YZ{~=puPYqr@;6M3w}W{Ji`K(j8-q1#_U7>(qdxrav(Lf zl^M$hM=ka-)BE0`FErwDM=TN^wP(CmG)|@9eVq1;MvDF+jpjl2fFqsBjm72)-lSwoUD(2d+L%ie&cLa~HdFJ(`G)(N=}$S$CpB?S{64pIaql@cqClLmi%&(or+w%^koMG>rr zSJ2|=FRcMm&1-BKu+@aanF@@qt+lRQ6Ju_FP76iNs5iS4Zm4QcJ;n7b8+M3p36vUO zG4bzUMI{SGb=R>i)t<{a#ur)Iz|#pATN7f_3gqsGj8A2`8oc zNgVA&`;J0bkW_+92N90xRADSK@GEMy8J8Ti7@SnV7*wDDDVzz{AL?UZ##8<6NHkP) zZw#eC+`B1FnTJD??O-5D*rCbByQbVB3$C=z??oFDKBWR)MfjA(rX>;cx+$}e(I8bL z&IO0`1V9Ck5;-60=xEqsc{>$M3g=7Qy1_9faw1u!3b9VfSRhtdYWe2L$#c$?75|O1 zjf>65vZuI|3QS}o=1{TjNiUauj7?tM%umMJUsb)W{mBN;{dTTmrkL1Rl8Y@H` zvBoh@+sW;F*guI)VAM`EEtym}=yo~nRBeys?P;nkiaSC?g)yj`*r|bdTF^XILc%|s zKIwy3(deivJ6iTG^l`^G#?CFC2+!U$aqNEoxZ}*i=9vpOxxHIAz!@E^pLOQUxv5sH zur(DNjgu%AwR!-huq*it)e`oMFQx*uEK)CEAm#1vi!S*0 z8gzEye31N$1SnA~L;ZN@jyY1Q>dAuRH_WB98PQ)^%_J6z-q6hHiAdzieV+VGc=3{L z+%i7B9IKp}kFB<1jkGh>x?mVX{-%VdoE)>qDuM7s+%}DDc9odDku7+$fssIUEi-$< zstXrq!ui!QL`)5Ik*8I2z{=;L3rP5g?^3nF2kw9V^KQFz=JZO7>~|!oaNKyF<#~J} z)%m*prMOI9=JSGAB(O)g9ChN>tf)5vBcU~D!*G&;alyO?#S&l%&TZ1bGA(%5I0=IPJ&S0=vv<>UDD6Q^}OSV=Zirw*r_JO56mYI zb70tC$$>Q2zjY+qZ+}RMumRYxD=E#CSs%)3-PojP4yJR|<>zy51cZ2ylhy!X9dV1fSzQo#OD^1QEz%doIY zv0GUx1?Y8;Sjg8Ca@fg(6~=R<;1fTS1dBnjTO?>B;G!4ep$j`IL-B=*cYZQz4VOaU zYRaq2Ya_MIad3N2a%$R^pGnx%>{5Jnan@_`$8rH%A~0(6_zfj(CSi@!c9m*#amwcyXRGWI z&Jb$h?v8m2Dlu;m>X4O`;8s{>xfsi#zZefaRUBx)ZVO6^*Jk|{G z7_6I$Ft4qz&dv134H5S9=5w&HonKm1X|w@mpcpJeCy40c8Bl|cOFjnjy(5MZHLq2A z14-#SEU%-lb>gpjJfI{2^<8R;lGb~xvAx%bK|Ys5AAfPzK^z#4b^ZCnfkMbxM2KWX z4v}=FrebR=!CYZvF7vGqcMj;G0+!gZ{np<(8_BjmyK{1x(1P8|BO0IszMJkJC(k!* zfKMNmIWNC|D5Ye?jq-qy@Nvw-DrkUGo-&YI57H zNxR+^jy_;~@rziwCwZg_xg%$nh`-Rhp^PE#BhIRku*~5qz%^X+Kz2&f)1^1C4+ZXT zB5Buf%j7F2f{kL_*t);57@xf%Po1M2s1Mj(KU=&0ebTR_^_29hk2mcawP(!fpehV- z$pD8oL(Ye$TLfpBN54@tZ(I{;Qw5gHRD_JM+ zZ3;1<*4;`=ZyL}FG9u4Wpg*#NpClG*VO9Z=jg1|X59g17{xU@zYK2gvpFj@`>CC->QFHM{vC zK(Yf{bsc0_dFiEc7SX*|Nd>3(?$i4M$}F?T5{X}v^2sQ4N3n=O*d+g)>b*uI z!9ed?!P6+8*>DJOr=HcK{MNgci!dk@hAc1F zA{}D%xgEvaLvRppI%^;Sv?mALBLkZA72Ii!bE;fG-LlT0hMg6pT8?}L557MT?y!6H z-oe6qF5Ek*ataa#Zhw@$0jsAHGQF`vRPYur??hLShZFygQH=%{-ezTwB3}(2U;@>1 z`r)&y=k$A0Jtq+Q_DOLbzM2i;wx)e;WwALslgq@THY>$Et3~p!w^GSr3mmQ}$*wbD zyV(Z3Nbs=hFa*k{mBwK7q-m#MBqI(7vj~U%gZ~2F$xA?x?bb!6a~_PY)zx-Pp1UDb zh(?!jfEIC>k*|U7;7U%F*#<-UA4 zaL4?uXI!PtO8r7J5}7?+@fjTYXnLaTFWX%c;vC~&?gm##`yV??FmAstHm@5)yQgGIfavX?PrA);KRz%Y}2 zv(M*5sR$&;+}eKKA^#dexewW2bMLNzDz4G+_UMn8OUE6Cp$($P-TqCa{OYB?S9O*? zm#B8RJV#BHsDJk^+@LAtyPcpljYHkVB@i=(T0+EA^{9RNWOJleMV>J~)dHj{Egfup zr5+9$)JW6~QyOTd7a1?R7QjY3EY-&G@e@6*z-@cb@q08Q!?H%f$n!)G-7Gd58GL5h zFu~{lxrd=9T9<0S{LnzoD?{u5v6qLI){3sX1~OYv87>n);s^*=u7?Ne4NbezkV!?u zzymgnjlQ}|6N&f`>H=zMy|C%s>!k%i5Qk2q0r!-!k>ucYQsMJvwWk?2pliYQZbvKD zi7Kca8u0rGTCwt>ft1pcz3oUaO01a;^hLZ%FN`2gVMM|W?25gJ^^+Abr;ezFbwa=e z3_)>vtcQ*UJ=a4)C~?4f7*o-7*~#lGU|7;zRQc=Iz@((Tbz^S{I3@d zX|C015jz81WjDF(Hw20EC`YWemmmG@v|zuY9RRP8mhXdmIMNyNJmka>Y-ay|t(x^` zTdQXK-?yI;Pob`{R1b*kj!8s)nZ=3p_0I&vUyoczgoq?pe@}QhyHkFSd z9&|?b%TwHL8y6mGjxZ#+1P+(1ws95*DnKp-6eX)|&<2c?7be~zKpoX)^=NOe$F3@`2(?7%VD)TomQ*k zdTkFgMMu9T`@}T6xfvmQZEdn#%x9B{NXR$spYF9(aK9|++0$KmHt>K$q883r(${o4 zNOwuNX$-wq3y`H*vRWv$1{MeC+y``}(5u{&QgmRwyC*#`{d&UmOHK-bk{QBnIe2V+ z9isZcDY-AM(C^ci$pmkcG+Epj%3L8QbQ~OT5tF6FB$Xl&$KL6GcB}uz{nGvH zvCZO>dnNgStpI`&`Af7yir1afQX~YtJJ8MT0N@HNOcsM-m``|wCs_(As*0CYRR8m{ ztH1p_i=RaquSxbPI7xV4sv!EZB3{-q42v`sY9&|-;hDS$>_(;uB!)re?Cr?5Xz zRaEK}9Y#&~vSO0-{pHgRB6#75q($l?ED*g=2!Aux}0PuCt>9AZsbyy(3gB)i)W&yMUvN8*U z==u(aEy(6U$hPP>v`ZvtJ@afFvvehGmp3!6>o`7|_u) zNoOG;4V@rCP(X3U5XhiUa9&>Hs4+U@y#V z?yxA%y!Zb<+Fw`Kty^{KoKwrKTlc0D7UCMmLd(9}lS~h8yFs4z;f5eL(tAovWYZ@N z!8i52$to{t>2`GzIVgt{OYSY%*e_)XCr_mBJU z*GFCY{>EEVZoctFo;IQv={bC$zthNyk3$01EBo>cJIeynep#Vx*Edwh-p*SeXug(q zmp&hF>C@+{ac`}s`S%K#YxkXueSP)YL;a#v@yLkiE^T#WFNv>?eWD`i%dXUdg%x@6 z{B>%})ygeDPTW@ID`)Yb(@)l09^m|`x^JKhxNiNe8N3(o>bi7Or6VI~G=6(su1m69 z;Y9L>A^(Tf>2uxm|H~TrI**^K)IeVka{YSE^8bxxtKUwa7&~=m)gn43CNeUndklAn zBcmhPpxstibHygU+5bu%S;h}$8!uB}-+NxJYdvmdBwu~XWnaDSx!iaEX&d_cpP#C7 zI-St<>pT5H{+V{yoiVkXYv?F7X=GGXr2Mr&wvJwYW0H)B^7lLXv*xF6q(v~Gu)@u9 zx6ERBUp?>rWG}P=}mJ4b#O!5bMI>~-<-%Fc#!oW8i>$<7Vo=-oW{;Oa0 zm^*#<_;0?wM;G@W64Sq_seiXY{dMN0$Ms{fCh~(egLFUivp&&X{ugcL$BF-!9!5X< zQ@Wl^XL@~Izd?U`bzO$&;UlA?A_opg?wgpuyv854$#l!;G}Ja{Ct(m1Ye z`OnIwuW4*t_L-r}w_3|i7vAwMErnMmvJ$R&#;B{#;yvLnU3y7Bcxify{_U+Pmom8p zVd1$gDMRLc?bPUz5z;_?GgjG)D9`U(SgF=H3DZ^Il#ikqo8=W043?Ld;7Bcv-7#vh~a-cKEF+pt922IF76)LAxw70qL4Pt%WP@D70t_p&3`X~t00+c zT+a+5(G@euc7$t8@%HU)#*n{Pi9Lq0cdMUent6XDcP`~Uu=4jP#p+QMVPT>zS8-fB z_%8OjxH6XxS8YZ&kN#ctZVK7$W$BkNhG#Y&kU!Aq`%a7DnT_6KdMEO&<3~Fu zCnryKj^;Zhh3_Gmcf`itk;$VTcl7FYM<#W&@E(^lmPhH=<=wUHh3yp;s^pz%Z4Za} z-ZQ4JJl!BWEp_Id#dpQ`9$z#zV~+X0^o8zz+r2}E-kTcJedxV|_-HYGCtPv6JQil&Gt zm%;x}BI@+(%b1etld<1zA|pCM&e0E?3UEJkW4XK{gUS?_o@MwSJjR3(b1}}`Myi_ zG2a>LXY$>aMz2&u%66X=A-#^;v;E#sB_*Ue8=*=SHGqr zC9P!{dG+U9`JTY}rwH>cAEURnaFZI1PHwUmbL@LHnLisn)ADQ5qB{xy@MAfJ+$&Ua zz*Brn_&Oi{CQRRJ;vZDqF8`iG{xRe)=T-1|mfyqqE#GaQ92IN1NhMh1yX}*!Zni|J zE}Ro@k?@10KdB~Ko>b$^w}k)Ir$$9s#;cnGI;)6)Ug~D+6aKLL_J1r3*bUlSwX-~; zLM#cqolU-f_?fG^TH=vSzS}-=%4V6(2Dh$!OZcjf^<~vdK9}QOQ2iyWo$9H}aozC6 zRy9hGQMX%%;eT>|zRIu+WsUJmHAP+IF4;w%1!+-J`6R3TYO2mwnaFsHwTN>0HlIYU zG~2?rsTB1Wm9E}Zw^`HGtrjO~@_8fs^Qy0YRrNE!iPPbf7l|JfsCf0U%1|GBAGh31 z+JE+$N`8FUF_U0EJ2;>8)+hNM#%Bz&-=h-sA62^Le*Bwb>ZHn4r&Ok%fj`{G=L^-% znyk9%vxLX;xdodKQpwaOQ7=?IRh2hUm!XFnR1Zsc)yZ<3>Y|sbDEUy2#2@5)=Lo+Z7Fx=&Y=^m~4Nh)%|MFZksl zY;=@>FDLQ$ZhFbb#MM%_d(r<7J^>Ne#v^Zv{*CHwwe#2i+T&vm-v0HJiqqW*->y=u z*}mV*4HEV1{Jo2}(96|%=28BAq>rHd2=x3Beno!}kivN{slj@uO0(o42Os^Viq*SG z8>Md7qnS_PQ#xG@Q(M$9z6bL?SiMHvL+JR*$M~K88apR)F5mLO7kuA}cb9#{`xg^b ziX}|hteNz~S?sjugHCRf4?5{B9~l$$Ib<4-52Vt^-J_xk$PdCOO`EL8XqPn+*>A$;P{XzdjEgtHz zgSN)UH>!?uDIIo*zm*YwQ;xE7H}U|?@?L}v@84m$_aLnBo`hB2FQD77+S@|71|PTT zLEdAqP}1vp-u=+!{R);#O1(jH(DjnDZtxz0jV7iE-lTTZYHrf)$cy){^7giybdiaf zW7z0z(tREuG&_Y5t* z2YE(mn+k*p%(bI5J7M5ZNu$#Y%cy&lUTnfkB_C=b=T>;n!j;rIO0V{wgHIkZCLF+Pq+rHMpKtB zVKaM@qN$PO(_+|)W}>N42((d`Xlle-95o`PsZlgFBE6OxMVlH$Qx|fkE)u^6Jw%&Y zL}MK<;YP#FFrL2~D(}`EY&h1$WOzR(Cd7xiPy;{JjjHHqPKW$$1d?Y z8~wy?#YXX_cJX>6`j4lMlBUVTi(PtSkyCKFVI4B`M(5wc zJ zyxZV%be@Wao8czBD;3X?H^^-^=YB$2snqK$xZkkF`w?NOU8=fha=v8f6>5v*j9o~h zJD{IbG;jn)n)n!`P1W6~X)0qyDD1(tbSgTz8M2%Y<5V1^XNHO9=ujya%?KxmJlf7Y zG!<*s!!m4_imu*=OKIJyShE~fNL|p_1-RPCu*RIVR_comzlIx(JoP4~!KB%U@1>$i zNh6v})tkNh7;Val8HTTZ52Ys=hOd4HYmjOfdixvPO1*}e-eVa0InVf%pu*rF${mKk zwZIA!ztT|rZ5T3~g7wsE7k z4nljw(Ftc64zqpJ(8`$6*=rXHd!+DD5tTQqIB_YMMbQ=a>mdpO9ht zgbdS%XHaf1G0d!?^x+vg$)u6KB7@d<35q-!=ujw{&oEMD;8BMOi|sOyjneTSNx#vY zyP4kd9<`0}Xfo|CnkOl(SYaBnXjtgo3m0(iG*yPrPg4s`csZp^qZXIoCh9fK^w`tX zR%Dx|cA%wcY9}_G#&{?E6b($HrUzgPo;i)0o>J3vC_XlgR>n~sDJAMIk^_CtA;>5X zWfYr+1|lJkr@%OQ;uCGeLea)F>b@V|FS6+e4DBZ8A}L+ZF&xk(_KS2-JRAQQFv(xl8ER~6_4#J1Lg|N{3A(W9WlNMJA zE4*%4N&CvA-K~Xg@3XMRTLCwDAA`-_XW&-v@8GBSLnd1K2DZ>EW}>Cj%=|kuc4VTH zO)!mC&$WQ$qi1^m4HnQlWzuRSJkP|tq%6Haa>ECX!=>0OQk29l9Au9Ms|s zSVtRos7A&+2i92)o6)(0(c}!=$|&Q&t2NwhDE4w-uVe6tIje>GISxeA|KT zh^N+<;2@D1J8~Af`Vh|az6b3leF3e*!JLp%@LQqNyAjSq^A7q$35#VNrsr{B-;;!w z;xi8YBvx=>-+#cBCcMV`XTodob_Z6LlpD~k11o<48)%OXtSsRsH1EKxkEud*dkzjZ zl(|qLJ=o_^=0b(afu0NL$Bsam3l-uUd!h8qg=qC_=r(C&E>wtaKZdm?z4Wey==Ocs zY;xO*oP~J%B~^%Tv_R?o3hDhWzyu^OG&7kszb&R=X_{<)7#H2iG*y7zy zOe^J}$BzoK?kqpbXzQ4(kmY3^y7X8u8vTbR|b+W>totd=9tc zEenm_78<=RG2#s+ry4nk6*1Cum$603VScJwx2`4bCTx7FT#Ibf-+B7q&HywMY`Uc)nLLK(f=adh)*ukO~gD( zjas3D(d1Dq83e0MjO^2Vlzv0FTS(6k3=_!VQ6tHt=tp9T%+Wc9a^>sx|Wzk@aOv`dU8m!Qdggtt=G z67+cl%ILfVKO{HgBsbH8EumFjARL2!me4kZ3DkWFeH!P|LgnaC6Q3q!Q6o8bo=AvR z<>+EYv?cUTlCzAtOK6+IDlEGM-;?-y!v;fXp-b?(R<)cuo`7=wxSV>OgjM+Da%v>3 zCWqzJ>j;$D=5kZ7<-s(!}&Y=gaYpFeq2Y%kd3~k(t$U)8{NV zGpptF(v(XrF2bew#&Uc^!ZLqYPF*OST3mv1U9+582<5tFIlYY>Z8R}W`08?6&_z{l zT0uEJvxcyPv8fyjehJGMWyv-?V@El2hHu~= z@2}y0?KRw$?LzlE*zHsxIDd;u>RdYOlpYlW4|X*JtmC}UhX*E`?A&Wso3T<^RK zW8^KpT<@HR-O*Ax8fy=2sw0%^opSo0eo+1vY&qJKqeDdodLhX<&HEgj;N1!3s;8VD zdn24LwO|xOa|sBXgT_d`V(9({Gp4gY8f&knp^!z!oQA27X(CEw(^u zO%==~ys(V%tAe?NgzM0G1-1x)yYROPtROjjYL3eMwn7~=@h$Z573iOw&9!6&y8Q>? zNUT|bZZE;1cy$FbaF)))Ln?H>p(z*5d`HYetXZL#;B^(~ffA|dak##r#qp(c!#1GHHa@GMV@wy98uA3^+d<&H8rb@i% zJY&2SFRe0j(JC_+twQqO6C*RFD&*e|WnNlEE&dxWM?Y265r-U~yeEWD2Nc-`M% zB%V;kwH0fcSW05LQI{&(^$oBGyx5pV=1?>l-pR!Z7k)c2M*?_SjtW7puWaZZeuC8v6LH2ogiK;#*0~q4c!tu)=OA>&ffT|4AsVV;%bc8g6CQu?}rtgr714T!*$lfwI20 z4sEx<7RI=Brte*cw*R5lq3yrH4#=<$ZIcphABWN+)}if#P)53SrbVnn+YyANMXW>H zl#aGjU;=NNS%kwI!5DQkDRT}2?^n2Be zR_EbzQdXnSRw%2Z)kc%m=rEY@4*a&-%uB1$qVX{PrUl%2i1Xn%@UIGf%6*Z$E&%aSF!JtJI+XGq5}NmTJ&{IJB{jSA+iBLDr*T zf=Ysk=IBr<9l!k$rqKh}Xqoxc&`U_UVuc#K*8`pSQVq5c&ZqaT!6MWGPks$9GUYC2 zj#^{pY&Cc_HKnikHLRe0)nKpFaJ9*Kjmdef30KiW)?l^Wu%3RS2CJcYJX~aG)S1o!w17!uK7Ah zjfPDoUe*cg@Hb&P`P3o5gk_bWj(OKwSc#VEn0;-BvL02ZYVf)`Rcq30GBM4JR&~s~ zcEeW5hpQ5DVC{%=bpifa$6V_hI1gW{W3F`+R!CV!+B#-j`w4F_@%8v#9nyXe8|kC! z(Dq^VI{G{Ww<7uLq(7zB6SEV_tZzN>d)0bMJP!*fcReK@hV#gCJtdxiGGAJ6N?cD4 zUlW#l1nbd{9BsfB>nZUhlu^5pb><-Gz*ietWeJB14a?~#8@bjy2rH>+Bl`IpbQ@OF z+u-}m;Ty4YfNIqD8$Mt-51(m7p50LT!$wv%3~EO5^Qsxox4<6s63uviN66y|Fi!Hs{|CZEb2N=! zw3%8Qh2>mTHS3jVshKs9AXrb&)2tgzcq8G>NO&5Sq($W-Vn4?czM)nRwS0b3L+!-b`W&(99M*wi(Xjx@HSfy#b|lZ=t5-Y}(5ftcE;z z@0U>8%NFA^TTFY|g4K=?(`e$GOn5UE+=?e#paa`&HGR}p{Mkx)p<%gqGvNv>vXwd> zg;hwhl{)@6ti~2wspBTK71?T`i#~QMSHUOXlhkf2Yj?tOth^ODTcNDwZbh~)pzJi* zia(PNvh9UUCVrbaYdiUD<35iSP9cYFc!CAmu;Vto{SGK=AlvYPJJfdkO2cZ>Y{##x zYP<2D?VJ@t*oHrB=d4f|XTq|!ww-e&rkp(AK@S>=m%c-87RYP`N^b9%+}<&{y<>8F zhup%6mpjYvAV~)(qt!bmw_SM7d9@2~5f;+J>@q&H3!iy`a3%KIg+8}Kx1p@O?Lwa$ zU@i9Dh0nYXo6-C(eC7b$V{&Vuhup;&aSF!J6YkQoCa?={k$9(xk-HeXun48#EtJk! zK>qj)IpZfspxlMrg)PoPxeK`qKan&tkKKhW&Z-ZoV-P!}Mq12bFA`_PNYUVYDo9Ko1puG@Sfoyy5WZ?$M0og9X z1{0RMlY5ZrqN10g2m1_L1VXu9{)`;jL*9bKo<}QJhqkiRZ4VW%2Fc%B*wUF?L~s~1SQx`H|9UV5tT@K@}y*vl*tIrSD|zC?11 z+Q*#g2n?lV?PEp#&+raf%|2#6r{HS(qJ3swy^odcbLuOz*7p_hr`18Ma2BQ$e~`ZG z7?d^1gZSZjSkB7TL1UML*kvnWH`lob>ASv#HQWb0h#$&Xn@oH&wmyg-ey$FhUhAM4 zRS%l`8VB*clf*k2`wr3@d;?vKPzUk1qfkcJgIHF$2Kf(SUnIf4$DxcY2k|{g-)Lf* zq+CXp7Ig%fzlXApdIUL-LAPNIr5w=?YIlTEzE?+0_%wbPug;>evru*~oYfOK_bi$@ z0+$)CX1>vaep+BU+Gs&P65~MH7Ut5eP_9H+#blPw3JSTg_JFUpP`boaQ_~i-^f|0G z;bzKeK|h>@H(H^r*teh`N+(~T3>muM*_9?Z}QY3ySErRw+iO7h|t@J$KK)I4?rC00;WsGh`p5Cx0 zJz=YkQ_VVb%2C-b(W=wXPb;m1{2AlEgmU%NYObDI>7y^7vAAY6kcJ5bhX*vwz4?SSNx1M@fC0nLX%<~GnNrQrXh zp+=;aISee9^t6I=aHZiIbkc!Va17Rak3#P2LDq^PGk@4*;#pPDossZe$nGP^tQEQq zYrKDDe+Ku3A=ff618YWd?JQx@d?e@o8FKd-R#BHo&J|XZew{sg!|N4wcb0T6|@ztmCm!^CT@r=XKsMR~ha}u+V(43R3|iU@ML#h})dX4dfn3W#u4N#1$zhGR5!QN7K(TlXZR8l7 zK<#4ab&o*qPQs<$ui!H8=dc`W#u$soAeEf8TJmHaNm4#XU1E^%TgYBJDAtcbhku8S zCWd`tgg29CS9Iuw(k{B17SR=X&J*5*{=3Qy0Ww2?%n%?m1l^5Z&I-9duDj6}1w$uo zwi~^Wa1HD(<1b`Q8?x>MSvA$&Ngo2~wIHjJkaaLhYGz+-59SyaNY4p(3TX|*V5>mb z)i6oYGiQ*P8RXD|IYThyPCYCzVW&BFo}tUcuQX?^Q5~sIv*A{1WTV6&xI;z2ordR0 zZ=+n|DK`XmHB91hJsagp%nTErsoD{?s}8Whgq?=-3|%JWO7=wCsAGHGi+;nVWBp7d z9A|1Bhn5lviwtqd5U%6MlcTzj9OBTG#LP2vkxv}CCFywb>5WyIRd={m4T0PE6EF$n zBk?=gi=M!&ELbN{i*~T9VUl68q0}M)?FB$Pd)X7Hg@g-L5OlJ`Jb`j;(8X@@1m;>2 z|0^U(K!)4&Eyyq#pAg$68rvlr+a(&?B^ui$8rvlr+a;R1Cu*@^qOoA2v0$RHV4|^L zqOo8irH7D4ESN~?0Z>X$q}+~LcC?;^+;fNJ-Zx<-t*ke#>;!ZhvU8ho9W7M$yZ#BX zuLH7%54q0*Wn__ku;0KI#u`Ro+JfwZCCpf}7pBo(ddp5T_<$kzJ_vK~9&+ywCH{}^OnF?3TRt9SHxNl3mE zHk*95QtKqvzRp4RenakeL+;({BxF7gS@nWx63^Ii6wWl1cAA8oN8mg|){6))klc_{ z(wC!?B>I-~kl7~WN(XW;2C|9*SwVu#Gog$l$w>IMPNuyELg_1#@w@g=`ig$aihlZW zH4y-tRVTO=@9l@T#K0XqVbc#=2tP1sTJWxZ_-&-_$MfqNc0lrecu{xQ)iB90*>DE_ z&=3D<2kmMgl$O{J|LF$jsb0`!!i#uvr5{%fa&#qawjZ9140u#BGIw4r818;V!_J25h%4K*X$P`u(D!ZM-_#W(7qjA%pA z{|AukT)34P)KJEYPSh@sR);@R5|8}Njo)I!2d`12je zuocR@A_Q42fz^zCX_Wpu$chl$_!*Q| zkcQnXP{#B$Sqp+(TR|t%rlF04P-IRsGpIDiQwhubCk@RAWt2}tGe==P7ECifpT-y} z;YO^PhJGZxnVcukq7Orv%}zl6Es(2qD09mR$S-8I2iACZL6LR>+B*WzqK65l%}!uW zdzA24d~534b&xAE z*oscF@r{LWo_8^Hd4CC);^En*Kg`BAE)r({65K#r%SMu2umL+}Bg6Z!iCJ_urJv+E zI(Fm0qe6UsFPwml9A-x6Am{H0FT-yg^Z;CS(*qoaYpJP&e&C4CGyOoGnU&>HiyC6& zY9-HjR35eXgs@z#70fgF&m;d$gt<=y%e=2bDPR4Yqo;Kt&o3cs zM6lfZ8@L+TT(sZQa66@!AmO)=duK4i`(Mz(6^?xoB$ta?84nFz@K1h@lR%x5M8nUQHY!-Qq7I3FJ&4b~HKSCsh#t7nkaGw7fe zvZMGCWDhEo5wMKfeE{8Dla^7tR#@ZxBjhe2+=TpP^yiY#R^}D5m)NVzs0%UlY2-|w zCS+w8vi}Ooh%Y;SPeHkQEu+0i8tzF!?n%*K$Y{8PRuBTEe_o0e-hmI%`j#T?Zphvq z$UPKT%ehPC31PU8x-Vs1BgS~kQoQAT!aUyrhv2tM(dwTecah*yG`SS5zN43s|7Wm_ zx%x7+8V+TyzRb+kmy!QI!jk_o@;{)Lv0wTk3_|{8c;jvu!`yorrF;RUe_Mv7f+2f- zp~IZDj1rfbQD&KbT5`kdPU|PgXODi8+MR$r`v6%lg{+st8a(Goc%0d! zc&Y3jJPTzlrNY>*f^%87<=g{MW=$2?>m4X#cLjcU8uA1X6syTz!NZUz?;!irAiLb5 zSg^v(1S;@A35zu==mUjokVJL{N|?Rwu)$E~q7_)vD|1$Cv=Xfzh3v+Mo0yZVG~Tq=(+Rv4u^!>)!& zTo zv5Wo{ZC~rvSa2tlb+FaOcB{?IZ8aABm>BLN!F}j+wW;Z9M)R|TW!3R%yz3l0RKy3? zlEWd$GZC-`zgo+=-{`fZ4A9Tv=O^`Z_|GvIW5Tjt`W!i&)v~Mb5|pu~irjt!Wj?hn0n`sN|A*A19Kc0l~9F7`qsWRSDg}0m_hI>O$u3uzlorJ|( zWKZ2i{i+%Jeg_}Z{|Rr^b&#k2@FMOym|klGy+J);2V*WzDj1ft!nOekk3+X%HKWW1 zoDH{g5cpj_2%zypuL7Bsd25BwU&FbZst9d3}l8E_^x+Ca}t zdc5ufSZ2aJ;YC<9Uyqyzp!BZw$mxL&dV_lO>4iLf31tMSN4Faw_v0Y<<6t#21a{w` z=XxV^Ju;slEHc+4b1)Q{>ycUFrPb7%R#T76+>bHsr5>5j5|-9ckIWXx(jq>y0A<{7FeNq^Ej1YZG*H&}#JAvk4W_SXpseGBML!Lc#ZjZ5 z2BRP5x%8zCltpf)C2m9mr?^|p?g&_p|7^ssyiiv1H==;&5A@S$Y|+Rr!E=PgB8{f+YD7QZ6Bb)EBH;nuh-{=c{?lmm z(`Y1YL^GsBGk=9*g+}B&4#f&Q(SZeNqGWhliPOE zx4>oGf4utN1L|S*CU+c0Gal6HR!f{E*Rs^I#d5%!WWCGku^tVW6c`e?IPgGFpPkGh0(iSAO=<@qjebvYBA z5f35$40dWIn z4|sXtT>}>nTs!dNTf5%+;Gp({CJlOdaQ=|=+dABKDD{=0rNdH(TZX?m;;s?7Kbv~{ z)Y})|e&~+QcN`eieUy7tzZ~Z{ekqi#-)sV zVBAx8_PX<jCia>5he?T(o}ZjP z`A<_uPT4%=%)N8(edgW`QwL6cZR+RKCQY9(eev|yrk}WP?tP~+znw8`#_pMS&0Kx| z()+)<|NH|FKJfO>EkEz|^O-+?=D{fsrDr8%U9x{ZD{EHStY6Q1bJlya4rIq=Kb*ZS z``et(IiqtP&)JZ3*wNYXh-0(kL~j4ww{myq#pO-U`%~Vx`Q7tV@{99dE4ZOxQbB&f z>Vl7EkDNVe_KCvwg*k;gi-r`vJZIpX=ZiZQ=N5n9ES>wn+>hoZ&RgM9u6)^+)?Z`uL--Ji6nt zvd5lXvV6&gr8g{nVd+=PMlWkzcHr^2$0t3$;&IR8ho9*9#K0$VpLpeoqsyl+KlJ2X zzZm(8*MHgPm#d!&dFr=M?JEx{?_U0X`H2-BSNvkd?uyYBwH2)^D_5Rc6|w56N=xOe z$`5{(uzJ$!kDuP~^ykkEd8X`{o&UD_*@$OTpWV4;@!F`hZ#_5lxl_Nc{I!SwKKS?9 zRnx0p|BuD)4({4@YTYZ(-}(Fl&lf$v?>8^M@bU{gUJQCM;l<(?8(-@1(#)5hdFfEK zr8>X*^Ujf z&N;o4Y?JJ>ik!BLIdknrMRr#~VnJJIWZoQmL6JYz6lV^_IBn_k9mS8>iwbh=w#0l# zQIT_`EBA7gNo!kBP?~R>;wW*r9(Lr|(w)Vnwh8t*4qLA&_9Dju`@**GDUQ7Plqh0e zmNLmmb6J=qf3a6e9cJ_AGR)M{|6{ttRZ`$Awhc__-+#bxTWM*oeSWDkzks3>AMT%$ z+S`^qj`ZlpWgFbzf0F;pR#0NI+e%&b9LF5HtI+1m{ek9Eu2tlZG?rxhv2y+|PRS_s zNs?1gGPlUS(3We@cGybu?WML{hrM*Z%TZ#RB1t1&0d^iD=H{1D9*DL z&!6LP*^5e&I7GDFm1B;QSGLPhifZhxg`~~%Wt2pPae>m(g*JR(ZjqzZVJmTzO4V}; z?Afk@(t>QVvX|HvU}E{Un<5KJIAF6EmEuu$&M7D^nOoq($g>vO<~UsrTb{!?$5HAc zQHi~{BpDYd$hDO&oa>Ovlt^ugZ3U&bl-PCE-|n(! zQ;dj}l3!XncUZrErTCk}o;Tm&%$?(W*n!(RBx`Xxe~KSC_tbn$Yy9tCXKv{NI|33> zRFLf`EB{RjF@5|`AMv}Q8l#+QE=%YxUig%!@>Qv_v1KS* z_2zq^>d!W|{)Cb*{~E}4eH+^~?WB~n_mDP26|*ewGF(VpqMGABK9al(n94g;kt!j~ zLLNtQcwi-)a_3Nrihabj`L{=%IfK=D!HHBPq{I!w% z($##*ELM-0JPSC+Eo&sqH!?|?BT1cmom5xywQ-}NfZFDB<`m9jnU8ZGhB>ALC;5vm zCXn|WVr{Ay>7)+4^nve%Kl&}XeMh$i}Dg;e7+$!eTGf1lsD z_%)d0*XrZiUpDe8A)Q#J6bZyb9LByZ`4Z=(+<)$KDgV?X|Fw@vifeUwea~sL)b;%S z|6eH?XyIy|Lh3RQcHUjk8eBICs(#9v6OtoYb1@xDEa2`>xx8@ zmsr@>3y3#KI$u8^b#o9Sb&}R4HS$?q%8=Sh|0HE(`=zq;E$vczmLfvF-;#e@EybsN zXUNeale_d$B9oLOb(TJ5;8}d5{i$26FrEJMvYF|Q+=<5XvjBiR^ z=8~?>G9sJLHqwqn@>@tR`js4$$=SuX$Wfx^q4Vp@Bdx&K;zWAUl~`MBlWoqGw&l}S z3P(hvb9tn#AOA_&q8afC>1U+WTx#Mpy_T=Hm0J0vZtLl;&Euc<+*2vR*J{(r)z|;s zYf33KeV$K)z7*mM;;*7NU!OUju+&a!;FHy+?xpV^&+mywlcKjPIgh_42l1pI_EiJu zf#hT3b*gQWU0d#z7WFV%k&&ZK4_Ei^;z8+Zl$y-9c#8Cv*XpH&x`;Q-#zRK`K{bfoyF7U|Eb34 zKz6PMbLSyjeW63tAK3TKyZm^^WEgLRy~q{M-%TxN2@;U!t2Uz!EGzf$6Dbk64n9)A2a-PS)Dr zRqyFrc$y%Qy+nOz}E=qQVdL?TS4d?9h0cb?;H?zqsNWtp@2aye)JryBX5;IChcUsWa38 z-u8T(zFUvi_po1_x7ewV^hEVHl>f1wq$les`d&R%4b{_F8J@21)4ZKZ&t!)If8$Gy z&_7q-=?B$D{SbQsex~humO8|p_OUvLyW#~pm!YRfy}r4>cvW)n$6IU>c_at zwNx+TU6zmQC-icj2zye!!hMEc=wI@d)VtIUX@mb(8wDx|{W^RXj5> zUX^k$;bEHQeC{UP!@Yo~^)ve4^s{P$Uc;*YL{{~Gt^b|X_5V;k)XTh$c#=A%o>Rxw zWbM}L^z-^R`UT!%`l5bG%ago843`V_%e?DmF;D$HqHFXk+#z{Y|5kmkPU+wA*6P#x z_pGG-r&_0;S1;;6@P?Ut)l*z$MyL>Wb8q1Zi+^Je(|<8FdWjv~f8p7z4XQ!a%e@yh zO?z0+e_gFm)3vPE%Zhb_`UTHRMC&*7oBEIXPuvUH$cku_TCJW`_vuag&-yKOl>06J zt>5Oo#Ann>?x-}Y6RbmK>c4Q8V2fI+mhsk>t*jr8W(9DEen;=r@9OvTF8#j#tNuWL zs6Wzw(;w?k^lmkSH*9~Z_vp{`=lToYANGLWs}A$d+&`(cdY}Hg`nmo}eXaL%hv;E}u-ofYB)> z*#Tn&qd@qW>;hNz{5iQrjZInGjhHrEZM0b@B9G&b8Vd5tAUduc$LM5UQxg3`>9 zu(Zo31gH5*w5Ap31*iE+4N5C5D9UjJq|J9Z1JXG=a9j#kRRQCq+;LaRjTpzZ%^bV0 z8By?h3#2%9#Nf#9A`$3d%5Ig=Jh$ADrRWK!#tI44*7_N!fQ@ zmBZacMBIHUdMnP(zVDV*E8JDei{3T>Uw7L}?DL5d-ew?0^Z9#ROj# z6U@mG6RtWjY{F$Z113t+iAMZ(6Z7X|CD;5pMO@bhPxRMdqOS(w6HAKhCHX!hPLfh4 z3#Q2VQ+!2D@f9`Ys-gn!mE-rCKL0G}W9HFijFp^9eHT8bPM{1)1g( zBygHIQ_wV@LZ@?D;C;rf_el=-`HH&lN>QQr+$my&`E2L{=Vw83_VNfvDP%W3z?8D^jBEGcz4=jJ=Y zSn=`uzcu@z((vpn#fD{H$vnqoo@4Y8lw-U;grh}{l9Jg$4pUf=!yFBBTs|wzA?s2p zMXXJAWS(CVA>p=M&5yPMLvx+;T_$~mgxaFbkG2!S^R84qBJV0k3Cp`&qkw#A zX8BhV1{IjPTMA|e7x;Bt;I9E|DAXWuwrDPV_LWm23a`pLqA<_pa18n!+J*ClJC;^|c!%G)9+cF9#wk<44OY;j{IqgdGsaaceu+yiNaOah#8aU5X zmvtWLrCq)%xUQ;#wdA4Fpb~R9up~QwfjzwBiWzsfMo@6Z97oLj8RzAz&(85;)(~XTDF7^RH3l ze7|$dFD~fce^mcq-}hMaJz#K}|2y6HJ!GK&`&RQka6qd6d#L|=l>d9Q`M!1Z82KJJ zaKK>yH|c!p4isO{3!3k9#RW#b1wQv#a7C4&3ods<3rtTFxKL7tFT9c@XrZqQT4-_# zdc@=r_Q(|%d&J@L=_5iyZMro-+LX&myXLvL8?Tu~r*jt}o&QFt5&R7sW!Yn4{hhzO z_YUvzKVa$LJ>%``QAxHOk1Z=V)}tn6I%Xt$G!Zt>Ta!Ei2{SzbY4>OLjO`h-BGcxX zG%2&EXXK0+nN{hGzibM(Bzb~kM|*1dW-T=?Naw_jPJGCTp~(v!g5N ztVtZRQKTg;+oRKFWsObt1hmDezOi*d0r6S3v=y;-sf;OG#fW?!TMTt*E74<(kF}5G z+`y!|z`!(*wi6CY^5`s^%@aE2F3|~r*wHgQVe)GVzry&H>)OCw8ny zkMXG6U)Nfrf@DufQk@D+o0_R?S>(7rJY1{ME3)c>Eq!BpAzNsYC$R57O%ayFnc-Qs zF-VjpV(|au%vjq9e#Uw_IJ(C4>`6x9NuIF2p0Ga2o`@uyZ5%pjQ+KRAHP*IbTILTU zW8}1UZQ`K{PedP&?$qDNb;DJ1{ov4zNw&e1o$P6!q&!xiO>vF3@+7D_%Z)Fk#@-&A zT6d%Fgj6>r*+w8iTdFKnYEMn}bVy2x9Fgp~`8r2YWHu=}Ce>L~=XhI+ZJhBlOMC`@ zFgA8vtbLY8$BuseX01DQq<~IXxidE8e{#eo`Tg-ZELO}G4(W7yUkTH0GNgSJ=QO2g*Q)6PuCtd6oGREXZ7QU<~0r%$z%INC}#J2+FT+X8@ z(k95=3Tc8du{~#8$q}l1O3J<NRP)Q)DNfAJCSu`^_nyo3MS4 zpNO~N-MZt=o(`nxndA{SNl5Z^>f4t2HFEV%@^tRI0)G+5SV5clk?fc%#S=~yZZY~4 zUu#o8jzp8RrQq+rTE->Sh0vi~_Q^IS{Y$SK_rG&AQLi-c5wWQ;J+Cr)&l!F}Vw1!l zJiQP*Uh3XvhD51uPqCGV*D?dCj&h8_4B^s0+eT+Hma!mquBTHP z4J$E=F>zYvl@{Q!#ExAb7H+llT_16iutOxA@p?dFaN3ly#06OTzNx)WdIDC}@w$A< F_&?-r`R@P# literal 0 HcmV?d00001 diff --git a/examples/generate-opengraph-image/go.mod b/examples/generate-opengraph-image/go.mod new file mode 100644 index 00000000..bab3fcd4 --- /dev/null +++ b/examples/generate-opengraph-image/go.mod @@ -0,0 +1,34 @@ +module github.com/go-fuego/fuego/examples/generate-image + +go 1.23.3 + +require ( + github.com/getkin/kin-openapi v0.128.0 + github.com/go-fuego/fuego v0.15.1 + github.com/go-fuego/fuego/middleware/cache v0.0.0-20241205062647-57f1083dfa29 + github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 + golang.org/x/image v0.23.0 +) + +require ( + github.com/gabriel-vasile/mimetype v1.4.7 // indirect + github.com/go-openapi/jsonpointer v0.21.0 // indirect + github.com/go-openapi/swag v0.23.0 // indirect + github.com/go-playground/locales v0.14.1 // indirect + github.com/go-playground/universal-translator v0.18.1 // indirect + github.com/go-playground/validator/v10 v10.23.0 // indirect + github.com/golang-jwt/jwt/v5 v5.2.1 // indirect + github.com/gorilla/schema v1.4.1 // indirect + github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect + github.com/invopop/yaml v0.3.1 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/leodido/go-urn v1.4.0 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect + github.com/perimeterx/marshmallow v1.1.5 // indirect + golang.org/x/crypto v0.29.0 // indirect + golang.org/x/net v0.31.0 // indirect + golang.org/x/sys v0.27.0 // indirect + golang.org/x/text v0.21.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/examples/generate-opengraph-image/go.sum b/examples/generate-opengraph-image/go.sum new file mode 100644 index 00000000..e03858ce --- /dev/null +++ b/examples/generate-opengraph-image/go.sum @@ -0,0 +1,73 @@ +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/gabriel-vasile/mimetype v1.4.7 h1:SKFKl7kD0RiPdbht0s7hFtjl489WcQ1VyPW8ZzUMYCA= +github.com/gabriel-vasile/mimetype v1.4.7/go.mod h1:GDlAgAyIRT27BhFl53XNAFtfjzOkLaF35JdEG0P7LtU= +github.com/getkin/kin-openapi v0.128.0 h1:jqq3D9vC9pPq1dGcOCv7yOp1DaEe7c/T1vzcLbITSp4= +github.com/getkin/kin-openapi v0.128.0/go.mod h1:OZrfXzUfGrNbsKj+xmFBx6E5c6yH3At/tAKSc2UszXM= +github.com/go-fuego/fuego v0.15.1 h1:9ESspiRFeUmSl2YdZzL5VE+8F2sGYSTBRkGJEfvoLXc= +github.com/go-fuego/fuego v0.15.1/go.mod h1:XMpAQQnZsoMON0UD6ncvzj6YukGQlNECDcINJt49zx4= +github.com/go-fuego/fuego/middleware/cache v0.0.0-20241205062647-57f1083dfa29 h1:lmWNDJcmLtrtVIyohuhMAQc7Xhn30CB2EZB10gkLH6w= +github.com/go-fuego/fuego/middleware/cache v0.0.0-20241205062647-57f1083dfa29/go.mod h1:OOX9YhxWG5dOkldwf+zzeBK/ef3uDPXZPSuZwA1w4Qg= +github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= +github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= +github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= +github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= +github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= +github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= +github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= +github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= +github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= +github.com/go-playground/validator/v10 v10.23.0 h1:/PwmTwZhS0dPkav3cdK9kV1FsAmrL8sThn8IHr/sO+o= +github.com/go-playground/validator/v10 v10.23.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= +github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= +github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= +github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= +github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= +github.com/gorilla/schema v1.4.1 h1:jUg5hUjCSDZpNGLuXQOgIWGdlgrIdYvgQ0wZtdK1M3E= +github.com/gorilla/schema v1.4.1/go.mod h1:Dg5SSm5PV60mhF2NFaTV1xuYYj8tV8NOPRo4FggUMnM= +github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= +github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= +github.com/invopop/yaml v0.3.1 h1:f0+ZpmhfBSS4MhG+4HYseMdJhoeeopbSKbq5Rpeelso= +github.com/invopop/yaml v0.3.1/go.mod h1:PMOp3nn4/12yEZUFfmOuNHJsZToEEOwoWsT+D81KkeA= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= +github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= +github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= +github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/thejerf/slogassert v0.3.4 h1:VoTsXixRbXMrRSSxDjYTiEDCM4VWbsYPW5rB/hX24kM= +github.com/thejerf/slogassert v0.3.4/go.mod h1:0zn9ISLVKo1aPMTqcGfG1o6dWwt+Rk574GlUxHD4rs8= +github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= +github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= +golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ= +golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg= +golang.org/x/image v0.23.0 h1:HseQ7c2OpPKTPVzNjG5fwJsOTCiiwS4QdsYi5XU6H68= +golang.org/x/image v0.23.0/go.mod h1:wJJBTdLfCCf3tiHa1fNxpZmUI4mmoZvwMCPP0ddoNKY= +golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo= +golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM= +golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= +golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/examples/generate-opengraph-image/main.go b/examples/generate-opengraph-image/main.go new file mode 100644 index 00000000..d8122a26 --- /dev/null +++ b/examples/generate-opengraph-image/main.go @@ -0,0 +1,119 @@ +package main + +import ( + "image" + "image/color" + "image/png" + "log" + "net/http" + "os" + + "golang.org/x/image/font" + "golang.org/x/image/math/fixed" + + "github.com/getkin/kin-openapi/openapi3" + "github.com/golang/freetype/truetype" + + "github.com/go-fuego/fuego" + "github.com/go-fuego/fuego/middleware/cache" + "github.com/go-fuego/fuego/option" + "github.com/go-fuego/fuego/param" +) + +// A custom option to add a custom response to the OpenAPI spec. +// The route returns a PNG image. +var optionReturnsPNG = func(br *fuego.BaseRoute) { + response := openapi3.NewResponse() + response.WithDescription("Generated image") + response.WithContent(openapi3.NewContentWithSchema(nil, []string{"image/png"})) + br.Operation.AddResponse(200, response) +} + +func main() { + s := fuego.NewServer( + fuego.WithOpenAPIConfig(fuego.OpenAPIConfig{ + PrettyFormatJson: true, + }), + ) + + fuego.GetStd(s, "/{title}", imageGen, + optionReturnsPNG, + option.Description("Generate an image with a title. Useful for Opengraph."), + option.Path("title", "The title to write on the image", param.Example("example", "My awesome article!")), + option.Middleware(cache.New()), + ) + + s.Run() +} + +var ( + darkGray = color.RGBA{50, 50, 50, 0xff} + red = color.RGBA{0xE3, 0x42, 0x34, 0xff} + yellow = color.RGBA{0xFF, 0xBA, 0x08, 0xff} + green = color.RGBA{0x84, 0xBD, 0x00, 0xff} + blue = color.RGBA{0x3D, 0xAE, 0xE3, 0xff} + blue2 = color.RGBA{0x1D, 0x99, 0xF3, 0xff} + width = 400 + height = 200 + lineY = 120 + startX = 40 +) + +func imageGen(w http.ResponseWriter, r *http.Request) { + upLeft := image.Point{0, 0} + lowRight := image.Point{width, height} + + img := image.NewRGBA(image.Rectangle{upLeft, lowRight}) + + // Set color for each pixel. + for x := 0; x < width; x++ { + for y := 0; y < height; y++ { + switch { + case lineY+5 < y && y < lineY+10 && startX <= x && x < 60: + img.Set(x, y, red) + case lineY+5 < y && y < lineY+10 && 60 <= x && x < 80: + img.Set(x, y, yellow) + case lineY+5 < y && y < lineY+10 && 80 <= x && x < 100: + img.Set(x, y, green) + case lineY+5 < y && y < lineY+10 && 100 <= x && x < 120: + img.Set(x, y, blue) + case lineY+5 < y && y < lineY+10 && 120 <= x && x < 140: + img.Set(x, y, blue2) + default: + img.Set(x, y, color.White) + } + } + } + addLabel(img, startX, lineY, 36, r.PathValue("title")) + + png.Encode(w, img) +} + +func addLabel(img *image.RGBA, x, y int, size float64, label string) { + point := fixed.Point26_6{X: fixed.I(x), Y: fixed.I(y)} + + fontBytes, err := os.ReadFile("./Raleway-Regular.ttf") + if err != nil { + log.Println(err) + return + } + f, err := truetype.Parse(fontBytes) + if err != nil { + log.Println(err) + return + } + + ffont := truetype.NewFace(f, &truetype.Options{ + Size: size, + DPI: 72, + Hinting: font.HintingNone, + }) + + d := &font.Drawer{ + Dst: img, + Src: image.NewUniform(darkGray), + Face: ffont, + Dot: point, + } + d.DrawString(label) +} diff --git a/go.work b/go.work index 5faa8d33..0d2d1f60 100644 --- a/go.work +++ b/go.work @@ -1,4 +1,4 @@ -go 1.22.6 +go 1.23.3 use ( . @@ -7,6 +7,7 @@ use ( ./examples/basic ./examples/custom-serializer ./examples/full-app-gourmet + ./examples/generate-opengraph-image ./examples/hello-world ./examples/openapi ./extra/markdown From c710645a211b6301172933bbff51ecb496830e47 Mon Sep 17 00:00:00 2001 From: EwenQuim Date: Thu, 5 Dec 2024 18:34:00 +0100 Subject: [PATCH 009/138] Updated CI go version to 1.23 --- .github/workflows/go.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 4e805ec4..3125a866 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -9,7 +9,7 @@ on: branches: ["main"] env: - GO_VERSION: "1.22" + GO_VERSION: "1.23" jobs: tests: @@ -57,4 +57,3 @@ jobs: go-version: ${{ env.GO_VERSION }} - run: make dependencies-analyze - From f9155261deead3ff2981ad8bf0e9493cc1fcf15c Mon Sep 17 00:00:00 2001 From: EwenQuim Date: Thu, 5 Dec 2024 22:27:26 +0100 Subject: [PATCH 010/138] Actually reusable OpenGraph image generation --- .../controller/opengraph.go | 93 +++++++++++++++++++ examples/generate-opengraph-image/main.go | 86 +---------------- 2 files changed, 95 insertions(+), 84 deletions(-) create mode 100644 examples/generate-opengraph-image/controller/opengraph.go diff --git a/examples/generate-opengraph-image/controller/opengraph.go b/examples/generate-opengraph-image/controller/opengraph.go new file mode 100644 index 00000000..2c3e8923 --- /dev/null +++ b/examples/generate-opengraph-image/controller/opengraph.go @@ -0,0 +1,93 @@ +package controller + +import ( + "image" + "image/color" + "image/png" + "log" + "net/http" + "os" + + "github.com/golang/freetype/truetype" + "golang.org/x/image/font" + "golang.org/x/image/math/fixed" +) + +var ( + Title = "Ewen's Notes" + SubtitleColor = color.RGBA{200, 200, 200, 0xff} + TitleColor = color.RGBA{255, 255, 255, 0xff} + LineColor = color.RGBA{0x3D, 0xAE, 0xE3, 0xff} + + Font *truetype.Font = nil + FontFile = "./Raleway-Regular.ttf" + + width = 400 + height = 200 + lineY = 120 + startX = 32 +) + +func OpenGraphHandler(w http.ResponseWriter, r *http.Request) { + upLeft := image.Point{0, 0} + lowRight := image.Point{width, height} + + img := image.NewRGBA(image.Rectangle{upLeft, lowRight}) + + // Set color for each pixel. + for x := 0; x < width; x++ { + for y := 0; y < height; y++ { + switch { + case lineY < y && y < lineY+4 && startX <= x && x < 140: + img.Set(x, y, LineColor) + default: + img.Set(x, y, color.Black) + } + } + } + addLabel(img, startX, lineY-12, 36, r.PathValue("title"), TitleColor) + addLabel(img, startX, lineY+32, 24, Title, SubtitleColor) + + png.Encode(w, img) +} + +func addLabel(img *image.RGBA, x, y int, size float64, label string, color color.RGBA) { + point := fixed.Point26_6{X: fixed.I(x), Y: fixed.I(y)} + + if Font == nil { + fontBytes, err := os.ReadFile(FontFile) + if err != nil { + log.Println(err) + return + } + f, err := truetype.Parse(fontBytes) + if err != nil { + log.Println(err) + return + } + Font = f + } + + ffont := truetype.NewFace(Font, &truetype.Options{ + Size: size, + DPI: 72, + Hinting: font.HintingNone, + }) + + d := &font.Drawer{ + Dst: img, + Src: image.NewUniform(color), + Face: ffont, + Dot: point, + } + + for d.MeasureString(label).Ceil() > width-(2*startX) || size <= 0 { + size-- + d.Face = truetype.NewFace(Font, &truetype.Options{ + Size: size, + DPI: 72, + Hinting: font.HintingNone, + }) + } + d.DrawString(label) +} diff --git a/examples/generate-opengraph-image/main.go b/examples/generate-opengraph-image/main.go index d8122a26..3e98af2e 100644 --- a/examples/generate-opengraph-image/main.go +++ b/examples/generate-opengraph-image/main.go @@ -1,20 +1,10 @@ package main import ( - "image" - "image/color" - "image/png" - "log" - "net/http" - "os" - - "golang.org/x/image/font" - "golang.org/x/image/math/fixed" - "github.com/getkin/kin-openapi/openapi3" - "github.com/golang/freetype/truetype" "github.com/go-fuego/fuego" + "github.com/go-fuego/fuego/examples/generate-image/controller" "github.com/go-fuego/fuego/middleware/cache" "github.com/go-fuego/fuego/option" "github.com/go-fuego/fuego/param" @@ -36,7 +26,7 @@ func main() { }), ) - fuego.GetStd(s, "/{title}", imageGen, + fuego.GetStd(s, "/{title}", controller.OpenGraphHandler, optionReturnsPNG, option.Description("Generate an image with a title. Useful for Opengraph."), option.Path("title", "The title to write on the image", param.Example("example", "My awesome article!")), @@ -45,75 +35,3 @@ func main() { s.Run() } - -var ( - darkGray = color.RGBA{50, 50, 50, 0xff} - red = color.RGBA{0xE3, 0x42, 0x34, 0xff} - yellow = color.RGBA{0xFF, 0xBA, 0x08, 0xff} - green = color.RGBA{0x84, 0xBD, 0x00, 0xff} - blue = color.RGBA{0x3D, 0xAE, 0xE3, 0xff} - blue2 = color.RGBA{0x1D, 0x99, 0xF3, 0xff} - width = 400 - height = 200 - lineY = 120 - startX = 40 -) - -func imageGen(w http.ResponseWriter, r *http.Request) { - upLeft := image.Point{0, 0} - lowRight := image.Point{width, height} - - img := image.NewRGBA(image.Rectangle{upLeft, lowRight}) - - // Set color for each pixel. - for x := 0; x < width; x++ { - for y := 0; y < height; y++ { - switch { - case lineY+5 < y && y < lineY+10 && startX <= x && x < 60: - img.Set(x, y, red) - case lineY+5 < y && y < lineY+10 && 60 <= x && x < 80: - img.Set(x, y, yellow) - case lineY+5 < y && y < lineY+10 && 80 <= x && x < 100: - img.Set(x, y, green) - case lineY+5 < y && y < lineY+10 && 100 <= x && x < 120: - img.Set(x, y, blue) - case lineY+5 < y && y < lineY+10 && 120 <= x && x < 140: - img.Set(x, y, blue2) - default: - img.Set(x, y, color.White) - } - } - } - addLabel(img, startX, lineY, 36, r.PathValue("title")) - - png.Encode(w, img) -} - -func addLabel(img *image.RGBA, x, y int, size float64, label string) { - point := fixed.Point26_6{X: fixed.I(x), Y: fixed.I(y)} - - fontBytes, err := os.ReadFile("./Raleway-Regular.ttf") - if err != nil { - log.Println(err) - return - } - f, err := truetype.Parse(fontBytes) - if err != nil { - log.Println(err) - return - } - - ffont := truetype.NewFace(f, &truetype.Options{ - Size: size, - DPI: 72, - Hinting: font.HintingNone, - }) - - d := &font.Drawer{ - Dst: img, - Src: image.NewUniform(darkGray), - Face: ffont, - Dot: point, - } - d.DrawString(label) -} From 944b22cd5ef8bdc1634abe20bd2d6aa851b6cd2e Mon Sep 17 00:00:00 2001 From: dylanhitt Date: Thu, 21 Nov 2024 18:34:09 -0500 Subject: [PATCH 011/138] BREAKING: only respond with HTTPError on proper type match --- errors.go | 10 +++++++++- errors_test.go | 6 ++---- examples/petstore/controllers/pets.go | 11 ++++++++++- .../petstore/lib/testdata/doc/openapi.golden.json | 11 ++++++++++- serve_test.go | 6 +++--- server_test.go | 2 +- 6 files changed, 35 insertions(+), 11 deletions(-) diff --git a/errors.go b/errors.go index 8fe343ae..44f24540 100644 --- a/errors.go +++ b/errors.go @@ -125,6 +125,15 @@ func (e NotAcceptableError) Unwrap() error { return HTTPError(e) } // It transforms any error into the unified error type [HTTPError], // Using the [ErrorWithStatus] interface. func ErrorHandler(err error) error { + var errorStatus ErrorWithStatus + if errors.As(err, &HTTPError{}) || errors.As(err, &errorStatus) { + return handleHTTPError(err) + } + + return err +} + +func handleHTTPError(err error) HTTPError { errResponse := HTTPError{ Err: err, } @@ -135,7 +144,6 @@ func ErrorHandler(err error) error { } // Check status code - errResponse.Status = http.StatusInternalServerError var errorStatus ErrorWithStatus if errors.As(err, &errorStatus) { errResponse.Status = errorStatus.StatusCode() diff --git a/errors_test.go b/errors_test.go index a0ee09ac..122c117a 100644 --- a/errors_test.go +++ b/errors_test.go @@ -18,13 +18,11 @@ func (e myError) Error() string { return "test error" } func (e myError) StatusCode() int { return e.status } func TestErrorHandler(t *testing.T) { - t.Run("basic error", func(t *testing.T) { + t.Run("basic", func(t *testing.T) { err := errors.New("test error") errResponse := ErrorHandler(err) - require.ErrorAs(t, errResponse, &HTTPError{}) - require.Contains(t, errResponse.Error(), "Internal Server Error") - require.Equal(t, http.StatusInternalServerError, errResponse.(HTTPError).StatusCode()) + require.Contains(t, errResponse.Error(), "test error") }) t.Run("not found error", func(t *testing.T) { diff --git a/examples/petstore/controllers/pets.go b/examples/petstore/controllers/pets.go index e5103d49..778f0a28 100644 --- a/examples/petstore/controllers/pets.go +++ b/examples/petstore/controllers/pets.go @@ -19,6 +19,15 @@ type PetsResources struct { PetsService PetsService } +type PetsError struct { + Err error `json:"-" xml:"-"` + Message string `json:"message"` +} + +var _ error = PetsError{} + +func (e PetsError) Error() string { return e.Err.Error() } + func (rs PetsResources) Routes(s *fuego.Server) { petsGroup := fuego.Group(s, "/pets", option.Header("X-Header", "header description")) @@ -37,7 +46,7 @@ func (rs PetsResources) Routes(s *fuego.Server) { fuego.Get(petsGroup, "/by-age", rs.getAllPetsByAge, option.Description("Returns an array of pets grouped by age")) fuego.Post(petsGroup, "/", rs.postPets, - option.AddError(409, "Conflict: Pet with the same name already exists"), + option.AddError(409, "Conflict: Pet with the same name already exists", PetsError{}), ) fuego.Get(petsGroup, "/{id}", rs.getPets, diff --git a/examples/petstore/lib/testdata/doc/openapi.golden.json b/examples/petstore/lib/testdata/doc/openapi.golden.json index f57b45a5..7f63affa 100644 --- a/examples/petstore/lib/testdata/doc/openapi.golden.json +++ b/examples/petstore/lib/testdata/doc/openapi.golden.json @@ -105,6 +105,15 @@ ], "type": "object" }, + "PetsError": { + "description": "PetsError schema", + "properties": { + "message": { + "type": "string" + } + }, + "type": "object" + }, "PetsUpdate": { "description": "PetsUpdate schema", "properties": { @@ -326,7 +335,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/HTTPError" + "$ref": "#/components/schemas/PetsError" } } }, diff --git a/serve_test.go b/serve_test.go index 4999d91b..c719fab7 100644 --- a/serve_test.go +++ b/serve_test.go @@ -31,7 +31,7 @@ func testController(c *ContextNoBody) (ans, error) { } func testControllerWithError(c *ContextNoBody) (ans, error) { - return ans{}, errors.New("error happened!") + return ans{}, HTTPError{Err: errors.New("error happened!")} } type testOutTransformer struct { @@ -56,7 +56,7 @@ func testControllerWithOutTransformerStar(c *ContextNoBody) (*testOutTransformer } func testControllerWithOutTransformerStarError(c *ContextNoBody) (*testOutTransformer, error) { - return nil, errors.New("error happened!") + return nil, HTTPError{Err: errors.New("error happened!")} } func testControllerWithOutTransformerStarNil(c *ContextNoBody) (*testOutTransformer, error) { @@ -333,7 +333,7 @@ func TestServeError(t *testing.T) { s := NewServer() Get(s, "/ctx/error-in-controller", func(c *ContextNoBody) (CtxRenderer, error) { - return nil, errors.New("error") + return nil, HTTPError{Err: errors.New("error")} }) t.Run("error return, asking for HTML", func(t *testing.T) { diff --git a/server_test.go b/server_test.go index e1271508..ae4d6842 100644 --- a/server_test.go +++ b/server_test.go @@ -19,7 +19,7 @@ func controller(c *ContextNoBody) (testStruct, error) { } func controllerWithError(c *ContextNoBody) (testStruct, error) { - return testStruct{}, errors.New("error") + return testStruct{}, HTTPError{Err: errors.New("error")} } func TestNewServer(t *testing.T) { From bb0698792711a79ca0ba3434918ad0a8367ea61a Mon Sep 17 00:00:00 2001 From: dylanhitt Date: Mon, 25 Nov 2024 10:10:36 -0500 Subject: [PATCH 012/138] chore: add ErrorHandler test case to ensure not duplicate HTTPError nesting --- errors_test.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/errors_test.go b/errors_test.go index 122c117a..b1b333ee 100644 --- a/errors_test.go +++ b/errors_test.go @@ -37,6 +37,18 @@ func TestErrorHandler(t *testing.T) { require.Equal(t, http.StatusNotFound, errResponse.(HTTPError).StatusCode()) }) + t.Run("not duplicate HTTPError", func(t *testing.T) { + err := HTTPError{ + Err: errors.New("HTTPError"), + } + errResponse := ErrorHandler(err) + + var httpError HTTPError + require.ErrorAs(t, errResponse, &httpError) + require.False(t, errors.As(httpError.Err, &HTTPError{})) + require.Contains(t, err.Error(), "Internal Server Error") + }) + t.Run("error with status ", func(t *testing.T) { err := myError{ status: http.StatusNotFound, From db6243588e8372496ee79e461aa0e64ec79e372c Mon Sep 17 00:00:00 2001 From: dylanhitt Date: Mon, 25 Nov 2024 10:17:16 -0500 Subject: [PATCH 013/138] chore: update ErrorHandler docs --- errors.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/errors.go b/errors.go index 44f24540..4e0c3b53 100644 --- a/errors.go +++ b/errors.go @@ -122,8 +122,11 @@ func (e NotAcceptableError) StatusCode() int { return http.StatusNotAcceptable } func (e NotAcceptableError) Unwrap() error { return HTTPError(e) } // ErrorHandler is the default error handler used by the framework. -// It transforms any error into the unified error type [HTTPError], -// Using the [ErrorWithStatus] interface. +// If the error is an [HTTPError] that is error is returned. +// If the error adheres to the [ErrorWithStatus] interface +// the error is transformed to a [HTTPError]. +// If the error is not an [HTTPError] nor does it adhere to an +// interface the error is returned. func ErrorHandler(err error) error { var errorStatus ErrorWithStatus if errors.As(err, &HTTPError{}) || errors.As(err, &errorStatus) { From 0851684be5cfd5932b75f28fbb164cb066dc222a Mon Sep 17 00:00:00 2001 From: dylanhitt Date: Wed, 27 Nov 2024 09:52:49 -0500 Subject: [PATCH 014/138] chore: bump go testify across all modules --- examples/acme-tls/go.mod | 1 + examples/full-app-gourmet/go.sum | 3 +-- examples/hello-world/go.mod | 1 + examples/hello-world/go.sum | 3 +-- examples/openapi/go.mod | 1 + examples/openapi/go.sum | 3 +-- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/acme-tls/go.mod b/examples/acme-tls/go.mod index 12f1fa3c..f68617b9 100644 --- a/examples/acme-tls/go.mod +++ b/examples/acme-tls/go.mod @@ -28,6 +28,7 @@ require ( github.com/miekg/dns v1.1.62 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect + github.com/stretchr/testify v1.10.0 // indirect github.com/zeebo/blake3 v0.2.4 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect diff --git a/examples/full-app-gourmet/go.sum b/examples/full-app-gourmet/go.sum index e037b7e5..de1b32a6 100644 --- a/examples/full-app-gourmet/go.sum +++ b/examples/full-app-gourmet/go.sum @@ -79,8 +79,7 @@ github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA= github.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/thejerf/slogassert v0.3.4 h1:VoTsXixRbXMrRSSxDjYTiEDCM4VWbsYPW5rB/hX24kM= github.com/thejerf/slogassert v0.3.4/go.mod h1:0zn9ISLVKo1aPMTqcGfG1o6dWwt+Rk574GlUxHD4rs8= github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= diff --git a/examples/hello-world/go.mod b/examples/hello-world/go.mod index 8bb35a4e..3dd0e386 100644 --- a/examples/hello-world/go.mod +++ b/examples/hello-world/go.mod @@ -20,6 +20,7 @@ require ( github.com/mailru/easyjson v0.7.7 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect + github.com/stretchr/testify v1.10.0 // indirect golang.org/x/crypto v0.27.0 // indirect golang.org/x/net v0.29.0 // indirect golang.org/x/sys v0.25.0 // indirect diff --git a/examples/hello-world/go.sum b/examples/hello-world/go.sum index 55a7a2c0..9fbd4d8e 100644 --- a/examples/hello-world/go.sum +++ b/examples/hello-world/go.sum @@ -44,8 +44,7 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= diff --git a/examples/openapi/go.mod b/examples/openapi/go.mod index ac1d7cab..c99d8005 100644 --- a/examples/openapi/go.mod +++ b/examples/openapi/go.mod @@ -20,6 +20,7 @@ require ( github.com/mailru/easyjson v0.7.7 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect + github.com/stretchr/testify v1.10.0 // indirect golang.org/x/crypto v0.27.0 // indirect golang.org/x/net v0.29.0 // indirect golang.org/x/sys v0.25.0 // indirect diff --git a/examples/openapi/go.sum b/examples/openapi/go.sum index 55a7a2c0..9fbd4d8e 100644 --- a/examples/openapi/go.sum +++ b/examples/openapi/go.sum @@ -44,8 +44,7 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= From 21343a6482a4aecf8e672bed00549c9157b49881 Mon Sep 17 00:00:00 2001 From: dylanhitt Date: Wed, 27 Nov 2024 10:05:19 -0500 Subject: [PATCH 015/138] chore: use updated testify functions in errors tests --- errors_test.go | 42 +++++++++++++-------------- examples/petstore/controllers/pets.go | 2 +- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/errors_test.go b/errors_test.go index b1b333ee..b49c9a77 100644 --- a/errors_test.go +++ b/errors_test.go @@ -22,7 +22,7 @@ func TestErrorHandler(t *testing.T) { err := errors.New("test error") errResponse := ErrorHandler(err) - require.Contains(t, errResponse.Error(), "test error") + require.ErrorContains(t, errResponse, "test error") }) t.Run("not found error", func(t *testing.T) { @@ -31,9 +31,9 @@ func TestErrorHandler(t *testing.T) { } errResponse := ErrorHandler(err) require.ErrorAs(t, errResponse, &HTTPError{}) - require.Contains(t, err.Error(), "Not Found :c") - require.Contains(t, errResponse.Error(), "Not Found") - require.Contains(t, errResponse.Error(), "404") + require.ErrorContains(t, err, "Not Found :c") + require.ErrorContains(t, errResponse, "Not Found") + require.ErrorContains(t, errResponse, "404") require.Equal(t, http.StatusNotFound, errResponse.(HTTPError).StatusCode()) }) @@ -45,8 +45,8 @@ func TestErrorHandler(t *testing.T) { var httpError HTTPError require.ErrorAs(t, errResponse, &httpError) - require.False(t, errors.As(httpError.Err, &HTTPError{})) - require.Contains(t, err.Error(), "Internal Server Error") + require.NotErrorAs(t, httpError.Err, &HTTPError{}) + require.ErrorContains(t, err, "Internal Server Error") }) t.Run("error with status ", func(t *testing.T) { @@ -55,8 +55,8 @@ func TestErrorHandler(t *testing.T) { } errResponse := ErrorHandler(err) require.ErrorAs(t, errResponse, &HTTPError{}) - require.Contains(t, errResponse.Error(), "Not Found") - require.Contains(t, errResponse.Error(), "404") + require.ErrorContains(t, errResponse, "Not Found") + require.ErrorContains(t, errResponse, "404") require.Equal(t, http.StatusNotFound, errResponse.(HTTPError).StatusCode()) }) @@ -66,9 +66,9 @@ func TestErrorHandler(t *testing.T) { } errResponse := ErrorHandler(err) require.ErrorAs(t, errResponse, &HTTPError{}) - require.Contains(t, err.Error(), "Conflict") - require.Contains(t, errResponse.Error(), "Conflict") - require.Contains(t, errResponse.Error(), "409") + require.ErrorContains(t, err, "Conflict") + require.ErrorContains(t, errResponse, "Conflict") + require.ErrorContains(t, errResponse, "409") require.Equal(t, http.StatusConflict, errResponse.(HTTPError).StatusCode()) }) @@ -78,9 +78,9 @@ func TestErrorHandler(t *testing.T) { } errResponse := ErrorHandler(err) require.ErrorAs(t, errResponse, &HTTPError{}) - require.Contains(t, err.Error(), "coucou") - require.Contains(t, errResponse.Error(), "Unauthorized") - require.Contains(t, errResponse.Error(), "401") + require.ErrorContains(t, err, "coucou") + require.ErrorContains(t, errResponse, "Unauthorized") + require.ErrorContains(t, errResponse, "401") require.Equal(t, http.StatusUnauthorized, errResponse.(HTTPError).StatusCode()) }) @@ -90,9 +90,9 @@ func TestErrorHandler(t *testing.T) { } errResponse := ErrorHandler(err) require.ErrorAs(t, errResponse, &HTTPError{}) - require.Contains(t, err.Error(), "Forbidden") - require.Contains(t, errResponse.Error(), "Forbidden") - require.Contains(t, errResponse.Error(), "403") + require.ErrorContains(t, err, "Forbidden") + require.ErrorContains(t, errResponse, "Forbidden") + require.ErrorContains(t, errResponse, "403") require.Equal(t, http.StatusForbidden, errResponse.(HTTPError).StatusCode()) }) } @@ -103,15 +103,15 @@ func TestHTTPError_Error(t *testing.T) { err := HTTPError{ Title: "Custom Title", } - require.Contains(t, err.Error(), "Custom Title") + require.ErrorContains(t, err, "Custom Title") }) t.Run("title from status", func(t *testing.T) { err := HTTPError{Status: http.StatusNotFound} - require.Contains(t, err.Error(), "Not Found") + require.ErrorContains(t, err, "Not Found") }) t.Run("default title", func(t *testing.T) { err := HTTPError{} - require.Contains(t, err.Error(), "Internal Server Error") + require.ErrorContains(t, err, "Internal Server Error") }) }) } @@ -124,6 +124,6 @@ func TestHTTPError_Unwrap(t *testing.T) { } var unwrapped myError - require.True(t, errors.As(errResponse.Unwrap(), &unwrapped)) + require.ErrorAs(t, errResponse.Unwrap(), &unwrapped) require.Equal(t, 999, unwrapped.status) } diff --git a/examples/petstore/controllers/pets.go b/examples/petstore/controllers/pets.go index 778f0a28..6a8a63cd 100644 --- a/examples/petstore/controllers/pets.go +++ b/examples/petstore/controllers/pets.go @@ -21,7 +21,7 @@ type PetsResources struct { type PetsError struct { Err error `json:"-" xml:"-"` - Message string `json:"message"` + Message string `json:"message" xml:"message"` } var _ error = PetsError{} From 4c4bc8bfe6ef043339072d9ffa66307286b6696c Mon Sep 17 00:00:00 2001 From: dylanhitt Date: Wed, 27 Nov 2024 10:43:43 -0500 Subject: [PATCH 016/138] chore: improve readability with switch case --- cmd/fuego/go.mod | 2 +- cmd/fuego/go.sum | 3 +-- errors.go | 4 +++- examples/acme-tls/go.mod | 4 ++-- examples/acme-tls/go.sum | 9 +++------ examples/basic/go.mod | 3 ++- examples/basic/go.sum | 6 ++---- examples/custom-serializer/go.mod | 3 ++- examples/custom-serializer/go.sum | 6 ++---- examples/full-app-gourmet/go.mod | 16 ++++++++-------- examples/full-app-gourmet/go.sum | 29 ++++++++++------------------- examples/hello-world/go.mod | 14 +++++++------- examples/hello-world/go.sum | 20 +++++++------------- examples/openapi/go.mod | 14 +++++++------- examples/openapi/go.sum | 20 +++++++------------- extra/markdown/go.sum | 3 +-- go.mod | 2 +- go.sum | 3 +-- middleware/basicauth/go.sum | 2 +- middleware/cache/go.sum | 2 +- testing-from-outside/go.mod | 14 +++++++------- testing-from-outside/go.sum | 17 ++++++++--------- 22 files changed, 84 insertions(+), 112 deletions(-) diff --git a/cmd/fuego/go.mod b/cmd/fuego/go.mod index ebb7ada0..21641070 100644 --- a/cmd/fuego/go.mod +++ b/cmd/fuego/go.mod @@ -8,7 +8,7 @@ require ( github.com/go-fuego/fuego v0.15.0 github.com/stretchr/testify v1.10.0 github.com/urfave/cli/v2 v2.27.5 - golang.org/x/text v0.20.0 + golang.org/x/text v0.21.0 ) require ( diff --git a/cmd/fuego/go.sum b/cmd/fuego/go.sum index ee8be7c2..7e2a9e75 100644 --- a/cmd/fuego/go.sum +++ b/cmd/fuego/go.sum @@ -64,8 +64,7 @@ golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo= golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM= golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug= -golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/errors.go b/errors.go index 4e0c3b53..75ffcb07 100644 --- a/errors.go +++ b/errors.go @@ -129,7 +129,9 @@ func (e NotAcceptableError) Unwrap() error { return HTTPError(e) } // interface the error is returned. func ErrorHandler(err error) error { var errorStatus ErrorWithStatus - if errors.As(err, &HTTPError{}) || errors.As(err, &errorStatus) { + switch { + case errors.As(err, &HTTPError{}), + errors.As(err, &errorStatus): return handleHTTPError(err) } diff --git a/examples/acme-tls/go.mod b/examples/acme-tls/go.mod index f68617b9..ff2b9dbf 100644 --- a/examples/acme-tls/go.mod +++ b/examples/acme-tls/go.mod @@ -35,9 +35,9 @@ require ( golang.org/x/crypto v0.29.0 // indirect golang.org/x/mod v0.22.0 // indirect golang.org/x/net v0.31.0 // indirect - golang.org/x/sync v0.9.0 // indirect + golang.org/x/sync v0.10.0 // indirect golang.org/x/sys v0.27.0 // indirect - golang.org/x/text v0.20.0 // indirect + golang.org/x/text v0.21.0 // indirect golang.org/x/tools v0.27.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/examples/acme-tls/go.sum b/examples/acme-tls/go.sum index 2cb26124..0fb27ee8 100644 --- a/examples/acme-tls/go.sum +++ b/examples/acme-tls/go.sum @@ -56,8 +56,7 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/thejerf/slogassert v0.3.4 h1:VoTsXixRbXMrRSSxDjYTiEDCM4VWbsYPW5rB/hX24kM= github.com/thejerf/slogassert v0.3.4/go.mod h1:0zn9ISLVKo1aPMTqcGfG1o6dWwt+Rk574GlUxHD4rs8= github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= @@ -80,12 +79,10 @@ golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4= golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo= golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM= -golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ= -golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug= -golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= golang.org/x/tools v0.27.0 h1:qEKojBykQkQ4EynWy4S8Weg69NumxKdn40Fce3uc/8o= golang.org/x/tools v0.27.0/go.mod h1:sUi0ZgbwW9ZPAq26Ekut+weQPR5eIM6GQLQ1Yjm1H0Q= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/examples/basic/go.mod b/examples/basic/go.mod index b344a264..8a4fa061 100644 --- a/examples/basic/go.mod +++ b/examples/basic/go.mod @@ -24,9 +24,10 @@ require ( github.com/mailru/easyjson v0.7.7 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect + github.com/stretchr/testify v1.10.0 // indirect golang.org/x/crypto v0.29.0 // indirect golang.org/x/net v0.31.0 // indirect golang.org/x/sys v0.27.0 // indirect - golang.org/x/text v0.20.0 // indirect + golang.org/x/text v0.21.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/examples/basic/go.sum b/examples/basic/go.sum index 2b9c28b0..e6bbcdca 100644 --- a/examples/basic/go.sum +++ b/examples/basic/go.sum @@ -48,8 +48,7 @@ github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA= github.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/thejerf/slogassert v0.3.4 h1:VoTsXixRbXMrRSSxDjYTiEDCM4VWbsYPW5rB/hX24kM= github.com/thejerf/slogassert v0.3.4/go.mod h1:0zn9ISLVKo1aPMTqcGfG1o6dWwt+Rk574GlUxHD4rs8= github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= @@ -60,8 +59,7 @@ golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo= golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM= golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug= -golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/examples/custom-serializer/go.mod b/examples/custom-serializer/go.mod index 3d94b98b..66c60f7e 100644 --- a/examples/custom-serializer/go.mod +++ b/examples/custom-serializer/go.mod @@ -25,9 +25,10 @@ require ( github.com/modern-go/reflect2 v1.0.2 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect + github.com/stretchr/testify v1.10.0 // indirect golang.org/x/crypto v0.29.0 // indirect golang.org/x/net v0.31.0 // indirect golang.org/x/sys v0.27.0 // indirect - golang.org/x/text v0.20.0 // indirect + golang.org/x/text v0.21.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/examples/custom-serializer/go.sum b/examples/custom-serializer/go.sum index 6c239ca5..564728b6 100644 --- a/examples/custom-serializer/go.sum +++ b/examples/custom-serializer/go.sum @@ -55,8 +55,7 @@ github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/thejerf/slogassert v0.3.4 h1:VoTsXixRbXMrRSSxDjYTiEDCM4VWbsYPW5rB/hX24kM= github.com/thejerf/slogassert v0.3.4/go.mod h1:0zn9ISLVKo1aPMTqcGfG1o6dWwt+Rk574GlUxHD4rs8= github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= @@ -67,8 +66,7 @@ golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo= golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM= golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug= -golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/examples/full-app-gourmet/go.mod b/examples/full-app-gourmet/go.mod index 3fb35383..8b78986b 100644 --- a/examples/full-app-gourmet/go.mod +++ b/examples/full-app-gourmet/go.mod @@ -14,20 +14,20 @@ require ( github.com/lmittmann/tint v1.0.5 github.com/rs/cors v1.11.1 github.com/stretchr/testify v1.10.0 - golang.org/x/text v0.19.0 + golang.org/x/text v0.21.0 modernc.org/sqlite v1.33.1 ) require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/dustin/go-humanize v1.0.1 // indirect - github.com/gabriel-vasile/mimetype v1.4.5 // indirect - github.com/getkin/kin-openapi v0.127.0 // indirect + github.com/gabriel-vasile/mimetype v1.4.7 // indirect + github.com/getkin/kin-openapi v0.128.0 // indirect github.com/go-openapi/jsonpointer v0.21.0 // indirect github.com/go-openapi/swag v0.23.0 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect - github.com/go-playground/validator/v10 v10.22.1 // indirect + github.com/go-playground/validator/v10 v10.23.0 // indirect github.com/gomarkdown/markdown v0.0.0-20240730141124-034f12af3bf6 // indirect github.com/gorilla/schema v1.4.1 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect @@ -44,10 +44,10 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect go.uber.org/atomic v1.11.0 // indirect - golang.org/x/crypto v0.27.0 // indirect - golang.org/x/net v0.29.0 // indirect - golang.org/x/sys v0.25.0 // indirect - golang.org/x/tools v0.25.0 // indirect + golang.org/x/crypto v0.29.0 // indirect + golang.org/x/net v0.31.0 // indirect + golang.org/x/sys v0.27.0 // indirect + golang.org/x/tools v0.27.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect modernc.org/gc/v3 v3.0.0-20240801135723-a856999a2e4a // indirect modernc.org/libc v1.55.3 // indirect diff --git a/examples/full-app-gourmet/go.sum b/examples/full-app-gourmet/go.sum index de1b32a6..5cdb2fe6 100644 --- a/examples/full-app-gourmet/go.sum +++ b/examples/full-app-gourmet/go.sum @@ -4,10 +4,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= -github.com/gabriel-vasile/mimetype v1.4.5 h1:J7wGKdGu33ocBOhGy0z653k/lFKLFDPJMG8Gql0kxn4= -github.com/gabriel-vasile/mimetype v1.4.5/go.mod h1:ibHel+/kbxn9x2407k1izTA1S81ku1z/DlgOW2QE0M4= -github.com/getkin/kin-openapi v0.127.0 h1:Mghqi3Dhryf3F8vR370nN67pAERW+3a95vomb3MAREY= -github.com/getkin/kin-openapi v0.127.0/go.mod h1:OZrfXzUfGrNbsKj+xmFBx6E5c6yH3At/tAKSc2UszXM= +github.com/gabriel-vasile/mimetype v1.4.7 h1:SKFKl7kD0RiPdbht0s7hFtjl489WcQ1VyPW8ZzUMYCA= +github.com/getkin/kin-openapi v0.128.0 h1:jqq3D9vC9pPq1dGcOCv7yOp1DaEe7c/T1vzcLbITSp4= github.com/go-chi/chi/v5 v5.1.0 h1:acVI1TYaD+hhedDJ3r54HyA6sExp3HfXq7QWEEY/xMw= github.com/go-chi/chi/v5 v5.1.0/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= @@ -20,8 +18,7 @@ github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/o github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= -github.com/go-playground/validator/v10 v10.22.1 h1:40JcKH+bBNGFczGuoBYgX4I6m/i27HYW8P9FDk5PbgA= -github.com/go-playground/validator/v10 v10.22.1/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= +github.com/go-playground/validator/v10 v10.23.0 h1:/PwmTwZhS0dPkav3cdK9kV1FsAmrL8sThn8IHr/sO+o= github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= @@ -86,20 +83,14 @@ github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0 github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= -golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= -golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= -golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= -golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= -golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ= +golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4= +golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= -golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= -golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -golang.org/x/tools v0.25.0 h1:oFU9pkj/iJgs+0DT+VMHrx+oBKs/LJMV+Uvg78sl+fE= +golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/tools v0.27.0 h1:qEKojBykQkQ4EynWy4S8Weg69NumxKdn40Fce3uc/8o= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/examples/hello-world/go.mod b/examples/hello-world/go.mod index 3dd0e386..eb88cf4e 100644 --- a/examples/hello-world/go.mod +++ b/examples/hello-world/go.mod @@ -5,13 +5,13 @@ go 1.22.2 require github.com/go-fuego/fuego v0.14.0 require ( - github.com/gabriel-vasile/mimetype v1.4.5 // indirect - github.com/getkin/kin-openapi v0.127.0 // indirect + github.com/gabriel-vasile/mimetype v1.4.7 // indirect + github.com/getkin/kin-openapi v0.128.0 // indirect github.com/go-openapi/jsonpointer v0.21.0 // indirect github.com/go-openapi/swag v0.23.0 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect - github.com/go-playground/validator/v10 v10.22.1 // indirect + github.com/go-playground/validator/v10 v10.23.0 // indirect github.com/golang-jwt/jwt/v5 v5.2.1 // indirect github.com/gorilla/schema v1.4.1 // indirect github.com/invopop/yaml v0.3.1 // indirect @@ -21,9 +21,9 @@ require ( github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect github.com/stretchr/testify v1.10.0 // indirect - golang.org/x/crypto v0.27.0 // indirect - golang.org/x/net v0.29.0 // indirect - golang.org/x/sys v0.25.0 // indirect - golang.org/x/text v0.19.0 // indirect + golang.org/x/crypto v0.29.0 // indirect + golang.org/x/net v0.31.0 // indirect + golang.org/x/sys v0.27.0 // indirect + golang.org/x/text v0.21.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/examples/hello-world/go.sum b/examples/hello-world/go.sum index 9fbd4d8e..36ba2f6f 100644 --- a/examples/hello-world/go.sum +++ b/examples/hello-world/go.sum @@ -1,9 +1,7 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/gabriel-vasile/mimetype v1.4.5 h1:J7wGKdGu33ocBOhGy0z653k/lFKLFDPJMG8Gql0kxn4= -github.com/gabriel-vasile/mimetype v1.4.5/go.mod h1:ibHel+/kbxn9x2407k1izTA1S81ku1z/DlgOW2QE0M4= -github.com/getkin/kin-openapi v0.127.0 h1:Mghqi3Dhryf3F8vR370nN67pAERW+3a95vomb3MAREY= -github.com/getkin/kin-openapi v0.127.0/go.mod h1:OZrfXzUfGrNbsKj+xmFBx6E5c6yH3At/tAKSc2UszXM= +github.com/gabriel-vasile/mimetype v1.4.7 h1:SKFKl7kD0RiPdbht0s7hFtjl489WcQ1VyPW8ZzUMYCA= +github.com/getkin/kin-openapi v0.128.0 h1:jqq3D9vC9pPq1dGcOCv7yOp1DaEe7c/T1vzcLbITSp4= github.com/go-fuego/fuego v0.14.0 h1:jYrfTXSAiWxYcqJUpFVUjH4EZ5ZBcy8piszeRlky7ZU= github.com/go-fuego/fuego v0.14.0/go.mod h1:T+e74Ln/DR8XRCQ421seu8QvmogpRpR/0D3dYxcEq6U= github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= @@ -16,8 +14,7 @@ github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/o github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= -github.com/go-playground/validator/v10 v10.22.1 h1:40JcKH+bBNGFczGuoBYgX4I6m/i27HYW8P9FDk5PbgA= -github.com/go-playground/validator/v10 v10.22.1/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= +github.com/go-playground/validator/v10 v10.23.0 h1:/PwmTwZhS0dPkav3cdK9kV1FsAmrL8sThn8IHr/sO+o= github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= @@ -47,13 +44,10 @@ github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99 github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= -golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= -golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= -golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= -golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= -golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= -golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= +golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ= +golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo= +golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/examples/openapi/go.mod b/examples/openapi/go.mod index c99d8005..f4f5dc01 100644 --- a/examples/openapi/go.mod +++ b/examples/openapi/go.mod @@ -5,13 +5,13 @@ go 1.22.2 require github.com/go-fuego/fuego v0.14.0 require ( - github.com/gabriel-vasile/mimetype v1.4.5 // indirect - github.com/getkin/kin-openapi v0.127.0 // indirect + github.com/gabriel-vasile/mimetype v1.4.7 // indirect + github.com/getkin/kin-openapi v0.128.0 // indirect github.com/go-openapi/jsonpointer v0.21.0 // indirect github.com/go-openapi/swag v0.23.0 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect - github.com/go-playground/validator/v10 v10.22.1 // indirect + github.com/go-playground/validator/v10 v10.23.0 // indirect github.com/golang-jwt/jwt/v5 v5.2.1 // indirect github.com/gorilla/schema v1.4.1 // indirect github.com/invopop/yaml v0.3.1 // indirect @@ -21,9 +21,9 @@ require ( github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect github.com/stretchr/testify v1.10.0 // indirect - golang.org/x/crypto v0.27.0 // indirect - golang.org/x/net v0.29.0 // indirect - golang.org/x/sys v0.25.0 // indirect - golang.org/x/text v0.19.0 // indirect + golang.org/x/crypto v0.29.0 // indirect + golang.org/x/net v0.31.0 // indirect + golang.org/x/sys v0.27.0 // indirect + golang.org/x/text v0.21.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/examples/openapi/go.sum b/examples/openapi/go.sum index 9fbd4d8e..36ba2f6f 100644 --- a/examples/openapi/go.sum +++ b/examples/openapi/go.sum @@ -1,9 +1,7 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/gabriel-vasile/mimetype v1.4.5 h1:J7wGKdGu33ocBOhGy0z653k/lFKLFDPJMG8Gql0kxn4= -github.com/gabriel-vasile/mimetype v1.4.5/go.mod h1:ibHel+/kbxn9x2407k1izTA1S81ku1z/DlgOW2QE0M4= -github.com/getkin/kin-openapi v0.127.0 h1:Mghqi3Dhryf3F8vR370nN67pAERW+3a95vomb3MAREY= -github.com/getkin/kin-openapi v0.127.0/go.mod h1:OZrfXzUfGrNbsKj+xmFBx6E5c6yH3At/tAKSc2UszXM= +github.com/gabriel-vasile/mimetype v1.4.7 h1:SKFKl7kD0RiPdbht0s7hFtjl489WcQ1VyPW8ZzUMYCA= +github.com/getkin/kin-openapi v0.128.0 h1:jqq3D9vC9pPq1dGcOCv7yOp1DaEe7c/T1vzcLbITSp4= github.com/go-fuego/fuego v0.14.0 h1:jYrfTXSAiWxYcqJUpFVUjH4EZ5ZBcy8piszeRlky7ZU= github.com/go-fuego/fuego v0.14.0/go.mod h1:T+e74Ln/DR8XRCQ421seu8QvmogpRpR/0D3dYxcEq6U= github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= @@ -16,8 +14,7 @@ github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/o github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= -github.com/go-playground/validator/v10 v10.22.1 h1:40JcKH+bBNGFczGuoBYgX4I6m/i27HYW8P9FDk5PbgA= -github.com/go-playground/validator/v10 v10.22.1/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= +github.com/go-playground/validator/v10 v10.23.0 h1:/PwmTwZhS0dPkav3cdK9kV1FsAmrL8sThn8IHr/sO+o= github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= @@ -47,13 +44,10 @@ github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99 github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= -golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= -golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= -golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= -golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= -golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= -golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= +golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ= +golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo= +golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/extra/markdown/go.sum b/extra/markdown/go.sum index 621b23af..d8dfd821 100644 --- a/extra/markdown/go.sum +++ b/extra/markdown/go.sum @@ -7,8 +7,7 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/go.mod b/go.mod index c61c50e1..7c8430e9 100644 --- a/go.mod +++ b/go.mod @@ -31,5 +31,5 @@ require ( golang.org/x/crypto v0.29.0 // indirect golang.org/x/net v0.31.0 // indirect golang.org/x/sys v0.27.0 // indirect - golang.org/x/text v0.20.0 // indirect + golang.org/x/text v0.21.0 // indirect ) diff --git a/go.sum b/go.sum index f3415a32..cb6f4743 100644 --- a/go.sum +++ b/go.sum @@ -56,8 +56,7 @@ golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo= golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM= golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug= -golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/middleware/basicauth/go.sum b/middleware/basicauth/go.sum index a5e595c7..e90f0a29 100644 --- a/middleware/basicauth/go.sum +++ b/middleware/basicauth/go.sum @@ -3,6 +3,6 @@ github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/middleware/cache/go.sum b/middleware/cache/go.sum index 0860a7ab..8d6fb7ac 100644 --- a/middleware/cache/go.sum +++ b/middleware/cache/go.sum @@ -4,6 +4,6 @@ github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/testing-from-outside/go.mod b/testing-from-outside/go.mod index 118757fd..ec10aa5d 100644 --- a/testing-from-outside/go.mod +++ b/testing-from-outside/go.mod @@ -10,13 +10,13 @@ require ( require ( github.com/davecgh/go-spew v1.1.1 // indirect - github.com/gabriel-vasile/mimetype v1.4.5 // indirect - github.com/getkin/kin-openapi v0.127.0 // indirect + github.com/gabriel-vasile/mimetype v1.4.7 // indirect + github.com/getkin/kin-openapi v0.128.0 // indirect github.com/go-openapi/jsonpointer v0.21.0 // indirect github.com/go-openapi/swag v0.23.0 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect - github.com/go-playground/validator/v10 v10.22.1 // indirect + github.com/go-playground/validator/v10 v10.23.0 // indirect github.com/golang-jwt/jwt/v5 v5.2.1 // indirect github.com/gomarkdown/markdown v0.0.0-20231222211730-1d6d20845b47 // indirect github.com/gorilla/schema v1.4.1 // indirect @@ -27,9 +27,9 @@ require ( github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - golang.org/x/crypto v0.27.0 // indirect - golang.org/x/net v0.29.0 // indirect - golang.org/x/sys v0.25.0 // indirect - golang.org/x/text v0.19.0 // indirect + golang.org/x/crypto v0.29.0 // indirect + golang.org/x/net v0.31.0 // indirect + golang.org/x/sys v0.27.0 // indirect + golang.org/x/text v0.21.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/testing-from-outside/go.sum b/testing-from-outside/go.sum index a871d631..6905c5cf 100644 --- a/testing-from-outside/go.sum +++ b/testing-from-outside/go.sum @@ -1,7 +1,7 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/gabriel-vasile/mimetype v1.4.5 h1:J7wGKdGu33ocBOhGy0z653k/lFKLFDPJMG8Gql0kxn4= -github.com/getkin/kin-openapi v0.127.0 h1:Mghqi3Dhryf3F8vR370nN67pAERW+3a95vomb3MAREY= +github.com/gabriel-vasile/mimetype v1.4.7 h1:SKFKl7kD0RiPdbht0s7hFtjl489WcQ1VyPW8ZzUMYCA= +github.com/getkin/kin-openapi v0.128.0 h1:jqq3D9vC9pPq1dGcOCv7yOp1DaEe7c/T1vzcLbITSp4= github.com/go-fuego/fuego v0.13.4 h1:tIDUH9ZKd8UTftkjtFnKhSYPo41NLhH1GxLsHBPZxII= github.com/go-fuego/fuego v0.13.4/go.mod h1:Haw/N+HVuU0mMTjgpPXOWsQ8DsvBJDWSiJCblEh/7P4= github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= @@ -14,7 +14,7 @@ github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/o github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= -github.com/go-playground/validator/v10 v10.22.1 h1:40JcKH+bBNGFczGuoBYgX4I6m/i27HYW8P9FDk5PbgA= +github.com/go-playground/validator/v10 v10.23.0 h1:/PwmTwZhS0dPkav3cdK9kV1FsAmrL8sThn8IHr/sO+o= github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= @@ -42,14 +42,13 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= -golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= -golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= -golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= -golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= +golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ= +golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo= +golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= From 51e881314d49da3ca4b01d007dfd9fc240ce3fe5 Mon Sep 17 00:00:00 2001 From: EwenQuim Date: Fri, 6 Dec 2024 09:15:51 +0100 Subject: [PATCH 017/138] Made README clearer --- README.md | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 17cc8267..878d20de 100644 --- a/README.md +++ b/README.md @@ -105,19 +105,22 @@ func main() { s := fuego.NewServer() // Automatically generates OpenAPI documentation for this route - fuego.Post(s, "/", func(c *fuego.ContextWithBody[MyInput]) (MyOutput, error) { - body, err := c.Body() - if err != nil { - return MyOutput{}, err - } - - return MyOutput{ - Message: "Hello, " + body.Name, - }, nil - }) + fuego.Post(s, "/user/{user}", myController) s.Run() } + +func myController(c *fuego.ContextWithBody[MyInput]) (MyOutput, error) { + body, err := c.Body() + if err != nil { + return MyOutput{}, err + } + + return MyOutput{ + Message: "Hello, " + body.Name, + }, nil +} + ``` ### With transformation & custom validation From b68c69e58294026c35b9fddc0e0b2437a7a8234a Mon Sep 17 00:00:00 2001 From: EwenQuim Date: Fri, 6 Dec 2024 09:16:19 +0100 Subject: [PATCH 018/138] Updated all dependencies --- cmd/fuego/go.mod | 8 ++-- cmd/fuego/go.sum | 17 +++---- examples/acme-tls/go.mod | 11 ++--- examples/acme-tls/go.sum | 25 ++++++---- examples/basic/go.mod | 9 ++-- examples/basic/go.sum | 18 ++++---- examples/custom-serializer/go.mod | 9 ++-- examples/custom-serializer/go.sum | 18 ++++---- examples/full-app-gourmet/go.mod | 28 +++++++----- examples/full-app-gourmet/go.sum | 55 ++++++++++++++-------- examples/generate-opengraph-image/go.mod | 8 ++-- examples/generate-opengraph-image/go.sum | 16 +++---- examples/hello-world/go.mod | 9 ++-- examples/hello-world/go.sum | 20 ++++++-- examples/openapi/go.mod | 9 ++-- examples/openapi/go.sum | 20 ++++++-- extra/markdown/go.mod | 2 +- extra/markdown/go.sum | 15 +++++- go.mod | 6 +-- go.sum | 13 +++--- middleware/basicauth/go.mod | 27 +++++++++-- middleware/basicauth/go.sum | 57 +++++++++++++++++++++++ middleware/cache/go.mod | 23 ++++++++-- middleware/cache/go.sum | 58 ++++++++++++++++++++++++ testing-from-outside/go.sum | 11 +++++ 25 files changed, 355 insertions(+), 137 deletions(-) diff --git a/cmd/fuego/go.mod b/cmd/fuego/go.mod index 21641070..c4e58669 100644 --- a/cmd/fuego/go.mod +++ b/cmd/fuego/go.mod @@ -5,7 +5,7 @@ go 1.22.2 toolchain go1.22.5 require ( - github.com/go-fuego/fuego v0.15.0 + github.com/go-fuego/fuego v0.15.1 github.com/stretchr/testify v1.10.0 github.com/urfave/cli/v2 v2.27.5 golang.org/x/text v0.21.0 @@ -32,8 +32,8 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect - golang.org/x/crypto v0.29.0 // indirect - golang.org/x/net v0.31.0 // indirect - golang.org/x/sys v0.27.0 // indirect + golang.org/x/crypto v0.30.0 // indirect + golang.org/x/net v0.32.0 // indirect + golang.org/x/sys v0.28.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/cmd/fuego/go.sum b/cmd/fuego/go.sum index 7e2a9e75..64ae7d5c 100644 --- a/cmd/fuego/go.sum +++ b/cmd/fuego/go.sum @@ -6,8 +6,8 @@ github.com/gabriel-vasile/mimetype v1.4.7 h1:SKFKl7kD0RiPdbht0s7hFtjl489WcQ1VyPW github.com/gabriel-vasile/mimetype v1.4.7/go.mod h1:GDlAgAyIRT27BhFl53XNAFtfjzOkLaF35JdEG0P7LtU= github.com/getkin/kin-openapi v0.128.0 h1:jqq3D9vC9pPq1dGcOCv7yOp1DaEe7c/T1vzcLbITSp4= github.com/getkin/kin-openapi v0.128.0/go.mod h1:OZrfXzUfGrNbsKj+xmFBx6E5c6yH3At/tAKSc2UszXM= -github.com/go-fuego/fuego v0.15.0 h1:T3DcbOSM9TDUn6ksXk2YH+bs4xDIyP1ObANokhGHLaw= -github.com/go-fuego/fuego v0.15.0/go.mod h1:oZ5g39TgfqG4S1mc2wlRZxl72aRCO26OnJemUIUJGHE= +github.com/go-fuego/fuego v0.15.1 h1:9ESspiRFeUmSl2YdZzL5VE+8F2sGYSTBRkGJEfvoLXc= +github.com/go-fuego/fuego v0.15.1/go.mod h1:XMpAQQnZsoMON0UD6ncvzj6YukGQlNECDcINJt49zx4= github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= @@ -58,13 +58,14 @@ github.com/urfave/cli/v2 v2.27.5 h1:WoHEJLdsXr6dDWoJgMq/CboDmyY/8HMMH1fTECbih+w= github.com/urfave/cli/v2 v2.27.5/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ= github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4= github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM= -golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ= -golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg= -golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo= -golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM= -golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= -golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY= +golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= +golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/examples/acme-tls/go.mod b/examples/acme-tls/go.mod index ff2b9dbf..0766be02 100644 --- a/examples/acme-tls/go.mod +++ b/examples/acme-tls/go.mod @@ -4,7 +4,7 @@ go 1.22.2 require ( github.com/caddyserver/certmagic v0.21.4 - github.com/go-fuego/fuego v0.15.0 + github.com/go-fuego/fuego v0.15.1 ) require ( @@ -28,16 +28,15 @@ require ( github.com/miekg/dns v1.1.62 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect - github.com/stretchr/testify v1.10.0 // indirect github.com/zeebo/blake3 v0.2.4 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect - golang.org/x/crypto v0.29.0 // indirect + golang.org/x/crypto v0.30.0 // indirect golang.org/x/mod v0.22.0 // indirect - golang.org/x/net v0.31.0 // indirect + golang.org/x/net v0.32.0 // indirect golang.org/x/sync v0.10.0 // indirect - golang.org/x/sys v0.27.0 // indirect + golang.org/x/sys v0.28.0 // indirect golang.org/x/text v0.21.0 // indirect - golang.org/x/tools v0.27.0 // indirect + golang.org/x/tools v0.28.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/examples/acme-tls/go.sum b/examples/acme-tls/go.sum index 0fb27ee8..a8f554f3 100644 --- a/examples/acme-tls/go.sum +++ b/examples/acme-tls/go.sum @@ -8,8 +8,8 @@ github.com/gabriel-vasile/mimetype v1.4.7 h1:SKFKl7kD0RiPdbht0s7hFtjl489WcQ1VyPW github.com/gabriel-vasile/mimetype v1.4.7/go.mod h1:GDlAgAyIRT27BhFl53XNAFtfjzOkLaF35JdEG0P7LtU= github.com/getkin/kin-openapi v0.128.0 h1:jqq3D9vC9pPq1dGcOCv7yOp1DaEe7c/T1vzcLbITSp4= github.com/getkin/kin-openapi v0.128.0/go.mod h1:OZrfXzUfGrNbsKj+xmFBx6E5c6yH3At/tAKSc2UszXM= -github.com/go-fuego/fuego v0.15.0 h1:T3DcbOSM9TDUn6ksXk2YH+bs4xDIyP1ObANokhGHLaw= -github.com/go-fuego/fuego v0.15.0/go.mod h1:oZ5g39TgfqG4S1mc2wlRZxl72aRCO26OnJemUIUJGHE= +github.com/go-fuego/fuego v0.15.1 h1:9ESspiRFeUmSl2YdZzL5VE+8F2sGYSTBRkGJEfvoLXc= +github.com/go-fuego/fuego v0.15.1/go.mod h1:XMpAQQnZsoMON0UD6ncvzj6YukGQlNECDcINJt49zx4= github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= @@ -26,6 +26,8 @@ github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/gorilla/schema v1.4.1 h1:jUg5hUjCSDZpNGLuXQOgIWGdlgrIdYvgQ0wZtdK1M3E= github.com/gorilla/schema v1.4.1/go.mod h1:Dg5SSm5PV60mhF2NFaTV1xuYYj8tV8NOPRo4FggUMnM= github.com/invopop/yaml v0.3.1 h1:f0+ZpmhfBSS4MhG+4HYseMdJhoeeopbSKbq5Rpeelso= @@ -57,6 +59,7 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/thejerf/slogassert v0.3.4 h1:VoTsXixRbXMrRSSxDjYTiEDCM4VWbsYPW5rB/hX24kM= github.com/thejerf/slogassert v0.3.4/go.mod h1:0zn9ISLVKo1aPMTqcGfG1o6dWwt+Rk574GlUxHD4rs8= github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= @@ -73,18 +76,20 @@ go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ= -golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg= +golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY= +golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4= golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= -golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo= -golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM= +golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= +golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs= golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= -golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= -golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= -golang.org/x/tools v0.27.0 h1:qEKojBykQkQ4EynWy4S8Weg69NumxKdn40Fce3uc/8o= -golang.org/x/tools v0.27.0/go.mod h1:sUi0ZgbwW9ZPAq26Ekut+weQPR5eIM6GQLQ1Yjm1H0Q= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +golang.org/x/tools v0.28.0 h1:WuB6qZ4RPCQo5aP3WdKZS7i595EdWqWR8vqJTlwTVK8= +golang.org/x/tools v0.28.0/go.mod h1:dcIOrVd3mfQKTgrDVQHqCPMWy6lnhfhtX3hLXYVLfRw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/examples/basic/go.mod b/examples/basic/go.mod index 8a4fa061..d5b869de 100644 --- a/examples/basic/go.mod +++ b/examples/basic/go.mod @@ -4,7 +4,7 @@ go 1.22.2 require ( github.com/go-chi/chi/v5 v5.1.0 - github.com/go-fuego/fuego v0.15.0 + github.com/go-fuego/fuego v0.15.1 github.com/rs/cors v1.11.1 ) @@ -24,10 +24,9 @@ require ( github.com/mailru/easyjson v0.7.7 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect - github.com/stretchr/testify v1.10.0 // indirect - golang.org/x/crypto v0.29.0 // indirect - golang.org/x/net v0.31.0 // indirect - golang.org/x/sys v0.27.0 // indirect + golang.org/x/crypto v0.30.0 // indirect + golang.org/x/net v0.32.0 // indirect + golang.org/x/sys v0.28.0 // indirect golang.org/x/text v0.21.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/examples/basic/go.sum b/examples/basic/go.sum index e6bbcdca..6936a3f1 100644 --- a/examples/basic/go.sum +++ b/examples/basic/go.sum @@ -6,8 +6,8 @@ github.com/getkin/kin-openapi v0.128.0 h1:jqq3D9vC9pPq1dGcOCv7yOp1DaEe7c/T1vzcLb github.com/getkin/kin-openapi v0.128.0/go.mod h1:OZrfXzUfGrNbsKj+xmFBx6E5c6yH3At/tAKSc2UszXM= github.com/go-chi/chi/v5 v5.1.0 h1:acVI1TYaD+hhedDJ3r54HyA6sExp3HfXq7QWEEY/xMw= github.com/go-chi/chi/v5 v5.1.0/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= -github.com/go-fuego/fuego v0.15.0 h1:T3DcbOSM9TDUn6ksXk2YH+bs4xDIyP1ObANokhGHLaw= -github.com/go-fuego/fuego v0.15.0/go.mod h1:oZ5g39TgfqG4S1mc2wlRZxl72aRCO26OnJemUIUJGHE= +github.com/go-fuego/fuego v0.15.1 h1:9ESspiRFeUmSl2YdZzL5VE+8F2sGYSTBRkGJEfvoLXc= +github.com/go-fuego/fuego v0.15.1/go.mod h1:XMpAQQnZsoMON0UD6ncvzj6YukGQlNECDcINJt49zx4= github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= @@ -49,17 +49,19 @@ github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99 github.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA= github.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/thejerf/slogassert v0.3.4 h1:VoTsXixRbXMrRSSxDjYTiEDCM4VWbsYPW5rB/hX24kM= github.com/thejerf/slogassert v0.3.4/go.mod h1:0zn9ISLVKo1aPMTqcGfG1o6dWwt+Rk574GlUxHD4rs8= github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= -golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ= -golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg= -golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo= -golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM= -golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= -golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY= +golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= +golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/examples/custom-serializer/go.mod b/examples/custom-serializer/go.mod index 66c60f7e..4b946860 100644 --- a/examples/custom-serializer/go.mod +++ b/examples/custom-serializer/go.mod @@ -3,7 +3,7 @@ module github.com/go-fuego/fuego/examples/custom-serializer go 1.22.2 require ( - github.com/go-fuego/fuego v0.15.0 + github.com/go-fuego/fuego v0.15.1 github.com/json-iterator/go v1.1.12 ) @@ -25,10 +25,9 @@ require ( github.com/modern-go/reflect2 v1.0.2 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect - github.com/stretchr/testify v1.10.0 // indirect - golang.org/x/crypto v0.29.0 // indirect - golang.org/x/net v0.31.0 // indirect - golang.org/x/sys v0.27.0 // indirect + golang.org/x/crypto v0.30.0 // indirect + golang.org/x/net v0.32.0 // indirect + golang.org/x/sys v0.28.0 // indirect golang.org/x/text v0.21.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/examples/custom-serializer/go.sum b/examples/custom-serializer/go.sum index 564728b6..0cc71adc 100644 --- a/examples/custom-serializer/go.sum +++ b/examples/custom-serializer/go.sum @@ -5,8 +5,8 @@ github.com/gabriel-vasile/mimetype v1.4.7 h1:SKFKl7kD0RiPdbht0s7hFtjl489WcQ1VyPW github.com/gabriel-vasile/mimetype v1.4.7/go.mod h1:GDlAgAyIRT27BhFl53XNAFtfjzOkLaF35JdEG0P7LtU= github.com/getkin/kin-openapi v0.128.0 h1:jqq3D9vC9pPq1dGcOCv7yOp1DaEe7c/T1vzcLbITSp4= github.com/getkin/kin-openapi v0.128.0/go.mod h1:OZrfXzUfGrNbsKj+xmFBx6E5c6yH3At/tAKSc2UszXM= -github.com/go-fuego/fuego v0.15.0 h1:T3DcbOSM9TDUn6ksXk2YH+bs4xDIyP1ObANokhGHLaw= -github.com/go-fuego/fuego v0.15.0/go.mod h1:oZ5g39TgfqG4S1mc2wlRZxl72aRCO26OnJemUIUJGHE= +github.com/go-fuego/fuego v0.15.1 h1:9ESspiRFeUmSl2YdZzL5VE+8F2sGYSTBRkGJEfvoLXc= +github.com/go-fuego/fuego v0.15.1/go.mod h1:XMpAQQnZsoMON0UD6ncvzj6YukGQlNECDcINJt49zx4= github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= @@ -56,17 +56,19 @@ github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/thejerf/slogassert v0.3.4 h1:VoTsXixRbXMrRSSxDjYTiEDCM4VWbsYPW5rB/hX24kM= github.com/thejerf/slogassert v0.3.4/go.mod h1:0zn9ISLVKo1aPMTqcGfG1o6dWwt+Rk574GlUxHD4rs8= github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= -golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ= -golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg= -golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo= -golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM= -golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= -golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY= +golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= +golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/examples/full-app-gourmet/go.mod b/examples/full-app-gourmet/go.mod index 8b78986b..5f021cae 100644 --- a/examples/full-app-gourmet/go.mod +++ b/examples/full-app-gourmet/go.mod @@ -1,12 +1,16 @@ module github.com/go-fuego/fuego/examples/full-app-gourmet -go 1.22.5 +go 1.22.6 + +toolchain go1.23.3 require ( - github.com/a-h/templ v0.2.778 + github.com/a-h/templ v0.2.793 github.com/go-chi/chi/v5 v5.1.0 - github.com/go-fuego/fuego v0.14.0 - github.com/go-fuego/fuego/extra/markdown v0.0.0-20240904160725-38b88648e0d4 + github.com/go-fuego/fuego v0.15.1 + github.com/go-fuego/fuego/extra/markdown v0.0.0-20241206012402-4c4bc8bfe6ef + github.com/go-fuego/fuego/middleware/basicauth v0.15.1 + github.com/go-fuego/fuego/middleware/cache v0.0.0-20241206012402-4c4bc8bfe6ef github.com/golang-jwt/jwt/v5 v5.2.1 github.com/golang-migrate/migrate/v4 v4.18.1 github.com/google/uuid v1.6.0 @@ -15,7 +19,7 @@ require ( github.com/rs/cors v1.11.1 github.com/stretchr/testify v1.10.0 golang.org/x/text v0.21.0 - modernc.org/sqlite v1.33.1 + modernc.org/sqlite v1.34.2 ) require ( @@ -28,7 +32,7 @@ require ( github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/validator/v10 v10.23.0 // indirect - github.com/gomarkdown/markdown v0.0.0-20240730141124-034f12af3bf6 // indirect + github.com/gomarkdown/markdown v0.0.0-20241205020045-f7e15b2f3e62 // indirect github.com/gorilla/schema v1.4.1 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect @@ -44,13 +48,13 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect go.uber.org/atomic v1.11.0 // indirect - golang.org/x/crypto v0.29.0 // indirect - golang.org/x/net v0.31.0 // indirect - golang.org/x/sys v0.27.0 // indirect - golang.org/x/tools v0.27.0 // indirect + golang.org/x/crypto v0.30.0 // indirect + golang.org/x/exp v0.0.0-20241204233417-43b7b7cde48d // indirect + golang.org/x/net v0.32.0 // indirect + golang.org/x/sys v0.28.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - modernc.org/gc/v3 v3.0.0-20240801135723-a856999a2e4a // indirect - modernc.org/libc v1.55.3 // indirect + modernc.org/gc/v3 v3.0.0-20241004144649-1aea3fae8852 // indirect + modernc.org/libc v1.61.4 // indirect modernc.org/mathutil v1.6.0 // indirect modernc.org/memory v1.8.0 // indirect modernc.org/strutil v1.2.0 // indirect diff --git a/examples/full-app-gourmet/go.sum b/examples/full-app-gourmet/go.sum index 5cdb2fe6..f25602eb 100644 --- a/examples/full-app-gourmet/go.sum +++ b/examples/full-app-gourmet/go.sum @@ -1,13 +1,17 @@ -github.com/a-h/templ v0.2.778 h1:VzhOuvWECrwOec4790lcLlZpP4Iptt5Q4K9aFxQmtaM= -github.com/a-h/templ v0.2.778/go.mod h1:lq48JXoUvuQrU0VThrK31yFwdRjTCnIE5bcPCM9IP1w= +github.com/a-h/templ v0.2.793 h1:Io+/ocnfGWYO4VHdR0zBbf39PQlnzVCVVD+wEEs6/qY= +github.com/a-h/templ v0.2.793/go.mod h1:lq48JXoUvuQrU0VThrK31yFwdRjTCnIE5bcPCM9IP1w= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/gabriel-vasile/mimetype v1.4.7 h1:SKFKl7kD0RiPdbht0s7hFtjl489WcQ1VyPW8ZzUMYCA= +github.com/gabriel-vasile/mimetype v1.4.7/go.mod h1:GDlAgAyIRT27BhFl53XNAFtfjzOkLaF35JdEG0P7LtU= github.com/getkin/kin-openapi v0.128.0 h1:jqq3D9vC9pPq1dGcOCv7yOp1DaEe7c/T1vzcLbITSp4= +github.com/getkin/kin-openapi v0.128.0/go.mod h1:OZrfXzUfGrNbsKj+xmFBx6E5c6yH3At/tAKSc2UszXM= github.com/go-chi/chi/v5 v5.1.0 h1:acVI1TYaD+hhedDJ3r54HyA6sExp3HfXq7QWEEY/xMw= github.com/go-chi/chi/v5 v5.1.0/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= +github.com/go-fuego/fuego/middleware/basicauth v0.15.1 h1:8VelgvZjvm0pg6X29qCFDPVzSqCFdv5ppRDy7hWAykc= +github.com/go-fuego/fuego/middleware/basicauth v0.15.1/go.mod h1:W2UY/grQlayDI3bJ1TpWhekeQXgSqIT1V3cu0pbvUYM= github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= @@ -19,14 +23,15 @@ github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/Nu github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= github.com/go-playground/validator/v10 v10.23.0 h1:/PwmTwZhS0dPkav3cdK9kV1FsAmrL8sThn8IHr/sO+o= +github.com/go-playground/validator/v10 v10.23.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= github.com/golang-migrate/migrate/v4 v4.18.1 h1:JML/k+t4tpHCpQTCAD62Nu43NUFzHY4CV3uAuvHGC+Y= github.com/golang-migrate/migrate/v4 v4.18.1/go.mod h1:HAX6m3sQgcdO81tdjn5exv20+3Kb13cmGli1hrD6hks= -github.com/gomarkdown/markdown v0.0.0-20240730141124-034f12af3bf6 h1:ZPy+2XJ8u0bB3sNFi+I72gMEMS7MTg7aZCCXPOjV8iw= -github.com/gomarkdown/markdown v0.0.0-20240730141124-034f12af3bf6/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA= +github.com/gomarkdown/markdown v0.0.0-20241205020045-f7e15b2f3e62 h1:pbAFUZisjG4s6sxvRJvf2N7vhpCvx2Oxb3PmS6pDO1g= +github.com/gomarkdown/markdown v0.0.0-20241205020045-f7e15b2f3e62/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd h1:gbpYu9NMq8jhDVbvlGkMFWCjLFlqqEZjEmObmhUy6Vo= @@ -77,37 +82,47 @@ github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99 github.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA= github.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/thejerf/slogassert v0.3.4 h1:VoTsXixRbXMrRSSxDjYTiEDCM4VWbsYPW5rB/hX24kM= github.com/thejerf/slogassert v0.3.4/go.mod h1:0zn9ISLVKo1aPMTqcGfG1o6dWwt+Rk574GlUxHD4rs8= github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ= +golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY= +golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/exp v0.0.0-20241204233417-43b7b7cde48d h1:0olWaB5pg3+oychR51GUVCEsGkeCU/2JxjBgIo4f3M0= +golang.org/x/exp v0.0.0-20241204233417-43b7b7cde48d/go.mod h1:qj5a5QZpwLU2NLQudwIN5koi3beDhSAlJwa67PuM98c= golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4= -golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo= +golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= +golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= +golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs= golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= -golang.org/x/tools v0.27.0 h1:qEKojBykQkQ4EynWy4S8Weg69NumxKdn40Fce3uc/8o= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +golang.org/x/tools v0.28.0 h1:WuB6qZ4RPCQo5aP3WdKZS7i595EdWqWR8vqJTlwTVK8= +golang.org/x/tools v0.28.0/go.mod h1:dcIOrVd3mfQKTgrDVQHqCPMWy6lnhfhtX3hLXYVLfRw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -modernc.org/cc/v4 v4.21.4 h1:3Be/Rdo1fpr8GrQ7IVw9OHtplU4gWbb+wNgeoBMmGLQ= -modernc.org/cc/v4 v4.21.4/go.mod h1:HM7VJTZbUCR3rV8EYBi9wxnJ0ZBRiGE5OeGXNA0IsLQ= -modernc.org/ccgo/v4 v4.19.2 h1:lwQZgvboKD0jBwdaeVCTouxhxAyN6iawF3STraAal8Y= -modernc.org/ccgo/v4 v4.19.2/go.mod h1:ysS3mxiMV38XGRTTcgo0DQTeTmAO4oCmJl1nX9VFI3s= +modernc.org/cc/v4 v4.23.1 h1:WqJoPL3x4cUufQVHkXpXX7ThFJ1C4ik80i2eXEXbhD8= +modernc.org/cc/v4 v4.23.1/go.mod h1:HM7VJTZbUCR3rV8EYBi9wxnJ0ZBRiGE5OeGXNA0IsLQ= +modernc.org/ccgo/v4 v4.23.1 h1:N49a7JiWGWV7lkPE4yYcvjkBGZQi93/JabRYjdWmJXc= +modernc.org/ccgo/v4 v4.23.1/go.mod h1:JoIUegEIfutvoWV/BBfDFpPpfR2nc3U0jKucGcbmwDU= modernc.org/fileutil v1.3.0 h1:gQ5SIzK3H9kdfai/5x41oQiKValumqNTDXMvKo62HvE= modernc.org/fileutil v1.3.0/go.mod h1:XatxS8fZi3pS8/hKG2GH/ArUogfxjpEKs3Ku3aK4JyQ= -modernc.org/gc/v2 v2.4.1 h1:9cNzOqPyMJBvrUipmynX0ZohMhcxPtMccYgGOJdOiBw= -modernc.org/gc/v2 v2.4.1/go.mod h1:wzN5dK1AzVGoH6XOzc3YZ+ey/jPgYHLuVckd62P0GYU= -modernc.org/gc/v3 v3.0.0-20240801135723-a856999a2e4a h1:CfbpOLEo2IwNzJdMvE8aiRbPMxoTpgAJeyePh0SmO8M= -modernc.org/gc/v3 v3.0.0-20240801135723-a856999a2e4a/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4= -modernc.org/libc v1.55.3 h1:AzcW1mhlPNrRtjS5sS+eW2ISCgSOLLNyFzRh/V3Qj/U= -modernc.org/libc v1.55.3/go.mod h1:qFXepLhz+JjFThQ4kzwzOjA/y/artDeg+pcYnY+Q83w= +modernc.org/gc/v2 v2.5.0 h1:bJ9ChznK1L1mUtAQtxi0wi5AtAs5jQuw4PrPHO5pb6M= +modernc.org/gc/v2 v2.5.0/go.mod h1:wzN5dK1AzVGoH6XOzc3YZ+ey/jPgYHLuVckd62P0GYU= +modernc.org/gc/v3 v3.0.0-20241004144649-1aea3fae8852 h1:IYXPPTTjjoSHvUClZIYexDiO7g+4x+XveKT4gCIAwiY= +modernc.org/gc/v3 v3.0.0-20241004144649-1aea3fae8852/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4= +modernc.org/libc v1.61.4 h1:wVyqEx6tlltte9lPTjq0kDAdtdM9c4JH8rU6M1ZVawA= +modernc.org/libc v1.61.4/go.mod h1:VfXVuM/Shh5XsMNrh3C6OkfL78G3loa4ZC/Ljv9k7xc= modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= @@ -116,8 +131,8 @@ modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4= modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= modernc.org/sortutil v1.2.0 h1:jQiD3PfS2REGJNzNCMMaLSp/wdMNieTbKX920Cqdgqc= modernc.org/sortutil v1.2.0/go.mod h1:TKU2s7kJMf1AE84OoiGppNHJwvB753OYfNl2WRb++Ss= -modernc.org/sqlite v1.33.1 h1:trb6Z3YYoeM9eDL1O8do81kP+0ejv+YzgyFo+Gwy0nM= -modernc.org/sqlite v1.33.1/go.mod h1:pXV2xHxhzXZsgT/RtTFAPY6JJDEvOTcTdwADQCCWD4k= +modernc.org/sqlite v1.34.2 h1:J9n76TPsfYYkFkZ9Uy1QphILYifiVEwwOT7yP5b++2Y= +modernc.org/sqlite v1.34.2/go.mod h1:dnR723UrTtjKpoHCAMN0Q/gZ9MT4r+iRvIBb9umWFkU= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= diff --git a/examples/generate-opengraph-image/go.mod b/examples/generate-opengraph-image/go.mod index bab3fcd4..20b8099c 100644 --- a/examples/generate-opengraph-image/go.mod +++ b/examples/generate-opengraph-image/go.mod @@ -5,7 +5,7 @@ go 1.23.3 require ( github.com/getkin/kin-openapi v0.128.0 github.com/go-fuego/fuego v0.15.1 - github.com/go-fuego/fuego/middleware/cache v0.0.0-20241205062647-57f1083dfa29 + github.com/go-fuego/fuego/middleware/cache v0.0.0-20241206012402-4c4bc8bfe6ef github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 golang.org/x/image v0.23.0 ) @@ -26,9 +26,9 @@ require ( github.com/mailru/easyjson v0.7.7 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect - golang.org/x/crypto v0.29.0 // indirect - golang.org/x/net v0.31.0 // indirect - golang.org/x/sys v0.27.0 // indirect + golang.org/x/crypto v0.30.0 // indirect + golang.org/x/net v0.32.0 // indirect + golang.org/x/sys v0.28.0 // indirect golang.org/x/text v0.21.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/examples/generate-opengraph-image/go.sum b/examples/generate-opengraph-image/go.sum index e03858ce..35251208 100644 --- a/examples/generate-opengraph-image/go.sum +++ b/examples/generate-opengraph-image/go.sum @@ -6,8 +6,8 @@ github.com/getkin/kin-openapi v0.128.0 h1:jqq3D9vC9pPq1dGcOCv7yOp1DaEe7c/T1vzcLb github.com/getkin/kin-openapi v0.128.0/go.mod h1:OZrfXzUfGrNbsKj+xmFBx6E5c6yH3At/tAKSc2UszXM= github.com/go-fuego/fuego v0.15.1 h1:9ESspiRFeUmSl2YdZzL5VE+8F2sGYSTBRkGJEfvoLXc= github.com/go-fuego/fuego v0.15.1/go.mod h1:XMpAQQnZsoMON0UD6ncvzj6YukGQlNECDcINJt49zx4= -github.com/go-fuego/fuego/middleware/cache v0.0.0-20241205062647-57f1083dfa29 h1:lmWNDJcmLtrtVIyohuhMAQc7Xhn30CB2EZB10gkLH6w= -github.com/go-fuego/fuego/middleware/cache v0.0.0-20241205062647-57f1083dfa29/go.mod h1:OOX9YhxWG5dOkldwf+zzeBK/ef3uDPXZPSuZwA1w4Qg= +github.com/go-fuego/fuego/middleware/cache v0.0.0-20241206012402-4c4bc8bfe6ef h1:hnjtw+FC2yykYN0lat+Ato7080yuNDl9ZAsSt7JCsfQ= +github.com/go-fuego/fuego/middleware/cache v0.0.0-20241206012402-4c4bc8bfe6ef/go.mod h1:OOX9YhxWG5dOkldwf+zzeBK/ef3uDPXZPSuZwA1w4Qg= github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= @@ -56,14 +56,14 @@ github.com/thejerf/slogassert v0.3.4 h1:VoTsXixRbXMrRSSxDjYTiEDCM4VWbsYPW5rB/hX2 github.com/thejerf/slogassert v0.3.4/go.mod h1:0zn9ISLVKo1aPMTqcGfG1o6dWwt+Rk574GlUxHD4rs8= github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= -golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ= -golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg= +golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY= +golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/image v0.23.0 h1:HseQ7c2OpPKTPVzNjG5fwJsOTCiiwS4QdsYi5XU6H68= golang.org/x/image v0.23.0/go.mod h1:wJJBTdLfCCf3tiHa1fNxpZmUI4mmoZvwMCPP0ddoNKY= -golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo= -golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM= -golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= -golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= +golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/examples/hello-world/go.mod b/examples/hello-world/go.mod index eb88cf4e..2f1cde62 100644 --- a/examples/hello-world/go.mod +++ b/examples/hello-world/go.mod @@ -2,7 +2,7 @@ module github.com/go-fuego/fuego/examples/hello-world go 1.22.2 -require github.com/go-fuego/fuego v0.14.0 +require github.com/go-fuego/fuego v0.15.1 require ( github.com/gabriel-vasile/mimetype v1.4.7 // indirect @@ -20,10 +20,9 @@ require ( github.com/mailru/easyjson v0.7.7 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect - github.com/stretchr/testify v1.10.0 // indirect - golang.org/x/crypto v0.29.0 // indirect - golang.org/x/net v0.31.0 // indirect - golang.org/x/sys v0.27.0 // indirect + golang.org/x/crypto v0.30.0 // indirect + golang.org/x/net v0.32.0 // indirect + golang.org/x/sys v0.28.0 // indirect golang.org/x/text v0.21.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/examples/hello-world/go.sum b/examples/hello-world/go.sum index 36ba2f6f..c54bcf23 100644 --- a/examples/hello-world/go.sum +++ b/examples/hello-world/go.sum @@ -1,9 +1,11 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/gabriel-vasile/mimetype v1.4.7 h1:SKFKl7kD0RiPdbht0s7hFtjl489WcQ1VyPW8ZzUMYCA= +github.com/gabriel-vasile/mimetype v1.4.7/go.mod h1:GDlAgAyIRT27BhFl53XNAFtfjzOkLaF35JdEG0P7LtU= github.com/getkin/kin-openapi v0.128.0 h1:jqq3D9vC9pPq1dGcOCv7yOp1DaEe7c/T1vzcLbITSp4= -github.com/go-fuego/fuego v0.14.0 h1:jYrfTXSAiWxYcqJUpFVUjH4EZ5ZBcy8piszeRlky7ZU= -github.com/go-fuego/fuego v0.14.0/go.mod h1:T+e74Ln/DR8XRCQ421seu8QvmogpRpR/0D3dYxcEq6U= +github.com/getkin/kin-openapi v0.128.0/go.mod h1:OZrfXzUfGrNbsKj+xmFBx6E5c6yH3At/tAKSc2UszXM= +github.com/go-fuego/fuego v0.15.1 h1:9ESspiRFeUmSl2YdZzL5VE+8F2sGYSTBRkGJEfvoLXc= +github.com/go-fuego/fuego v0.15.1/go.mod h1:XMpAQQnZsoMON0UD6ncvzj6YukGQlNECDcINJt49zx4= github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= @@ -15,6 +17,7 @@ github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/Nu github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= github.com/go-playground/validator/v10 v10.23.0 h1:/PwmTwZhS0dPkav3cdK9kV1FsAmrL8sThn8IHr/sO+o= +github.com/go-playground/validator/v10 v10.23.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= @@ -42,12 +45,19 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/thejerf/slogassert v0.3.4 h1:VoTsXixRbXMrRSSxDjYTiEDCM4VWbsYPW5rB/hX24kM= +github.com/thejerf/slogassert v0.3.4/go.mod h1:0zn9ISLVKo1aPMTqcGfG1o6dWwt+Rk574GlUxHD4rs8= github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= -golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ= -golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo= -golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= +golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY= +golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= +golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/examples/openapi/go.mod b/examples/openapi/go.mod index f4f5dc01..0d87d966 100644 --- a/examples/openapi/go.mod +++ b/examples/openapi/go.mod @@ -2,7 +2,7 @@ module github.com/go-fuego/fuego/examples/openapi go 1.22.2 -require github.com/go-fuego/fuego v0.14.0 +require github.com/go-fuego/fuego v0.15.1 require ( github.com/gabriel-vasile/mimetype v1.4.7 // indirect @@ -20,10 +20,9 @@ require ( github.com/mailru/easyjson v0.7.7 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect - github.com/stretchr/testify v1.10.0 // indirect - golang.org/x/crypto v0.29.0 // indirect - golang.org/x/net v0.31.0 // indirect - golang.org/x/sys v0.27.0 // indirect + golang.org/x/crypto v0.30.0 // indirect + golang.org/x/net v0.32.0 // indirect + golang.org/x/sys v0.28.0 // indirect golang.org/x/text v0.21.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/examples/openapi/go.sum b/examples/openapi/go.sum index 36ba2f6f..c54bcf23 100644 --- a/examples/openapi/go.sum +++ b/examples/openapi/go.sum @@ -1,9 +1,11 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/gabriel-vasile/mimetype v1.4.7 h1:SKFKl7kD0RiPdbht0s7hFtjl489WcQ1VyPW8ZzUMYCA= +github.com/gabriel-vasile/mimetype v1.4.7/go.mod h1:GDlAgAyIRT27BhFl53XNAFtfjzOkLaF35JdEG0P7LtU= github.com/getkin/kin-openapi v0.128.0 h1:jqq3D9vC9pPq1dGcOCv7yOp1DaEe7c/T1vzcLbITSp4= -github.com/go-fuego/fuego v0.14.0 h1:jYrfTXSAiWxYcqJUpFVUjH4EZ5ZBcy8piszeRlky7ZU= -github.com/go-fuego/fuego v0.14.0/go.mod h1:T+e74Ln/DR8XRCQ421seu8QvmogpRpR/0D3dYxcEq6U= +github.com/getkin/kin-openapi v0.128.0/go.mod h1:OZrfXzUfGrNbsKj+xmFBx6E5c6yH3At/tAKSc2UszXM= +github.com/go-fuego/fuego v0.15.1 h1:9ESspiRFeUmSl2YdZzL5VE+8F2sGYSTBRkGJEfvoLXc= +github.com/go-fuego/fuego v0.15.1/go.mod h1:XMpAQQnZsoMON0UD6ncvzj6YukGQlNECDcINJt49zx4= github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= @@ -15,6 +17,7 @@ github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/Nu github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= github.com/go-playground/validator/v10 v10.23.0 h1:/PwmTwZhS0dPkav3cdK9kV1FsAmrL8sThn8IHr/sO+o= +github.com/go-playground/validator/v10 v10.23.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= @@ -42,12 +45,19 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/thejerf/slogassert v0.3.4 h1:VoTsXixRbXMrRSSxDjYTiEDCM4VWbsYPW5rB/hX24kM= +github.com/thejerf/slogassert v0.3.4/go.mod h1:0zn9ISLVKo1aPMTqcGfG1o6dWwt+Rk574GlUxHD4rs8= github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= -golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ= -golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo= -golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= +golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY= +golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= +golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/extra/markdown/go.mod b/extra/markdown/go.mod index cdae406e..48d17f83 100644 --- a/extra/markdown/go.mod +++ b/extra/markdown/go.mod @@ -3,7 +3,7 @@ module github.com/go-fuego/fuego/extra/markdown go 1.22.5 require ( - github.com/gomarkdown/markdown v0.0.0-20240730141124-034f12af3bf6 + github.com/gomarkdown/markdown v0.0.0-20241205020045-f7e15b2f3e62 github.com/stretchr/testify v1.10.0 ) diff --git a/extra/markdown/go.sum b/extra/markdown/go.sum index d8dfd821..30b2e919 100644 --- a/extra/markdown/go.sum +++ b/extra/markdown/go.sum @@ -1,14 +1,25 @@ +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/gomarkdown/markdown v0.0.0-20240730141124-034f12af3bf6 h1:ZPy+2XJ8u0bB3sNFi+I72gMEMS7MTg7aZCCXPOjV8iw= -github.com/gomarkdown/markdown v0.0.0-20240730141124-034f12af3bf6/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA= +github.com/gomarkdown/markdown v0.0.0-20241205020045-f7e15b2f3e62 h1:pbAFUZisjG4s6sxvRJvf2N7vhpCvx2Oxb3PmS6pDO1g= +github.com/gomarkdown/markdown v0.0.0-20241205020045-f7e15b2f3e62/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/go.mod b/go.mod index 7c8430e9..7a0e8573 100644 --- a/go.mod +++ b/go.mod @@ -28,8 +28,8 @@ require ( github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - golang.org/x/crypto v0.29.0 // indirect - golang.org/x/net v0.31.0 // indirect - golang.org/x/sys v0.27.0 // indirect + golang.org/x/crypto v0.30.0 // indirect + golang.org/x/net v0.32.0 // indirect + golang.org/x/sys v0.28.0 // indirect golang.org/x/text v0.21.0 // indirect ) diff --git a/go.sum b/go.sum index cb6f4743..0d6b0cf2 100644 --- a/go.sum +++ b/go.sum @@ -50,13 +50,14 @@ github.com/thejerf/slogassert v0.3.4 h1:VoTsXixRbXMrRSSxDjYTiEDCM4VWbsYPW5rB/hX2 github.com/thejerf/slogassert v0.3.4/go.mod h1:0zn9ISLVKo1aPMTqcGfG1o6dWwt+Rk574GlUxHD4rs8= github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= -golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ= -golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg= -golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo= -golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM= -golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= -golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY= +golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= +golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/middleware/basicauth/go.mod b/middleware/basicauth/go.mod index 9b061813..7fea7139 100644 --- a/middleware/basicauth/go.mod +++ b/middleware/basicauth/go.mod @@ -2,13 +2,32 @@ module github.com/go-fuego/fuego/middleware/basicauth go 1.22.6 -require github.com/stretchr/testify v1.10.0 +require ( + github.com/go-fuego/fuego v0.15.1 + github.com/stretchr/testify v1.10.0 +) require ( github.com/davecgh/go-spew v1.1.1 // indirect - github.com/kr/pretty v0.3.1 // indirect + github.com/gabriel-vasile/mimetype v1.4.7 // indirect + github.com/getkin/kin-openapi v0.128.0 // indirect + github.com/go-openapi/jsonpointer v0.21.0 // indirect + github.com/go-openapi/swag v0.23.0 // indirect + github.com/go-playground/locales v0.14.1 // indirect + github.com/go-playground/universal-translator v0.18.1 // indirect + github.com/go-playground/validator/v10 v10.23.0 // indirect + github.com/golang-jwt/jwt/v5 v5.2.1 // indirect + github.com/gorilla/schema v1.4.1 // indirect + github.com/invopop/yaml v0.3.1 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/leodido/go-urn v1.4.0 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect + github.com/perimeterx/marshmallow v1.1.5 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/rogpeppe/go-internal v1.12.0 // indirect - gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect + golang.org/x/crypto v0.30.0 // indirect + golang.org/x/net v0.32.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/text v0.21.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/middleware/basicauth/go.sum b/middleware/basicauth/go.sum index e90f0a29..c54bcf23 100644 --- a/middleware/basicauth/go.sum +++ b/middleware/basicauth/go.sum @@ -1,8 +1,65 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/gabriel-vasile/mimetype v1.4.7 h1:SKFKl7kD0RiPdbht0s7hFtjl489WcQ1VyPW8ZzUMYCA= +github.com/gabriel-vasile/mimetype v1.4.7/go.mod h1:GDlAgAyIRT27BhFl53XNAFtfjzOkLaF35JdEG0P7LtU= +github.com/getkin/kin-openapi v0.128.0 h1:jqq3D9vC9pPq1dGcOCv7yOp1DaEe7c/T1vzcLbITSp4= +github.com/getkin/kin-openapi v0.128.0/go.mod h1:OZrfXzUfGrNbsKj+xmFBx6E5c6yH3At/tAKSc2UszXM= +github.com/go-fuego/fuego v0.15.1 h1:9ESspiRFeUmSl2YdZzL5VE+8F2sGYSTBRkGJEfvoLXc= +github.com/go-fuego/fuego v0.15.1/go.mod h1:XMpAQQnZsoMON0UD6ncvzj6YukGQlNECDcINJt49zx4= +github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= +github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= +github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= +github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= +github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= +github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= +github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= +github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= +github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= +github.com/go-playground/validator/v10 v10.23.0 h1:/PwmTwZhS0dPkav3cdK9kV1FsAmrL8sThn8IHr/sO+o= +github.com/go-playground/validator/v10 v10.23.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= +github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= +github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= +github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= +github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= +github.com/gorilla/schema v1.4.1 h1:jUg5hUjCSDZpNGLuXQOgIWGdlgrIdYvgQ0wZtdK1M3E= +github.com/gorilla/schema v1.4.1/go.mod h1:Dg5SSm5PV60mhF2NFaTV1xuYYj8tV8NOPRo4FggUMnM= +github.com/invopop/yaml v0.3.1 h1:f0+ZpmhfBSS4MhG+4HYseMdJhoeeopbSKbq5Rpeelso= +github.com/invopop/yaml v0.3.1/go.mod h1:PMOp3nn4/12yEZUFfmOuNHJsZToEEOwoWsT+D81KkeA= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= +github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= +github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= +github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/thejerf/slogassert v0.3.4 h1:VoTsXixRbXMrRSSxDjYTiEDCM4VWbsYPW5rB/hX24kM= +github.com/thejerf/slogassert v0.3.4/go.mod h1:0zn9ISLVKo1aPMTqcGfG1o6dWwt+Rk574GlUxHD4rs8= +github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= +github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= +golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY= +golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= +golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/middleware/cache/go.mod b/middleware/cache/go.mod index 0d1163ea..4324829b 100644 --- a/middleware/cache/go.mod +++ b/middleware/cache/go.mod @@ -3,15 +3,32 @@ module github.com/go-fuego/fuego/middleware/cache go 1.22.6 require ( + github.com/go-fuego/fuego v0.15.1 github.com/hashicorp/golang-lru/v2 v2.0.7 github.com/stretchr/testify v1.10.0 ) require ( github.com/davecgh/go-spew v1.1.1 // indirect - github.com/kr/pretty v0.3.1 // indirect + github.com/gabriel-vasile/mimetype v1.4.7 // indirect + github.com/getkin/kin-openapi v0.128.0 // indirect + github.com/go-openapi/jsonpointer v0.21.0 // indirect + github.com/go-openapi/swag v0.23.0 // indirect + github.com/go-playground/locales v0.14.1 // indirect + github.com/go-playground/universal-translator v0.18.1 // indirect + github.com/go-playground/validator/v10 v10.23.0 // indirect + github.com/golang-jwt/jwt/v5 v5.2.1 // indirect + github.com/gorilla/schema v1.4.1 // indirect + github.com/invopop/yaml v0.3.1 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/leodido/go-urn v1.4.0 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect + github.com/perimeterx/marshmallow v1.1.5 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/rogpeppe/go-internal v1.12.0 // indirect - gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect + golang.org/x/crypto v0.29.0 // indirect + golang.org/x/net v0.31.0 // indirect + golang.org/x/sys v0.27.0 // indirect + golang.org/x/text v0.20.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/middleware/cache/go.sum b/middleware/cache/go.sum index 8d6fb7ac..455cd44a 100644 --- a/middleware/cache/go.sum +++ b/middleware/cache/go.sum @@ -1,9 +1,67 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/gabriel-vasile/mimetype v1.4.7 h1:SKFKl7kD0RiPdbht0s7hFtjl489WcQ1VyPW8ZzUMYCA= +github.com/gabriel-vasile/mimetype v1.4.7/go.mod h1:GDlAgAyIRT27BhFl53XNAFtfjzOkLaF35JdEG0P7LtU= +github.com/getkin/kin-openapi v0.128.0 h1:jqq3D9vC9pPq1dGcOCv7yOp1DaEe7c/T1vzcLbITSp4= +github.com/getkin/kin-openapi v0.128.0/go.mod h1:OZrfXzUfGrNbsKj+xmFBx6E5c6yH3At/tAKSc2UszXM= +github.com/go-fuego/fuego v0.15.1 h1:9ESspiRFeUmSl2YdZzL5VE+8F2sGYSTBRkGJEfvoLXc= +github.com/go-fuego/fuego v0.15.1/go.mod h1:XMpAQQnZsoMON0UD6ncvzj6YukGQlNECDcINJt49zx4= +github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= +github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= +github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= +github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= +github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= +github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= +github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= +github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= +github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= +github.com/go-playground/validator/v10 v10.23.0 h1:/PwmTwZhS0dPkav3cdK9kV1FsAmrL8sThn8IHr/sO+o= +github.com/go-playground/validator/v10 v10.23.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= +github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= +github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= +github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= +github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= +github.com/gorilla/schema v1.4.1 h1:jUg5hUjCSDZpNGLuXQOgIWGdlgrIdYvgQ0wZtdK1M3E= +github.com/gorilla/schema v1.4.1/go.mod h1:Dg5SSm5PV60mhF2NFaTV1xuYYj8tV8NOPRo4FggUMnM= github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= +github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= +github.com/invopop/yaml v0.3.1 h1:f0+ZpmhfBSS4MhG+4HYseMdJhoeeopbSKbq5Rpeelso= +github.com/invopop/yaml v0.3.1/go.mod h1:PMOp3nn4/12yEZUFfmOuNHJsZToEEOwoWsT+D81KkeA= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= +github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= +github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= +github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/thejerf/slogassert v0.3.4 h1:VoTsXixRbXMrRSSxDjYTiEDCM4VWbsYPW5rB/hX24kM= +github.com/thejerf/slogassert v0.3.4/go.mod h1:0zn9ISLVKo1aPMTqcGfG1o6dWwt+Rk574GlUxHD4rs8= +github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= +github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= +golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ= +golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg= +golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo= +golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM= +golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= +golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug= +golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/testing-from-outside/go.sum b/testing-from-outside/go.sum index 6905c5cf..0d195b30 100644 --- a/testing-from-outside/go.sum +++ b/testing-from-outside/go.sum @@ -1,7 +1,9 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/gabriel-vasile/mimetype v1.4.7 h1:SKFKl7kD0RiPdbht0s7hFtjl489WcQ1VyPW8ZzUMYCA= +github.com/gabriel-vasile/mimetype v1.4.7/go.mod h1:GDlAgAyIRT27BhFl53XNAFtfjzOkLaF35JdEG0P7LtU= github.com/getkin/kin-openapi v0.128.0 h1:jqq3D9vC9pPq1dGcOCv7yOp1DaEe7c/T1vzcLbITSp4= +github.com/getkin/kin-openapi v0.128.0/go.mod h1:OZrfXzUfGrNbsKj+xmFBx6E5c6yH3At/tAKSc2UszXM= github.com/go-fuego/fuego v0.13.4 h1:tIDUH9ZKd8UTftkjtFnKhSYPo41NLhH1GxLsHBPZxII= github.com/go-fuego/fuego v0.13.4/go.mod h1:Haw/N+HVuU0mMTjgpPXOWsQ8DsvBJDWSiJCblEh/7P4= github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= @@ -15,6 +17,7 @@ github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/Nu github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= github.com/go-playground/validator/v10 v10.23.0 h1:/PwmTwZhS0dPkav3cdK9kV1FsAmrL8sThn8IHr/sO+o= +github.com/go-playground/validator/v10 v10.23.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= @@ -22,7 +25,9 @@ github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVI github.com/gomarkdown/markdown v0.0.0-20231222211730-1d6d20845b47 h1:k4Tw0nt6lwro3Uin8eqoET7MDA4JnT8YgbCjc/g5E3k= github.com/gomarkdown/markdown v0.0.0-20231222211730-1d6d20845b47/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA= github.com/gorilla/schema v1.4.1 h1:jUg5hUjCSDZpNGLuXQOgIWGdlgrIdYvgQ0wZtdK1M3E= +github.com/gorilla/schema v1.4.1/go.mod h1:Dg5SSm5PV60mhF2NFaTV1xuYYj8tV8NOPRo4FggUMnM= github.com/invopop/yaml v0.3.1 h1:f0+ZpmhfBSS4MhG+4HYseMdJhoeeopbSKbq5Rpeelso= +github.com/invopop/yaml v0.3.1/go.mod h1:PMOp3nn4/12yEZUFfmOuNHJsZToEEOwoWsT+D81KkeA= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -42,13 +47,19 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA= +github.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ= +golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg= golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo= +golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM= golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= +golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= From d7478e4a78383f9614b4248c720fd420ff28757b Mon Sep 17 00:00:00 2001 From: EwenQuim Date: Fri, 6 Dec 2024 09:27:18 +0100 Subject: [PATCH 019/138] Updated generate-opengraph-image module name to match package --- examples/generate-opengraph-image/go.mod | 2 +- examples/generate-opengraph-image/main.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/generate-opengraph-image/go.mod b/examples/generate-opengraph-image/go.mod index 20b8099c..6c34b457 100644 --- a/examples/generate-opengraph-image/go.mod +++ b/examples/generate-opengraph-image/go.mod @@ -1,4 +1,4 @@ -module github.com/go-fuego/fuego/examples/generate-image +module github.com/go-fuego/fuego/examples/generate-opengraph-image go 1.23.3 diff --git a/examples/generate-opengraph-image/main.go b/examples/generate-opengraph-image/main.go index 3e98af2e..d04757c8 100644 --- a/examples/generate-opengraph-image/main.go +++ b/examples/generate-opengraph-image/main.go @@ -4,7 +4,7 @@ import ( "github.com/getkin/kin-openapi/openapi3" "github.com/go-fuego/fuego" - "github.com/go-fuego/fuego/examples/generate-image/controller" + "github.com/go-fuego/fuego/examples/generate-opengraph-image/controller" "github.com/go-fuego/fuego/middleware/cache" "github.com/go-fuego/fuego/option" "github.com/go-fuego/fuego/param" From 66d77176ce4a8a9db8e3b4552d1a32098a63f517 Mon Sep 17 00:00:00 2001 From: EwenQuim Date: Fri, 6 Dec 2024 11:25:36 +0100 Subject: [PATCH 020/138] Fix server cache issue by setting the Content-Type header --- examples/generate-opengraph-image/controller/opengraph.go | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/generate-opengraph-image/controller/opengraph.go b/examples/generate-opengraph-image/controller/opengraph.go index 2c3e8923..87b039a8 100644 --- a/examples/generate-opengraph-image/controller/opengraph.go +++ b/examples/generate-opengraph-image/controller/opengraph.go @@ -48,6 +48,7 @@ func OpenGraphHandler(w http.ResponseWriter, r *http.Request) { addLabel(img, startX, lineY-12, 36, r.PathValue("title"), TitleColor) addLabel(img, startX, lineY+32, 24, Title, SubtitleColor) + w.Header().Set("Content-Type", "image/png") png.Encode(w, img) } From d55afac99ca1cec9a5e75d94d0920e1f78557555 Mon Sep 17 00:00:00 2001 From: simonemastella Date: Sat, 16 Nov 2024 12:17:36 +0100 Subject: [PATCH 021/138] added securityScheme --- openapi_operations.go | 12 ++++++++++++ server.go | 26 ++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/openapi_operations.go b/openapi_operations.go index 43087a11..48a49410 100644 --- a/openapi_operations.go +++ b/openapi_operations.go @@ -87,6 +87,18 @@ func (r Route[ResponseBody, RequestBody]) Param(paramType ParamType, name, descr return r } +// Security adds a security requirement to the route. +// It configures the route to require authentication using the specified security scheme. +// The requirementName parameter should match a security scheme defined in the OpenAPI components section. +// For example, if you have a JWT bearer auth scheme named "bearerAuth" in your components, +// you would call Security("bearerAuth") to require JWT authentication for this route. +func (r Route[ResponseBody, RequestBody]) Security(requirementName string) Route[ResponseBody, RequestBody] { + securityRequirement := openapi3.NewSecurityRequirement() + securityRequirement[requirementName] = []string{} + r.Operation.Security = &openapi3.SecurityRequirements{securityRequirement} + return r +} + // Header registers a header parameter for the route. // // Deprecated: Use `option.Header` from github.com/go-fuego/fuego/option instead. diff --git a/server.go b/server.go index 84f7a2db..e82f04c2 100644 --- a/server.go +++ b/server.go @@ -209,6 +209,32 @@ func WithGlobalResponseTypes(code int, description string, errorType ...any) fun } } +// WithSecurity configures security schemes in the OpenAPI specification. +// It allows setting up authentication methods like JWT Bearer tokens, API keys, OAuth2, etc. +// For example: +// +// app := fuego.NewServer( +// fuego.WithSecurity(map[string]*openapi3.SecuritySchemeRef{ +// "bearerAuth": &openapi3.SecuritySchemeRef{ +// Value: openapi3.NewSecurityScheme(). +// WithType("http"). +// WithScheme("bearer"). +// WithBearerFormat("JWT"). +// WithDescription("Enter your JWT token in the format: Bearer "), +// }, +// }), +// ) +func WithSecurity(schemes openapi3.SecuritySchemes) func(*Server) { + return func(s *Server) { + if s.OpenApiSpec.Components.SecuritySchemes == nil { + s.OpenApiSpec.Components.SecuritySchemes = openapi3.SecuritySchemes{} + } + for name, scheme := range schemes { + s.OpenApiSpec.Components.SecuritySchemes[name] = scheme + } + } +} + // WithoutAutoGroupTags disables the automatic grouping of routes by tags. // By default, routes are tagged by group. // For example: From 365db87b97c799a27310d199d41613bdebb2eb58 Mon Sep 17 00:00:00 2001 From: simonemastella Date: Tue, 19 Nov 2024 23:40:26 +0100 Subject: [PATCH 022/138] added OptionSecurity --- openapi_operations.go | 12 ---- option.go | 11 ++++ option/option.go | 3 + option_test.go | 149 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 163 insertions(+), 12 deletions(-) diff --git a/openapi_operations.go b/openapi_operations.go index 48a49410..43087a11 100644 --- a/openapi_operations.go +++ b/openapi_operations.go @@ -87,18 +87,6 @@ func (r Route[ResponseBody, RequestBody]) Param(paramType ParamType, name, descr return r } -// Security adds a security requirement to the route. -// It configures the route to require authentication using the specified security scheme. -// The requirementName parameter should match a security scheme defined in the OpenAPI components section. -// For example, if you have a JWT bearer auth scheme named "bearerAuth" in your components, -// you would call Security("bearerAuth") to require JWT authentication for this route. -func (r Route[ResponseBody, RequestBody]) Security(requirementName string) Route[ResponseBody, RequestBody] { - securityRequirement := openapi3.NewSecurityRequirement() - securityRequirement[requirementName] = []string{} - r.Operation.Security = &openapi3.SecurityRequirements{securityRequirement} - return r -} - // Header registers a header parameter for the route. // // Deprecated: Use `option.Header` from github.com/go-fuego/fuego/option instead. diff --git a/option.go b/option.go index 9dabaa43..1efe9a5c 100644 --- a/option.go +++ b/option.go @@ -267,3 +267,14 @@ func OptionHide() func(*BaseRoute) { r.Hidden = true } } + +func OptionSecurity(securityRequirements ...openapi3.SecurityRequirement) func(*BaseRoute) { + return func(r *BaseRoute) { + if r.Operation.Security == nil { + r.Operation.Security = &openapi3.SecurityRequirements{} + } + + // Append all provided security requirements + *r.Operation.Security = append(*r.Operation.Security, securityRequirements...) + } +} diff --git a/option/option.go b/option/option.go index 59c9ea57..0bb940c9 100644 --- a/option/option.go +++ b/option/option.go @@ -87,6 +87,9 @@ var Summary = fuego.OptionSummary // Description adds a description to the route. var Description = fuego.OptionDescription +// Security adds a list of openapi3.SecurityRequirement to the route. +var Security = fuego.OptionSecurity + // OperationID adds an operation ID to the route. var OperationID = fuego.OptionOperationID diff --git a/option_test.go b/option_test.go index da0afb69..b1e7b91a 100644 --- a/option_test.go +++ b/option_test.go @@ -6,6 +6,7 @@ import ( "net/http/httptest" "testing" + "github.com/getkin/kin-openapi/openapi3" "github.com/stretchr/testify/require" "github.com/thejerf/slogassert" @@ -443,3 +444,151 @@ func TestHide(t *testing.T) { require.Equal(t, "hello world", w.Body.String()) }) } + +func TestSecurity(t *testing.T) { + t.Run("single security requirement", func(t *testing.T) { + s := fuego.NewServer() + basic := openapi3.SecurityRequirement{ + "basic": []string{}, + } + route := fuego.Get(s, "/test", helloWorld, + fuego.OptionSecurity(basic), + ) + + require.NotNil(t, route.Operation.Security) + require.Len(t, *route.Operation.Security, 1) + require.Contains(t, (*route.Operation.Security)[0], "basic") + require.Empty(t, (*route.Operation.Security)[0]["basic"]) + + r := httptest.NewRequest(http.MethodGet, "/test", nil) + w := httptest.NewRecorder() + s.Mux.ServeHTTP(w, r) + require.Equal(t, "hello world", w.Body.String()) + }) + + t.Run("security with scopes", func(t *testing.T) { + s := fuego.NewServer() + + route := fuego.Get(s, "/test", helloWorld, + fuego.OptionSecurity( + openapi3.SecurityRequirement{ + "oauth2": []string{"read:users", "write:users"}, + }, + ), + ) + + require.NotNil(t, route.Operation.Security) + require.Len(t, *route.Operation.Security, 1) + require.Equal(t, + []string{"read:users", "write:users"}, + (*route.Operation.Security)[0]["oauth2"], + ) + }) + + t.Run("AND combination", func(t *testing.T) { + s := fuego.NewServer() + + route := fuego.Get(s, "/test", helloWorld, + fuego.OptionSecurity( + openapi3.SecurityRequirement{ + "basic": []string{}, + "oauth2": []string{"read:users"}, + }, + ), + ) + + require.NotNil(t, route.Operation.Security) + require.Len(t, *route.Operation.Security, 1) + require.Contains(t, (*route.Operation.Security)[0], "basic") + require.Contains(t, (*route.Operation.Security)[0], "oauth2") + require.Equal(t, []string{"read:users"}, (*route.Operation.Security)[0]["oauth2"]) + }) + + t.Run("OR combination", func(t *testing.T) { + s := fuego.NewServer() + + route := fuego.Get(s, "/test", helloWorld, + fuego.OptionSecurity( + openapi3.SecurityRequirement{ + "basic": []string{}, + }, + openapi3.SecurityRequirement{ + "oauth2": []string{"read:users"}, + }, + ), + ) + + require.NotNil(t, route.Operation.Security) + require.Len(t, *route.Operation.Security, 2) + require.Contains(t, (*route.Operation.Security)[0], "basic") + require.Contains(t, (*route.Operation.Security)[1], "oauth2") + require.Equal(t, []string{"read:users"}, (*route.Operation.Security)[1]["oauth2"]) + }) + + t.Run("complex combination", func(t *testing.T) { + s := fuego.NewServer() + + route := fuego.Get(s, "/test", helloWorld, + fuego.OptionSecurity( + openapi3.SecurityRequirement{ + "basic": []string{}, + "oauth2": []string{"read:users"}, + }, + openapi3.SecurityRequirement{ + "apiKey": []string{}, + }, + ), + ) + + require.NotNil(t, route.Operation.Security) + require.Len(t, *route.Operation.Security, 2) + + // Check first requirement (basic AND oauth2) + require.Contains(t, (*route.Operation.Security)[0], "basic") + require.Contains(t, (*route.Operation.Security)[0], "oauth2") + require.Equal(t, []string{"read:users"}, (*route.Operation.Security)[0]["oauth2"]) + + // Check second requirement (apiKey) + require.Contains(t, (*route.Operation.Security)[1], "apiKey") + require.Empty(t, (*route.Operation.Security)[1]["apiKey"]) + }) + + t.Run("empty security options", func(t *testing.T) { + s := fuego.NewServer() + + route := fuego.Get(s, "/test", helloWorld, + fuego.OptionSecurity(), + ) + + require.NotNil(t, route.Operation.Security) + require.Len(t, *route.Operation.Security, 0) + require.Empty(t, (*route.Operation.Security)) + }) + + t.Run("multiple security options with different scopes", func(t *testing.T) { + s := fuego.NewServer() + + route := fuego.Get(s, "/test", helloWorld, + fuego.OptionSecurity( + openapi3.SecurityRequirement{ + "Bearer": []string{"read"}, + "ApiKey": []string{"basic"}, + }, + ), + ) + + require.NotNil(t, route.Operation.Security) + require.Len(t, *route.Operation.Security, 1) + + // Check security requirements + security := (*route.Operation.Security)[0] + + // Check Bearer requirements + require.Contains(t, security, "Bearer") + require.Equal(t, []string{"read"}, security["Bearer"]) + + // Check ApiKey requirements + require.Contains(t, security, "ApiKey") + require.Equal(t, []string{"basic"}, security["ApiKey"]) + }) +} From 873c0d54ebff365dceece3eedaf98d80b04942a2 Mon Sep 17 00:00:00 2001 From: simonemastella Date: Wed, 20 Nov 2024 21:39:33 +0100 Subject: [PATCH 023/138] enhance description of option.Security --- option/option.go | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/option/option.go b/option/option.go index 0bb940c9..c076917c 100644 --- a/option/option.go +++ b/option/option.go @@ -87,7 +87,36 @@ var Summary = fuego.OptionSummary // Description adds a description to the route. var Description = fuego.OptionDescription -// Security adds a list of openapi3.SecurityRequirement to the route. +// OptionSecurity configures security requirements to the route. +// +// Single Scheme (AND Logic): +// +// Add a single security requirement with multiple schemes. +// All schemes must be satisfied: +// OptionSecurity(openapi3.SecurityRequirement{ +// "basic": [], // Requires basic auth +// "oauth2": ["read"] // AND requires oauth with read scope +// }) +// +// Multiple Schemes (OR Logic): +// +// Add multiple security requirements. +// At least one requirement must be satisfied: +// OptionSecurity( +// openapi3.SecurityRequirement{"basic": []}, // First option +// openapi3.SecurityRequirement{"oauth2": ["read"]} // Alternative option +// }) +// +// Mixing Approaches: +// +// Combine AND logic within requirements and OR logic between requirements: +// OptionSecurity( +// openapi3.SecurityRequirement{ +// "basic": [], // Requires basic auth +// "oauth2": ["read:user"] // AND oauth with read:user scope +// }, +// openapi3.SecurityRequirement{"apiKey": []} // OR alternative with API key +// }) var Security = fuego.OptionSecurity // OperationID adds an operation ID to the route. From d4f985ec7db202b6f21e39631a19b944a19900e3 Mon Sep 17 00:00:00 2001 From: simonemastella Date: Wed, 20 Nov 2024 21:48:02 +0100 Subject: [PATCH 024/138] added tests to cover WithSecurity --- server_test.go | 129 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) diff --git a/server_test.go b/server_test.go index ae4d6842..e3e43355 100644 --- a/server_test.go +++ b/server_test.go @@ -9,6 +9,7 @@ import ( "net/http/httptest" "testing" + "github.com/getkin/kin-openapi/openapi3" "github.com/go-playground/validator/v10" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -571,3 +572,131 @@ func TestHideGroupAfterGroupParam(t *testing.T) { document := s.OutputOpenAPISpec() require.Nil(t, document.Paths.Find("/api/test")) } + +func TestWithSecurity(t *testing.T) { + t.Run("add single security scheme", func(t *testing.T) { + s := NewServer( + WithSecurity(openapi3.SecuritySchemes{ + "bearerAuth": &openapi3.SecuritySchemeRef{ + Value: openapi3.NewSecurityScheme(). + WithType("http"). + WithScheme("bearer"). + WithBearerFormat("JWT"), + }, + }), + ) + + require.NotNil(t, s.OpenApiSpec.Components.SecuritySchemes) + require.Contains(t, s.OpenApiSpec.Components.SecuritySchemes, "bearerAuth") + + scheme := s.OpenApiSpec.Components.SecuritySchemes["bearerAuth"].Value + require.Equal(t, "http", scheme.Type) + require.Equal(t, "bearer", scheme.Scheme) + require.Equal(t, "JWT", scheme.BearerFormat) + }) + + t.Run("add multiple security schemes", func(t *testing.T) { + s := NewServer( + WithSecurity(openapi3.SecuritySchemes{ + "bearerAuth": &openapi3.SecuritySchemeRef{ + Value: openapi3.NewSecurityScheme(). + WithType("http"). + WithScheme("bearer"). + WithBearerFormat("JWT"), + }, + "apiKey": &openapi3.SecuritySchemeRef{ + Value: openapi3.NewSecurityScheme(). + WithType("apiKey"). + WithIn("header"). + WithName("X-API-Key"), + }, + }), + ) + + require.NotNil(t, s.OpenApiSpec.Components.SecuritySchemes) + require.Contains(t, s.OpenApiSpec.Components.SecuritySchemes, "bearerAuth") + require.Contains(t, s.OpenApiSpec.Components.SecuritySchemes, "apiKey") + + bearerScheme := s.OpenApiSpec.Components.SecuritySchemes["bearerAuth"].Value + apiKeyScheme := s.OpenApiSpec.Components.SecuritySchemes["apiKey"].Value + + require.Equal(t, "http", bearerScheme.Type) + require.Equal(t, "bearer", bearerScheme.Scheme) + require.Equal(t, "JWT", bearerScheme.BearerFormat) + + require.Equal(t, "apiKey", apiKeyScheme.Type) + require.Equal(t, "header", apiKeyScheme.In) + require.Equal(t, "X-API-Key", apiKeyScheme.Name) + }) + + t.Run("add security scheme to server with existing schemes", func(t *testing.T) { + s := NewServer( + WithSecurity(openapi3.SecuritySchemes{ + "bearerAuth": &openapi3.SecuritySchemeRef{ + Value: openapi3.NewSecurityScheme(). + WithType("http"). + WithScheme("bearer"). + WithBearerFormat("JWT"), + }, + }), + ) + + // Add another security scheme to the existing server + s.OpenApiSpec.Components.SecuritySchemes["oauth2"] = &openapi3.SecuritySchemeRef{ + Value: openapi3.NewOIDCSecurityScheme("https://example.com/.well-known/openid-configuration"). + WithType("oauth2"), + } + + require.NotNil(t, s.OpenApiSpec.Components.SecuritySchemes) + require.Contains(t, s.OpenApiSpec.Components.SecuritySchemes, "bearerAuth") + require.Contains(t, s.OpenApiSpec.Components.SecuritySchemes, "oauth2") + + oauth2Scheme := s.OpenApiSpec.Components.SecuritySchemes["oauth2"].Value + require.Equal(t, "oauth2", oauth2Scheme.Type) + require.Equal(t, "https://example.com/.well-known/openid-configuration", oauth2Scheme.OpenIdConnectUrl) + }) + + t.Run("multiple calls to WithSecurity", func(t *testing.T) { + s := NewServer( + WithSecurity(openapi3.SecuritySchemes{ + "bearerAuth": &openapi3.SecuritySchemeRef{ + Value: openapi3.NewSecurityScheme(). + WithType("http"). + WithScheme("bearer"). + WithBearerFormat("JWT"), + }, + }), + WithSecurity(openapi3.SecuritySchemes{ + "apiKey": &openapi3.SecuritySchemeRef{ + Value: openapi3.NewSecurityScheme(). + WithType("apiKey"). + WithIn("header"). + WithName("X-API-Key"), + }, + }), + ) + + require.NotNil(t, s.OpenApiSpec.Components.SecuritySchemes) + require.Contains(t, s.OpenApiSpec.Components.SecuritySchemes, "bearerAuth") + require.Contains(t, s.OpenApiSpec.Components.SecuritySchemes, "apiKey") + }) + + t.Run("initialize security schemes if nil", func(t *testing.T) { + s := NewServer() + s.OpenApiSpec.Components.SecuritySchemes = nil + + s = NewServer( + WithSecurity(openapi3.SecuritySchemes{ + "bearerAuth": &openapi3.SecuritySchemeRef{ + Value: openapi3.NewSecurityScheme(). + WithType("http"). + WithScheme("bearer"). + WithBearerFormat("JWT"), + }, + }), + ) + + require.NotNil(t, s.OpenApiSpec.Components.SecuritySchemes) + require.Contains(t, s.OpenApiSpec.Components.SecuritySchemes, "bearerAuth") + }) +} From 4cb8e57ae7c94a18d4c29f6cf9029a89f288be99 Mon Sep 17 00:00:00 2001 From: simone mastella <35423599+simonemastella@users.noreply.github.com> Date: Wed, 20 Nov 2024 22:21:41 +0100 Subject: [PATCH 025/138] Update option_test.go Co-authored-by: ccoVeille <3875889+ccoVeille@users.noreply.github.com> --- option_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/option_test.go b/option_test.go index b1e7b91a..ff791433 100644 --- a/option_test.go +++ b/option_test.go @@ -561,7 +561,6 @@ func TestSecurity(t *testing.T) { ) require.NotNil(t, route.Operation.Security) - require.Len(t, *route.Operation.Security, 0) require.Empty(t, (*route.Operation.Security)) }) From fc79beb7452f6bf75ae633679c7d345d082534d2 Mon Sep 17 00:00:00 2001 From: simonemastella Date: Wed, 20 Nov 2024 22:28:20 +0100 Subject: [PATCH 026/138] requested changes --- option_test.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/option_test.go b/option_test.go index ff791433..b7b69272 100644 --- a/option_test.go +++ b/option_test.go @@ -479,6 +479,7 @@ func TestSecurity(t *testing.T) { require.NotNil(t, route.Operation.Security) require.Len(t, *route.Operation.Security, 1) + require.Contains(t, (*route.Operation.Security)[0], "oauth2") require.Equal(t, []string{"read:users", "write:users"}, (*route.Operation.Security)[0]["oauth2"], @@ -500,6 +501,7 @@ func TestSecurity(t *testing.T) { require.NotNil(t, route.Operation.Security) require.Len(t, *route.Operation.Security, 1) require.Contains(t, (*route.Operation.Security)[0], "basic") + require.Empty(t, (*route.Operation.Security)[0]["basic"]) require.Contains(t, (*route.Operation.Security)[0], "oauth2") require.Equal(t, []string{"read:users"}, (*route.Operation.Security)[0]["oauth2"]) }) @@ -521,6 +523,7 @@ func TestSecurity(t *testing.T) { require.NotNil(t, route.Operation.Security) require.Len(t, *route.Operation.Security, 2) require.Contains(t, (*route.Operation.Security)[0], "basic") + require.Empty(t, (*route.Operation.Security)[0]["basic"]) require.Contains(t, (*route.Operation.Security)[1], "oauth2") require.Equal(t, []string{"read:users"}, (*route.Operation.Security)[1]["oauth2"]) }) @@ -545,6 +548,7 @@ func TestSecurity(t *testing.T) { // Check first requirement (basic AND oauth2) require.Contains(t, (*route.Operation.Security)[0], "basic") + require.Empty(t, (*route.Operation.Security)[0]["basic"]) require.Contains(t, (*route.Operation.Security)[0], "oauth2") require.Equal(t, []string{"read:users"}, (*route.Operation.Security)[0]["oauth2"]) From c8e0af9ea90632aad36a2a0e57f6963ad263149e Mon Sep 17 00:00:00 2001 From: simonemastella Date: Thu, 21 Nov 2024 23:54:04 +0100 Subject: [PATCH 027/138] added check on secreq declaration --- option.go | 13 ++++ option_test.go | 159 ++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 136 insertions(+), 36 deletions(-) diff --git a/option.go b/option.go index 1efe9a5c..894d93fd 100644 --- a/option.go +++ b/option.go @@ -1,6 +1,7 @@ package fuego import ( + "fmt" "net/http" "github.com/getkin/kin-openapi/openapi3" @@ -270,6 +271,18 @@ func OptionHide() func(*BaseRoute) { func OptionSecurity(securityRequirements ...openapi3.SecurityRequirement) func(*BaseRoute) { return func(r *BaseRoute) { + + // Validate the security scheme exists in components + for _, req := range securityRequirements { + for schemeName := range req { + if r.mainRouter.OpenApiSpec.Components != nil { + if _, exists := r.mainRouter.OpenApiSpec.Components.SecuritySchemes[schemeName]; !exists { + panic(fmt.Sprintf("security scheme '%s' not defined in components", schemeName)) + } + } + } + } + if r.Operation.Security == nil { r.Operation.Security = &openapi3.SecurityRequirements{} } diff --git a/option_test.go b/option_test.go index b7b69272..21244f84 100644 --- a/option_test.go +++ b/option_test.go @@ -446,8 +446,17 @@ func TestHide(t *testing.T) { } func TestSecurity(t *testing.T) { - t.Run("single security requirement", func(t *testing.T) { - s := fuego.NewServer() + t.Run("single security requirement with defined scheme", func(t *testing.T) { + s := fuego.NewServer( + fuego.WithSecurity(openapi3.SecuritySchemes{ + "basic": &openapi3.SecuritySchemeRef{ + Value: openapi3.NewSecurityScheme(). + WithType("http"). + WithScheme("basic"), + }, + }), + ) + basic := openapi3.SecurityRequirement{ "basic": []string{}, } @@ -466,8 +475,25 @@ func TestSecurity(t *testing.T) { require.Equal(t, "hello world", w.Body.String()) }) - t.Run("security with scopes", func(t *testing.T) { - s := fuego.NewServer() + t.Run("security with scopes and defined scheme", func(t *testing.T) { + s := fuego.NewServer( + fuego.WithSecurity(openapi3.SecuritySchemes{ + "oauth2": &openapi3.SecuritySchemeRef{ + Value: &openapi3.SecurityScheme{ + Type: "oauth2", + Flows: &openapi3.OAuthFlows{ + AuthorizationCode: &openapi3.OAuthFlow{ + AuthorizationURL: "https://example.com/oauth/authorize", + TokenURL: "https://example.com/oauth/token", + Scopes: map[string]string{ + "read:users": "Read user information", + }, + }, + }, + }, + }, + }), + ) route := fuego.Get(s, "/test", helloWorld, fuego.OptionSecurity( @@ -486,8 +512,30 @@ func TestSecurity(t *testing.T) { ) }) - t.Run("AND combination", func(t *testing.T) { - s := fuego.NewServer() + t.Run("AND combination with defined schemes", func(t *testing.T) { + s := fuego.NewServer( + fuego.WithSecurity(openapi3.SecuritySchemes{ + "basic": &openapi3.SecuritySchemeRef{ + Value: openapi3.NewSecurityScheme(). + WithType("http"). + WithScheme("basic"), + }, + "oauth2": &openapi3.SecuritySchemeRef{ + Value: &openapi3.SecurityScheme{ + Type: "oauth2", + Flows: &openapi3.OAuthFlows{ + AuthorizationCode: &openapi3.OAuthFlow{ + AuthorizationURL: "https://example.com/oauth/authorize", + TokenURL: "https://example.com/oauth/token", + Scopes: map[string]string{ + "read:users": "Read user information", + }, + }, + }, + }, + }, + }), + ) route := fuego.Get(s, "/test", helloWorld, fuego.OptionSecurity( @@ -506,8 +554,30 @@ func TestSecurity(t *testing.T) { require.Equal(t, []string{"read:users"}, (*route.Operation.Security)[0]["oauth2"]) }) - t.Run("OR combination", func(t *testing.T) { - s := fuego.NewServer() + t.Run("OR combination with defined schemes", func(t *testing.T) { + s := fuego.NewServer( + fuego.WithSecurity(openapi3.SecuritySchemes{ + "basic": &openapi3.SecuritySchemeRef{ + Value: openapi3.NewSecurityScheme(). + WithType("http"). + WithScheme("basic"), + }, + "oauth2": &openapi3.SecuritySchemeRef{ + Value: &openapi3.SecurityScheme{ + Type: "oauth2", + Flows: &openapi3.OAuthFlows{ + AuthorizationCode: &openapi3.OAuthFlow{ + AuthorizationURL: "https://example.com/oauth/authorize", + TokenURL: "https://example.com/oauth/token", + Scopes: map[string]string{ + "read:users": "Read user information", + }, + }, + }, + }, + }, + }), + ) route := fuego.Get(s, "/test", helloWorld, fuego.OptionSecurity( @@ -528,33 +598,41 @@ func TestSecurity(t *testing.T) { require.Equal(t, []string{"read:users"}, (*route.Operation.Security)[1]["oauth2"]) }) - t.Run("complex combination", func(t *testing.T) { + t.Run("panic on undefined security scheme", func(t *testing.T) { s := fuego.NewServer() - route := fuego.Get(s, "/test", helloWorld, - fuego.OptionSecurity( - openapi3.SecurityRequirement{ - "basic": []string{}, - "oauth2": []string{"read:users"}, - }, - openapi3.SecurityRequirement{ - "apiKey": []string{}, + require.Panics(t, func() { + fuego.Get(s, "/test", helloWorld, + fuego.OptionSecurity( + openapi3.SecurityRequirement{ + "undefined": []string{}, + }, + ), + ) + }) + }) + + t.Run("panic on partially undefined schemes", func(t *testing.T) { + s := fuego.NewServer( + fuego.WithSecurity(openapi3.SecuritySchemes{ + "basic": &openapi3.SecuritySchemeRef{ + Value: openapi3.NewSecurityScheme(). + WithType("http"). + WithScheme("basic"), }, - ), + }), ) - require.NotNil(t, route.Operation.Security) - require.Len(t, *route.Operation.Security, 2) - - // Check first requirement (basic AND oauth2) - require.Contains(t, (*route.Operation.Security)[0], "basic") - require.Empty(t, (*route.Operation.Security)[0]["basic"]) - require.Contains(t, (*route.Operation.Security)[0], "oauth2") - require.Equal(t, []string{"read:users"}, (*route.Operation.Security)[0]["oauth2"]) - - // Check second requirement (apiKey) - require.Contains(t, (*route.Operation.Security)[1], "apiKey") - require.Empty(t, (*route.Operation.Security)[1]["apiKey"]) + require.Panics(t, func() { + fuego.Get(s, "/test", helloWorld, + fuego.OptionSecurity( + openapi3.SecurityRequirement{ + "basic": []string{}, + "undefined": []string{}, + }, + ), + ) + }) }) t.Run("empty security options", func(t *testing.T) { @@ -569,7 +647,21 @@ func TestSecurity(t *testing.T) { }) t.Run("multiple security options with different scopes", func(t *testing.T) { - s := fuego.NewServer() + s := fuego.NewServer( + fuego.WithSecurity(openapi3.SecuritySchemes{ + "Bearer": &openapi3.SecuritySchemeRef{ + Value: openapi3.NewSecurityScheme(). + WithType("http"). + WithScheme("bearer"), + }, + "ApiKey": &openapi3.SecuritySchemeRef{ + Value: openapi3.NewSecurityScheme(). + WithType("apiKey"). + WithIn("header"). + WithName("X-API-Key"), + }, + }), + ) route := fuego.Get(s, "/test", helloWorld, fuego.OptionSecurity( @@ -583,14 +675,9 @@ func TestSecurity(t *testing.T) { require.NotNil(t, route.Operation.Security) require.Len(t, *route.Operation.Security, 1) - // Check security requirements security := (*route.Operation.Security)[0] - - // Check Bearer requirements require.Contains(t, security, "Bearer") require.Equal(t, []string{"read"}, security["Bearer"]) - - // Check ApiKey requirements require.Contains(t, security, "ApiKey") require.Equal(t, []string{"basic"}, security["ApiKey"]) }) From 4cf4668e43ec2529272b5bc3811a6bf669bf45db Mon Sep 17 00:00:00 2001 From: simonemastella Date: Sat, 23 Nov 2024 10:44:26 +0100 Subject: [PATCH 028/138] optimized OptionSecurity --- option.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/option.go b/option.go index 894d93fd..0ad84895 100644 --- a/option.go +++ b/option.go @@ -271,14 +271,15 @@ func OptionHide() func(*BaseRoute) { func OptionSecurity(securityRequirements ...openapi3.SecurityRequirement) func(*BaseRoute) { return func(r *BaseRoute) { + if r.mainRouter.OpenApiSpec.Components == nil { + panic("zero security schemes have been registered with the server") + } // Validate the security scheme exists in components for _, req := range securityRequirements { for schemeName := range req { - if r.mainRouter.OpenApiSpec.Components != nil { - if _, exists := r.mainRouter.OpenApiSpec.Components.SecuritySchemes[schemeName]; !exists { - panic(fmt.Sprintf("security scheme '%s' not defined in components", schemeName)) - } + if _, exists := r.mainRouter.OpenApiSpec.Components.SecuritySchemes[schemeName]; !exists { + panic(fmt.Sprintf("security scheme '%s' not defined in components", schemeName)) } } } From 3db8ab1c683db20470b393dbce33254a265646db Mon Sep 17 00:00:00 2001 From: EwenQuim Date: Fri, 6 Dec 2024 11:53:21 +0100 Subject: [PATCH 029/138] Add comments to OptionSecurity to explain how to use it --- option.go | 30 ++++++++++++++++++++++++++++++ option/option.go | 8 ++++---- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/option.go b/option.go index 0ad84895..50b9f65a 100644 --- a/option.go +++ b/option.go @@ -269,6 +269,36 @@ func OptionHide() func(*BaseRoute) { } } +// OptionSecurity configures security requirements to the route. +// +// Single Scheme (AND Logic): +// +// Add a single security requirement with multiple schemes. +// All schemes must be satisfied: +// OptionSecurity(openapi3.SecurityRequirement{ +// "basic": [], // Requires basic auth +// "oauth2": ["read"] // AND requires oauth with read scope +// }) +// +// Multiple Schemes (OR Logic): +// +// Add multiple security requirements. +// At least one requirement must be satisfied: +// OptionSecurity( +// openapi3.SecurityRequirement{"basic": []}, // First option +// openapi3.SecurityRequirement{"oauth2": ["read"]} // Alternative option +// }) +// +// Mixing Approaches: +// +// Combine AND logic within requirements and OR logic between requirements: +// OptionSecurity( +// openapi3.SecurityRequirement{ +// "basic": [], // Requires basic auth +// "oauth2": ["read:user"] // AND oauth with read:user scope +// }, +// openapi3.SecurityRequirement{"apiKey": []} // OR alternative with API key +// }) func OptionSecurity(securityRequirements ...openapi3.SecurityRequirement) func(*BaseRoute) { return func(r *BaseRoute) { if r.mainRouter.OpenApiSpec.Components == nil { diff --git a/option/option.go b/option/option.go index c076917c..403f5609 100644 --- a/option/option.go +++ b/option/option.go @@ -87,13 +87,13 @@ var Summary = fuego.OptionSummary // Description adds a description to the route. var Description = fuego.OptionDescription -// OptionSecurity configures security requirements to the route. +// Security configures security requirements to the route. // // Single Scheme (AND Logic): // // Add a single security requirement with multiple schemes. // All schemes must be satisfied: -// OptionSecurity(openapi3.SecurityRequirement{ +// Security(openapi3.SecurityRequirement{ // "basic": [], // Requires basic auth // "oauth2": ["read"] // AND requires oauth with read scope // }) @@ -102,7 +102,7 @@ var Description = fuego.OptionDescription // // Add multiple security requirements. // At least one requirement must be satisfied: -// OptionSecurity( +// Security( // openapi3.SecurityRequirement{"basic": []}, // First option // openapi3.SecurityRequirement{"oauth2": ["read"]} // Alternative option // }) @@ -110,7 +110,7 @@ var Description = fuego.OptionDescription // Mixing Approaches: // // Combine AND logic within requirements and OR logic between requirements: -// OptionSecurity( +// Security( // openapi3.SecurityRequirement{ // "basic": [], // Requires basic auth // "oauth2": ["read:user"] // AND oauth with read:user scope From a4ad38e8621846f5e55f12c5f98985ac20ffdd13 Mon Sep 17 00:00:00 2001 From: EwenQuim Date: Fri, 6 Dec 2024 14:17:43 +0100 Subject: [PATCH 030/138] Removes deprecated route option methods --- mux_test.go | 43 ++++-------- openapi_operations.go | 137 ------------------------------------- openapi_operations_test.go | 76 +++++++++----------- server.go | 15 +++- 4 files changed, 58 insertions(+), 213 deletions(-) diff --git a/mux_test.go b/mux_test.go index 0d9f252c..9cf6d5c3 100644 --- a/mux_test.go +++ b/mux_test.go @@ -406,16 +406,17 @@ func TestRegister(t *testing.T) { OperationID: "my-operation-id", }, }, - }, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})). - OperationID("new-operation-id"). - Summary("new-summary"). - Description("new-description"). - Tags("new-tag") + }, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {}), + OptionOperationID("new-operation-id"), + OptionSummary("new-summary"), + OptionDescription("new-description"), + OptionTags("new-tag"), + ) require.NotNil(t, route) - require.Equal(t, []string{"new-tag"}, route.Operation.Tags) + require.Equal(t, []string{"my-tag", "new-tag"}, route.Operation.Tags) require.Equal(t, "new-summary", route.Operation.Summary) - require.Equal(t, "new-description", route.Operation.Description) + require.Equal(t, "controller: `/test`\n\n---\n\nnew-description", route.Operation.Description) require.Equal(t, "new-operation-id", route.Operation.OperationID) }) } @@ -451,37 +452,17 @@ func TestGroupTagsOnRoute(t *testing.T) { require.Equal(t, []string{"my-server-tag"}, route.Operation.Tags) }) - t.Run("route tag override", func(t *testing.T) { - s := NewServer(). - Tags("my-server-tag") - - route := Get(s, "/path", func(ctx *ContextNoBody) (string, error) { - return "test", nil - }).Tags("my-route-tag") - - require.Equal(t, []string{"my-route-tag"}, route.Operation.Tags) - }) - t.Run("route tag add", func(t *testing.T) { s := NewServer(). Tags("my-server-tag") route := Get(s, "/path", func(ctx *ContextNoBody) (string, error) { return "test", nil - }).AddTags("my-route-tag") - - require.Equal(t, []string{"my-server-tag", "my-route-tag"}, route.Operation.Tags) - }) - - t.Run("route tag removal", func(t *testing.T) { - s := NewServer(). - Tags("my-server-tag") - - route := Get(s, "/path", func(ctx *ContextNoBody) (string, error) { - return "test", nil - }).AddTags("my-route-tag").RemoveTags("my-server-tag") + }, + OptionTags("my-route-tag"), + ) - require.Equal(t, []string{"my-route-tag"}, route.Operation.Tags) + require.Equal(t, []string{"my-route-tag", "my-server-tag"}, route.Operation.Tags) }) } diff --git a/openapi_operations.go b/openapi_operations.go index 43087a11..d259a588 100644 --- a/openapi_operations.go +++ b/openapi_operations.go @@ -1,8 +1,6 @@ package fuego import ( - "slices" - "github.com/getkin/kin-openapi/openapi3" ) @@ -31,39 +29,6 @@ type OpenAPIParamOption struct { GoType string // integer, string, bool } -// Overrides the description for the route. -// -// Deprecated: Use `option.Description` from github.com/go-fuego/fuego/option instead. -// Example: -// -// fuego.Get(s, "/test", testController, option.Description("my description")) -func (r Route[ResponseBody, RequestBody]) Description(description string) Route[ResponseBody, RequestBody] { - r.Operation.Description = description - return r -} - -// Overrides the summary for the route. -// -// Deprecated: Use `option.Summary` from github.com/go-fuego/fuego/option instead. -// Example: -// -// fuego.Get(s, "/test", testController, option.Summary("my summary")) -func (r Route[ResponseBody, RequestBody]) Summary(summary string) Route[ResponseBody, RequestBody] { - r.Operation.Summary = summary - return r -} - -// Overrides the operationID for the route. -// -// Deprecated: Use `option.OperationID` from github.com/go-fuego/fuego/option instead. -// Example: -// -// fuego.Get(s, "/test", testController, option.OperationID("my-operation-id")) -func (r Route[ResponseBody, RequestBody]) OperationID(operationID string) Route[ResponseBody, RequestBody] { - r.Operation.OperationID = operationID - return r -} - // Param registers a parameter for the route. // The paramType can be "query", "header" or "cookie" as defined in [ParamType]. // [Cookie], [Header], [QueryParam] are shortcuts for Param. @@ -87,84 +52,6 @@ func (r Route[ResponseBody, RequestBody]) Param(paramType ParamType, name, descr return r } -// Header registers a header parameter for the route. -// -// Deprecated: Use `option.Header` from github.com/go-fuego/fuego/option instead. -// Example: -// -// fuego.Get(s, "/test", testController, option.Header("my-header", "my description")) -func (r Route[ResponseBody, RequestBody]) Header(name, description string, params ...OpenAPIParamOption) Route[ResponseBody, RequestBody] { - r.Param(HeaderParamType, name, description, params...) - return r -} - -// Cookie registers a cookie parameter for the route. -// -// Deprecated: Use `option.Cookie` from github.com/go-fuego/fuego/option instead. -// Example: -// -// fuego.Get(s, "/test", testController, option.Cookie("my-cookie", "my description")) -func (r Route[ResponseBody, RequestBody]) Cookie(name, description string, params ...OpenAPIParamOption) Route[ResponseBody, RequestBody] { - r.Param(CookieParamType, name, description, params...) - return r -} - -// QueryParam registers a query parameter for the route. -// -// Deprecated: Use `option.Query` from github.com/go-fuego/fuego/option instead. -// Example: -// -// fuego.Get(s, "/test", testController, option.Query("my-param", "my description")) -func (r Route[ResponseBody, RequestBody]) QueryParam(name, description string, params ...OpenAPIParamOption) Route[ResponseBody, RequestBody] { - r.Param(QueryParamType, name, description, params...) - return r -} - -// Replace the tags for the route. -// By default, the tag is the type of the response body. -// -// Deprecated: Use `option.Tags` from github.com/go-fuego/fuego/option instead. -// Example: -// -// fuego.Get(s, "/test", testController, option.Tags("my-tag")) -func (r Route[ResponseBody, RequestBody]) Tags(tags ...string) Route[ResponseBody, RequestBody] { - r.Operation.Tags = tags - return r -} - -// Replace the available request Content-Types for the route. -// By default, the request Content-Types are `application/json` and `application/xml` -// -// Deprecated: Use `option.RequestContentType` from github.com/go-fuego/fuego/option instead. -// Example: -// -// fuego.Post(s, "/test", testControllerWithBody, option.RequestContentType("application/json")) -func (r Route[ResponseBody, RequestBody]) RequestContentType(consumes ...string) Route[ResponseBody, RequestBody] { - bodyTag := SchemaTagFromType(r.mainRouter, *new(RequestBody)) - - if bodyTag.Name != "unknown-interface" { - requestBody := newRequestBody[RequestBody](bodyTag, consumes) - - // set just Value as we do not want to reference - // a global requestBody - r.Operation.RequestBody = &openapi3.RequestBodyRef{ - Value: requestBody, - } - } - return r -} - -// AddTags adds tags to the route. -// -// Deprecated: Use `option.Tags` from github.com/go-fuego/fuego/option instead. -// Example: -// -// fuego.Get(s, "/test", testController, option.Tags("my-tag")) -func (r Route[ResponseBody, RequestBody]) AddTags(tags ...string) Route[ResponseBody, RequestBody] { - r.Operation.Tags = append(r.Operation.Tags, tags...) - return r -} - // AddError adds an error to the route. // // Deprecated: Use `option.AddError` from github.com/go-fuego/fuego/option instead. @@ -196,27 +83,3 @@ type openAPIError struct { Description string ErrorType any } - -// RemoveTags removes tags from the route. -func (r Route[ResponseBody, RequestBody]) RemoveTags(tags ...string) Route[ResponseBody, RequestBody] { - for _, tag := range tags { - for i, t := range r.Operation.Tags { - if t == tag { - r.Operation.Tags = slices.Delete(r.Operation.Tags, i, i+1) - break - } - } - } - return r -} - -// Deprecated marks the route as deprecated. -// -// Deprecated: Use `option.Deprecated` from github.com/go-fuego/fuego/option instead. -// Example: -// -// fuego.Get(s, "/test", testController, option.Deprecated()) -func (r Route[ResponseBody, RequestBody]) Deprecated() Route[ResponseBody, RequestBody] { - r.Operation.Deprecated = true - return r -} diff --git a/openapi_operations_test.go b/openapi_operations_test.go index 4a86d37b..9b59a532 100644 --- a/openapi_operations_test.go +++ b/openapi_operations_test.go @@ -8,55 +8,43 @@ import ( func TestTags(t *testing.T) { s := NewServer() - route := Get(s, "/test", testController). - Tags("my-tag"). - Description("my description"). - Summary("my summary"). - Deprecated() - - require.Equal(t, route.Operation.Tags, []string{"my-tag"}) - require.Equal(t, route.Operation.Description, "my description") - require.Equal(t, route.Operation.Summary, "my summary") - require.Equal(t, route.Operation.Deprecated, true) + route := Get(s, "/test", testController, + OptionTags("my-tag"), + OptionDescription("my description"), + OptionSummary("my summary"), + OptionDeprecated(), + ) + + require.Equal(t, []string{"my-tag"}, route.Operation.Tags) + require.Equal(t, "controller: `github.com/go-fuego/fuego.testController`\n\n---\n\nmy description", route.Operation.Description) + require.Equal(t, "my summary", route.Operation.Summary) + require.Equal(t, true, route.Operation.Deprecated) } func TestAddTags(t *testing.T) { s := NewServer() - route := Get(s, "/test", func(ctx *ContextNoBody) (string, error) { - return "test", nil - }). - AddTags("my-tag"). - AddTags("my-other-tag") + route := Get(s, "/test", dummyController, + OptionTags("my-tag"), + OptionTags("my-other-tag"), + ) require.Equal(t, route.Operation.Tags, []string{"my-tag", "my-other-tag"}) } -func TestRemoveTags(t *testing.T) { - s := NewServer() - route := Get(s, "/test", func(ctx *ContextNoBody) (string, error) { - return "test", nil - }). - AddTags("my-tag"). - RemoveTags("my-tag", "string"). - AddTags("my-other-tag") - - require.Equal(t, route.Operation.Tags, []string{"my-other-tag"}) -} - -func TestQueryParams(t *testing.T) { +func TestQuery(t *testing.T) { s := NewServer() - route := Get(s, "/test", func(ctx *ContextNoBody) (string, error) { - return "test", nil - }). - QueryParam("my-param", "my description") + route := Get(s, "/test", dummyController, + OptionQuery("my-param", "my description"), + ) require.Equal(t, "my description", route.Operation.Parameters.GetByInAndName("query", "my-param").Description) } func TestHeaderParams(t *testing.T) { s := NewServer() - route := Get(s, "/test", testController). - Header("my-header", "my description") + route := Get(s, "/test", testController, + OptionHeader("my-header", "my description"), + ) require.Equal(t, "my description", route.Operation.Parameters.GetByInAndName("header", "my-header").Description) } @@ -102,19 +90,23 @@ func TestCustomErrorGlobalAndOnRoute(t *testing.T) { func TestCookieParams(t *testing.T) { t.Run("basic cookie", func(t *testing.T) { s := NewServer() - route := Get(s, "/test", testController). - Cookie("my-cookie", "my description") + route := Get(s, "/test", testController, + OptionCookie("my-cookie", "my description"), + ) require.Equal(t, "my description", route.Operation.Parameters.GetByInAndName("cookie", "my-cookie").Description) }) t.Run("with more parameters", func(t *testing.T) { s := NewServer() - route := Get(s, "/test", testController). - Cookie("my-cookie", "my description", OpenAPIParamOption{Required: true, Example: "my-example"}) - - require.Equal(t, "my description", route.Operation.Parameters.GetByInAndName("cookie", "my-cookie").Description) - require.Equal(t, true, route.Operation.Parameters.GetByInAndName("cookie", "my-cookie").Required) - require.Equal(t, "my-example", route.Operation.Parameters.GetByInAndName("cookie", "my-cookie").Example) + route := Get(s, "/test", testController, + OptionCookie("my-cookie", "my description", ParamRequired(), ParamExample("example", "my-example")), + ) + + cookieParam := route.Operation.Parameters.GetByInAndName("cookie", "my-cookie") + t.Logf("%#v", cookieParam.Examples["example"].Value) + require.Equal(t, "my description", cookieParam.Description) + require.Equal(t, true, cookieParam.Required) + require.Equal(t, "my-example", cookieParam.Examples["example"].Value.Value) }) } diff --git a/server.go b/server.go index e82f04c2..b7218f97 100644 --- a/server.go +++ b/server.go @@ -146,14 +146,23 @@ func NewServer(options ...func(*Server)) *Server { s.startTime = time.Now() if s.autoAuth.Enabled { - Post(s, "/auth/login", s.Security.LoginHandler(s.autoAuth.VerifyUserInfo)).Tags("Auth").Summary("Login") - PostStd(s, "/auth/logout", s.Security.CookieLogoutHandler).Tags("Auth").Summary("Logout") + Post(s, "/auth/login", s.Security.LoginHandler(s.autoAuth.VerifyUserInfo), + OptionTags("Auth"), + OptionSummary("Login"), + ) + PostStd(s, "/auth/logout", s.Security.CookieLogoutHandler, + OptionTags("Auth"), + OptionSummary("Logout"), + ) s.middlewares = []func(http.Handler) http.Handler{ s.Security.TokenToContext(TokenFromCookie, TokenFromHeader), } - PostStd(s, "/auth/refresh", s.Security.RefreshHandler).Tags("Auth").Summary("Refresh token") + PostStd(s, "/auth/refresh", s.Security.RefreshHandler, + OptionTags("Auth"), + OptionSummary("Refresh"), + ) } return s From 5b9f9b320ebd5be8a5fa56e6274d0fb4f61b17fa Mon Sep 17 00:00:00 2001 From: EwenQuim Date: Fri, 6 Dec 2024 15:15:32 +0100 Subject: [PATCH 031/138] Remove deprecated params and add option to replace error if already set --- mux.go | 4 ++-- openapi.go | 2 +- openapi_operations.go | 23 ++++++++++------------- openapi_operations_test.go | 16 +++++++++------- option.go | 8 +++++++- server.go | 12 +++++++++--- 6 files changed, 38 insertions(+), 27 deletions(-) diff --git a/mux.go b/mux.go index b6f04a73..b366564b 100644 --- a/mux.go +++ b/mux.go @@ -24,7 +24,7 @@ import ( // return ans{Ans: "users"}, nil // }) // s.Run() -func Group(s *Server, path string, options ...func(*BaseRoute)) *Server { +func Group(s *Server, path string, routeOptions ...func(*BaseRoute)) *Server { if path == "/" { path = "" } else if path != "" && path[len(path)-1] == '/' { @@ -44,7 +44,7 @@ func Group(s *Server, path string, options ...func(*BaseRoute)) *Server { Params: make(map[string]OpenAPIParam), Operation: openapi3.NewOperation(), } - for _, option := range options { + for _, option := range routeOptions { option(&baseRoute) } diff --git a/openapi.go b/openapi.go index e8c260e3..8a88123b 100644 --- a/openapi.go +++ b/openapi.go @@ -182,7 +182,7 @@ func RegisterOpenAPIOperation[T, B any](s *Server, route Route[T, B]) (*openapi3 // Response - globals for _, openAPIGlobalResponse := range s.globalOpenAPIResponses { - addResponse(s, route.Operation, openAPIGlobalResponse.Code, openAPIGlobalResponse.Description, openAPIGlobalResponse.ErrorType) + addResponseIfNotSet(s, route.Operation, openAPIGlobalResponse.Code, openAPIGlobalResponse.Description, openAPIGlobalResponse.ErrorType) } // Automatically add non-declared 200 Response diff --git a/openapi_operations.go b/openapi_operations.go index d259a588..d182bec5 100644 --- a/openapi_operations.go +++ b/openapi_operations.go @@ -1,6 +1,8 @@ package fuego import ( + "strconv" + "github.com/getkin/kin-openapi/openapi3" ) @@ -52,15 +54,8 @@ func (r Route[ResponseBody, RequestBody]) Param(paramType ParamType, name, descr return r } -// AddError adds an error to the route. -// -// Deprecated: Use `option.AddError` from github.com/go-fuego/fuego/option instead. -func (r Route[ResponseBody, RequestBody]) AddError(code int, description string, errorType ...any) Route[ResponseBody, RequestBody] { - addResponse(r.mainRouter, r.Operation, code, description, errorType...) - return r -} - -func addResponse(s *Server, operation *openapi3.Operation, code int, description string, errorType ...any) { +// Registers a response for the route, only if error for this code is not already set. +func addResponseIfNotSet(s *Server, operation *openapi3.Operation, code int, description string, errorType ...any) { var responseSchema SchemaTag if len(errorType) > 0 { @@ -70,11 +65,13 @@ func addResponse(s *Server, operation *openapi3.Operation, code int, description } content := openapi3.NewContentWithSchemaRef(&responseSchema.SchemaRef, []string{"application/json"}) - response := openapi3.NewResponse(). - WithDescription(description). - WithContent(content) + if operation.Responses.Value(strconv.Itoa(code)) == nil { + response := openapi3.NewResponse(). + WithDescription(description). + WithContent(content) - operation.AddResponse(code, response) + operation.AddResponse(code, response) + } } // openAPIError describes a response error in the OpenAPI spec. diff --git a/openapi_operations_test.go b/openapi_operations_test.go index 9b59a532..c03e129f 100644 --- a/openapi_operations_test.go +++ b/openapi_operations_test.go @@ -54,8 +54,9 @@ func TestCustomError(t *testing.T) { Message string } s := NewServer() - route := Get(s, "/test", testController). - AddError(400, "My Validation Error", MyError{}) + route := Get(s, "/test", testController, + OptionAddError(400, "My Validation Error", MyError{}), + ) require.Equal(t, "My Validation Error", *route.Operation.Responses.Map()["400"].Value.Description) } @@ -74,12 +75,13 @@ func TestCustomErrorGlobalAndOnRoute(t *testing.T) { } routeGlobal := Get(s, "/test-global", testController) - routeCustom := Get(s, "/test-custom", testController). - AddError(400, "My Local Error", MyLocalError{}). - AddError(419, "My Local Teapot") + routeCustom := Get(s, "/test-custom", testController, + OptionAddError(400, "My Local Error", MyLocalError{}), + OptionAddError(419, "My Local Teapot"), + ) - require.Equal(t, "My Global Error", *routeGlobal.Operation.Responses.Map()["400"].Value.Description, "Overrides Fuego's default 400 error") - require.Equal(t, "Another Global Error", *routeGlobal.Operation.Responses.Map()["501"].Value.Description) + require.Equal(t, "My Global Error", *routeGlobal.Operation.Responses.Value("400").Value.Description, "Overrides Fuego's default 400 error") + require.Equal(t, "Another Global Error", *routeGlobal.Operation.Responses.Value("501").Value.Description) require.Equal(t, "My Local Error", *routeCustom.Operation.Responses.Map()["400"].Value.Description, "Local error overrides global error") require.Equal(t, "My Local Teapot", *routeCustom.Operation.Responses.Map()["419"].Value.Description) diff --git a/option.go b/option.go index 50b9f65a..5cdcda36 100644 --- a/option.go +++ b/option.go @@ -3,6 +3,7 @@ package fuego import ( "fmt" "net/http" + "strconv" "github.com/getkin/kin-openapi/openapi3" ) @@ -231,6 +232,7 @@ func OptionDeprecated() func(*BaseRoute) { } // AddError adds an error to the route. +// It replaces any existing error previously set with the same code. // Required: should only supply one type to `errorType` func OptionAddError(code int, description string, errorType ...any) func(*BaseRoute) { var responseSchema SchemaTag @@ -249,7 +251,11 @@ func OptionAddError(code int, description string, errorType ...any) func(*BaseRo response := openapi3.NewResponse(). WithDescription(description). WithContent(content) - r.Operation.AddResponse(code, response) + + if r.Operation.Responses == nil { + r.Operation.Responses = openapi3.NewResponses() + } + r.Operation.Responses.Set(strconv.Itoa(code), &openapi3.ResponseRef{Value: response}) } } diff --git a/server.go b/server.go index b7218f97..12538463 100644 --- a/server.go +++ b/server.go @@ -124,17 +124,23 @@ func NewServer(options ...func(*Server)) *Server { Security: NewSecurity(), } + // Default options that can be overridden defaultOptions := [...]func(*Server){ WithAddr("localhost:9999"), WithDisallowUnknownFields(true), WithSerializer(Send), WithErrorSerializer(SendError), WithErrorHandler(ErrorHandler), + } + options = append(defaultOptions[:], options...) + + // Options set if not provided + options = append(options, WithGlobalResponseTypes(http.StatusBadRequest, "Bad Request _(validation or deserialization error)_", HTTPError{}), WithGlobalResponseTypes(http.StatusInternalServerError, "Internal Server Error _(panics)_", HTTPError{}), - } + ) - for _, option := range append(defaultOptions[:], options...) { + for _, option := range options { option(s) } @@ -203,7 +209,7 @@ func WithCorsMiddleware(corsMiddleware func(http.Handler) http.Handler) func(*Se } // WithGlobalResponseTypes adds default response types to the server. -// useful for adding global error types. +// Useful for adding global error types. // For example: // // app := fuego.NewServer( From fb36fa01c2865fb173a49a0c6efd15a39a25b806 Mon Sep 17 00:00:00 2001 From: EwenQuim Date: Fri, 6 Dec 2024 16:25:17 +0100 Subject: [PATCH 032/138] Refactored route option inheritance --- .../lib/testdata/doc/openapi.golden.json | 57 ++++--- mux.go | 31 +--- mux_test.go | 82 +++++----- openapi.go | 13 -- openapi_test.go | 2 +- option.go | 14 +- option/option.go | 8 + server.go | 92 +---------- server_test.go | 147 ++++-------------- 9 files changed, 136 insertions(+), 310 deletions(-) diff --git a/examples/petstore/lib/testdata/doc/openapi.golden.json b/examples/petstore/lib/testdata/doc/openapi.golden.json index 7f63affa..9d72d6d7 100644 --- a/examples/petstore/lib/testdata/doc/openapi.golden.json +++ b/examples/petstore/lib/testdata/doc/openapi.golden.json @@ -162,6 +162,14 @@ "type": "string" } }, + { + "description": "header description", + "in": "header", + "name": "X-Header", + "schema": { + "type": "string" + } + }, { "description": "Number of items per page", "in": "query", @@ -213,14 +221,6 @@ "default": 3, "type": "integer" } - }, - { - "description": "header description", - "in": "header", - "name": "X-Header", - "schema": { - "type": "string" - } } ], "responses": { @@ -373,6 +373,14 @@ "type": "string" } }, + { + "description": "header description", + "in": "header", + "name": "X-Header", + "schema": { + "type": "string" + } + }, { "description": "Number of items per page", "in": "query", @@ -401,14 +409,6 @@ "default": 1, "type": "integer" } - }, - { - "description": "header description", - "in": "header", - "name": "X-Header", - "schema": { - "type": "string" - } } ], "responses": { @@ -459,8 +459,8 @@ }, "summary": "get all pets", "tags": [ - "my-tag", - "pets" + "pets", + "my-tag" ] } }, @@ -704,6 +704,14 @@ "type": "string" } }, + { + "description": "header description", + "in": "header", + "name": "X-Header", + "schema": { + "type": "string" + } + }, { "description": "Pet ID", "examples": { @@ -717,14 +725,6 @@ "schema": { "type": "string" } - }, - { - "description": "header description", - "in": "header", - "name": "X-Header", - "schema": { - "type": "string" - } } ], "responses": { @@ -949,10 +949,5 @@ "description": "local server", "url": "http://localhost:9999" } - ], - "tags": [ - { - "name": "pets" - } ] } \ No newline at end of file diff --git a/mux.go b/mux.go index b366564b..b07c8e21 100644 --- a/mux.go +++ b/mux.go @@ -34,28 +34,13 @@ func Group(s *Server, path string, routeOptions ...func(*BaseRoute)) *Server { ss := *s newServer := &ss newServer.basePath += path - newServer.groupTag = strings.TrimLeft(path, "/") - if newServer.groupTag != "" { - s.OpenApiSpec.Tags = append(s.OpenApiSpec.Tags, &openapi3.Tag{Name: newServer.groupTag}) + + if !s.disableAutoGroupTags { + newServer.routeOptions = append(s.routeOptions, OptionTags(strings.TrimLeft(path, "/"))) } newServer.mainRouter = s - baseRoute := BaseRoute{ - Params: make(map[string]OpenAPIParam), - Operation: openapi3.NewOperation(), - } - for _, option := range routeOptions { - option(&baseRoute) - } - - // Copy the params from the parent server, and add the new ones - newServer.params = make(map[string]OpenAPIParam, len(baseRoute.Params)) - for k, v := range s.params { - newServer.params[k] = v - } - for k, v := range baseRoute.Params { - newServer.params[k] = v - } + newServer.routeOptions = append(newServer.routeOptions, routeOptions...) return newServer } @@ -202,19 +187,17 @@ func registerFuegoController[T, B any, Contexted ctx[B]](s *Server, method, path mainRouter: s.mainRouter, } // Copy the params from the server/group, and add the route ones - for k, v := range s.params { - route.Params[k] = v - } if route.mainRouter == nil { route.mainRouter = s } + route.AcceptedContentTypes = route.mainRouter.acceptedContentTypes acceptHeaderParameter := openapi3.NewHeaderParameter("Accept") acceptHeaderParameter.Schema = openapi3.NewStringSchema().NewRef() route.Operation.AddParameter(acceptHeaderParameter) - for _, o := range options { + for _, o := range append(s.routeOptions, options...) { o(&route) } @@ -229,7 +212,7 @@ func registerStdController(s *Server, method, path string, controller func(http. Operation: openapi3.NewOperation(), } - for _, o := range options { + for _, o := range append(s.routeOptions, options...) { o(&route) } diff --git a/mux_test.go b/mux_test.go index 9cf6d5c3..9f13693c 100644 --- a/mux_test.go +++ b/mux_test.go @@ -435,17 +435,19 @@ func TestGroupInheritance(t *testing.T) { return "test", nil }) - t.Log(route.Params) - require.Len(t, route.Params, 2) - require.Contains(t, route.Params, "Header-1") - require.Contains(t, route.Params, "Header-2") + require.Equal(t, 3, len(route.Operation.Parameters)) + require.NotNil(t, route.Operation.Parameters.GetByInAndName("header", "Header-1")) + require.NotNil(t, route.Operation.Parameters.GetByInAndName("header", "Header-2")) + require.NotNil(t, route.Operation.Parameters.GetByInAndName("header", "Accept")) + require.Nil(t, route.Operation.Parameters.GetByInAndName("header", "Not-exists")) }) } func TestGroupTagsOnRoute(t *testing.T) { t.Run("route tag inheritance", func(t *testing.T) { - s := NewServer(). - Tags("my-server-tag") + s := NewServer( + WithRouteOptions(OptionTags("my-server-tag")), + ) route := Get(s, "/path", func(ctx *ContextNoBody) (string, error) { return "test", nil }) @@ -453,8 +455,9 @@ func TestGroupTagsOnRoute(t *testing.T) { }) t.Run("route tag add", func(t *testing.T) { - s := NewServer(). - Tags("my-server-tag") + s := NewServer( + WithRouteOptions(OptionTags("my-server-tag")), + ) route := Get(s, "/path", func(ctx *ContextNoBody) (string, error) { return "test", nil @@ -462,7 +465,7 @@ func TestGroupTagsOnRoute(t *testing.T) { OptionTags("my-route-tag"), ) - require.Equal(t, []string{"my-route-tag", "my-server-tag"}, route.Operation.Tags) + require.Equal(t, []string{"my-server-tag", "my-route-tag"}, route.Operation.Tags) }) } @@ -691,45 +694,50 @@ func TestGroup(t *testing.T) { func TestGroupTags(t *testing.T) { t.Run("inherit tags", func(t *testing.T) { - s := NewServer(). - Tags("my-server-tag") + s := NewServer( + WithRouteOptions(OptionTags("my-server-tag")), + ) group := Group(s, "/slash") + route := Get(group, "/test", dummyController) - require.Equal(t, []string{"my-server-tag"}, group.tags) + require.Equal(t, []string{"my-server-tag", "slash"}, route.Operation.Tags) }) t.Run("override parent tags", func(t *testing.T) { - s := NewServer(). - Tags("my-server-tag") - group := Group(s, "/slash"). - Tags("my-group-tag") + s := NewServer( + WithRouteOptions(OptionTags("my-server-tag")), + ) + group := Group(s, "/slash", + OptionTags("my-group-tag"), + ) + route := Get(group, "/test", dummyController) - require.Equal(t, []string{"my-group-tag"}, group.tags) + require.Equal(t, []string{"my-server-tag", "slash", "my-group-tag"}, route.Operation.Tags) }) t.Run("add child group tag", func(t *testing.T) { - s := NewServer(). - Tags("my-server-tag") - group := Group(s, "/slash"). - AddTags("my-group-tag") + s := NewServer( + WithRouteOptions(OptionTags("my-server-tag")), + ) + group := Group(s, "/slash", + OptionTags("my-group-tag"), + ) + route := Get(group, "/test", dummyController) - require.Equal(t, []string{"my-server-tag", "my-group-tag"}, group.tags) + require.Equal(t, []string{"my-server-tag", "slash", "my-group-tag"}, route.Operation.Tags) }) - t.Run("remove server tag", func(t *testing.T) { - s := NewServer(). - Tags("my-server-tag", "my-other-server-tag") - group := Group(s, "/slash"). - RemoveTags("my-server-tag") - require.Equal(t, []string{"my-other-server-tag"}, group.tags) - }) t.Run("multiple groups inheritance", func(t *testing.T) { - s := NewServer(). - Tags("my-server-tag") - group := Group(s, "/slash"). - AddTags("my-group-tag") - childGroup := Group(group, "/slash"). - AddTags("my-childGroup-tag") - - require.Equal(t, []string{"my-server-tag", "my-group-tag", "my-childGroup-tag"}, childGroup.tags) + s := NewServer( + WithRouteOptions(OptionTags("my-server-tag")), + ) + group := Group(s, "/slash", + OptionTags("my-group-tag"), + ) + childGroup := Group(group, "/slash", + OptionTags("my-childGroup-tag"), + ) + route := Get(childGroup, "/test", dummyController) + + require.Equal(t, []string{"my-server-tag", "slash", "my-group-tag", "slash", "my-childGroup-tag"}, route.Operation.Tags) }) } diff --git a/openapi.go b/openapi.go index 8a88123b..516d5f86 100644 --- a/openapi.go +++ b/openapi.go @@ -153,19 +153,6 @@ func RegisterOpenAPIOperation[T, B any](s *Server, route Route[T, B]) (*openapi3 route.Operation = openapi3.NewOperation() } - if s.tags != nil { - route.Operation.Tags = append(route.Operation.Tags, s.tags...) - } - - // Tags - if !s.disableAutoGroupTags && s.groupTag != "" { - route.Operation.Tags = append(route.Operation.Tags, s.groupTag) - } - - for _, param := range s.params { - route.Param(param.Type, param.Name, param.Description, param.OpenAPIParamOption) - } - // Request Body if route.Operation.RequestBody == nil { bodyTag := SchemaTagFromType(s, *new(B)) diff --git a/openapi_test.go b/openapi_test.go index 3828a875..89667f92 100644 --- a/openapi_test.go +++ b/openapi_test.go @@ -453,7 +453,7 @@ func TestAutoGroupTags(t *testing.T) { require.NotNil(t, document) require.Nil(t, document.Paths.Find("/a").Get.Tags) require.Equal(t, []string{"group"}, document.Paths.Find("/group/b").Get.Tags) - require.Equal(t, []string{"subgroup"}, document.Paths.Find("/group/subgroup/c").Get.Tags) + require.Equal(t, []string{"group", "subgroup"}, document.Paths.Find("/group/subgroup/c").Get.Tags) require.Equal(t, []string{"other"}, document.Paths.Find("/other/d").Get.Tags) } diff --git a/option.go b/option.go index 5cdcda36..dfa0cf85 100644 --- a/option.go +++ b/option.go @@ -210,13 +210,25 @@ func OptionSummary(summary string) func(*BaseRoute) { } } -// Description adds a description to the route. +// Description sets the description to the route. +// By default, the description is set by Fuego with some info, +// like the controller function name and the package name. +// If you want to add a description, please use [AddDescription] instead. func OptionDescription(description string) func(*BaseRoute) { return func(r *BaseRoute) { r.Operation.Description = description } } +// Description appends a description to the route. +// By default, the description is set by Fuego with some info, +// like the controller function name and the package name. +func OptionAddDescription(description string) func(*BaseRoute) { + return func(r *BaseRoute) { + r.Operation.Description += description + } +} + // OperationID adds an operation ID to the route. func OptionOperationID(operationID string) func(*BaseRoute) { return func(r *BaseRoute) { diff --git a/option/option.go b/option/option.go index 403f5609..fcaebaff 100644 --- a/option/option.go +++ b/option/option.go @@ -85,8 +85,16 @@ var Tags = fuego.OptionTags var Summary = fuego.OptionSummary // Description adds a description to the route. +// By default, the description is set by Fuego with some info, +// like the controller function name and the package name. +// If you want to add a description, please use [AddDescription] instead. var Description = fuego.OptionDescription +// AddDescription adds a description to the route. +// By default, the description is set by Fuego with some info, +// like the controller function name and the package name. +var AddDescription = fuego.OptionAddDescription + // Security configures security requirements to the route. // // Single Scheme (AND Logic): diff --git a/server.go b/server.go index 12538463..6daba7ee 100644 --- a/server.go +++ b/server.go @@ -8,7 +8,6 @@ import ( "log/slog" "net/http" "os" - "slices" "time" "github.com/getkin/kin-openapi/openapi3" @@ -49,18 +48,14 @@ type Server struct { // For example, it allows OPTIONS /foo even if it is not declared (only GET /foo is declared). corsMiddleware func(http.Handler) http.Handler - // OpenAPI documentation tags used for logical groupings of operations - // These tags will be inherited by child Routes/Groups - tags []string - - // OpenAPI documentation parameters used for all server routes - params map[string]OpenAPIParam + // routeOptions is used to store the options + // that will be applied of the route. + routeOptions []func(*BaseRoute) middlewares []func(http.Handler) http.Handler disableStartupMessages bool disableAutoGroupTags bool - groupTag string mainRouter *Server // Ref to the main router (used for groups) basePath string // Base path of the group @@ -119,8 +114,6 @@ func NewServer(options ...func(*Server)) *Server { openapi3gen.UseAllExportedFields(), ), - params: make(map[string]OpenAPIParam), - Security: NewSecurity(), } @@ -452,83 +445,6 @@ func WithValidator(newValidator *validator.Validate) func(*Server) { func WithRouteOptions(options ...func(*BaseRoute)) func(*Server) { return func(s *Server) { - baseRoute := &BaseRoute{ - Params: make(map[string]OpenAPIParam), - Operation: openapi3.NewOperation(), - } - for _, option := range options { - option(baseRoute) - } - s.params = baseRoute.Params - } -} - -// Replaces Tags for the Server (i.e Group) -// By default, the tag is the type of the response body. -func (s *Server) Tags(tags ...string) *Server { - s.tags = tags - return s -} - -// AddTags adds tags from the Server (i.e Group) -// Tags from the parent Groups will be respected -func (s *Server) AddTags(tags ...string) *Server { - s.tags = append(s.tags, tags...) - return s -} - -// RemoveTags removes tags from the Server (i.e Group) -// if the parent Group(s) has matching tags they will be removed -func (s *Server) RemoveTags(tags ...string) *Server { - for _, tag := range tags { - for i, t := range s.tags { - if t == tag { - s.tags = slices.Delete(s.tags, i, i+1) - break - } - } + s.routeOptions = append(s.routeOptions, options...) } - return s -} - -// Registers a param for all server routes. -func (s *Server) Param(name, description string, params ...OpenAPIParamOption) *Server { - param := OpenAPIParam{Name: name, Description: description} - - for _, p := range params { - if p.Required { - param.Required = p.Required - } - if p.Example != "" { - param.Example = p.Example - } - if p.Type != "" { - param.Type = p.Type - } - } - - if s.params == nil { - s.params = make(map[string]OpenAPIParam) - } - s.params[name] = param - - return s -} - -// Registers a header param for all server routes. -func (s *Server) Header(name, description string, params ...OpenAPIParamOption) *Server { - s.Param(name, description, append(params, OpenAPIParamOption{Type: HeaderParamType})...) - return s -} - -// Registers a cookie param for all server routes. -func (s *Server) Cookie(name, description string, params ...OpenAPIParamOption) *Server { - s.Param(name, description, append(params, OpenAPIParamOption{Type: CookieParamType})...) - return s -} - -// Registers a query param for all server routes. -func (s *Server) Query(name, description string, params ...OpenAPIParamOption) *Server { - s.Param(name, description, append(params, OpenAPIParamOption{Type: QueryParamType})...) - return s } diff --git a/server_test.go b/server_test.go index e3e43355..51d75764 100644 --- a/server_test.go +++ b/server_test.go @@ -300,82 +300,6 @@ func TestWithoutAutoGroupTags(t *testing.T) { require.Nil(t, document.Paths.Find("/api/test").Get.Tags) } -func TestServerTags(t *testing.T) { - t.Run("set tags", func(t *testing.T) { - s := NewServer(). - Tags("my-server-tag") - - require.Equal(t, s.tags, []string{"my-server-tag"}) - }) - - t.Run("add tags", func(t *testing.T) { - s := NewServer(). - AddTags("my-server-tag"). - AddTags("my-other-server-tag") - - require.Equal(t, s.tags, []string{"my-server-tag", "my-other-server-tag"}) - }) - - t.Run("remove tags", func(t *testing.T) { - s := NewServer(). - Tags("my-server-tag"). - AddTags("my-other-server-tag"). - RemoveTags("my-other-server-tag") - - require.Equal(t, s.tags, []string{"my-server-tag"}) - }) - - t.Run("inherit tags from group, replace", func(t *testing.T) { - s := NewServer(). - Tags("my-server-tag") - - group := Group(s, "/api"). - Tags("my-group-tag") - - require.Equal(t, group.tags, []string{"my-group-tag"}) - - subGroup := Group(group, "/users"). - Tags("my-sub-group-tag") - - require.Equal(t, subGroup.tags, []string{"my-sub-group-tag"}) - }) - - t.Run("inherit tags from group, add", func(t *testing.T) { - s := NewServer(). - Tags("my-server-tag") - - group := Group(s, "/api"). - AddTags("my-group-tag") - - require.Equal(t, group.tags, []string{"my-server-tag", "my-group-tag"}) - - subGroup := Group(group, "/users"). - AddTags("my-sub-group-tag") - - require.Equal(t, subGroup.tags, []string{"my-server-tag", "my-group-tag", "my-sub-group-tag"}) - }) - - t.Run("inherit tags from group, remove", func(t *testing.T) { - s := NewServer(). - Tags("my-server-tag") - - group := Group(s, "/api"). - AddTags("my-group-tag") - - require.Equal(t, group.tags, []string{"my-server-tag", "my-group-tag"}) - - siblingGroup := Group(s, "/api2"). - AddTags("my-sibling-group-tag") - - require.Equal(t, siblingGroup.tags, []string{"my-server-tag", "my-sibling-group-tag"}) - - subGroup := Group(group, "/users"). - RemoveTags("my-group-tag") - - require.Equal(t, subGroup.tags, []string{"my-server-tag"}) - }) -} - type ReqBody struct { A string B int @@ -438,15 +362,17 @@ func TestCustomSerialization(t *testing.T) { func TestGroupParams(t *testing.T) { s := NewServer() - group := Group(s, "/api").Param("X-Test-Header", "test-value", OpenAPIParamOption{Example: "example", Required: true}) + group := Group(s, "/api", + OptionHeader("X-Test-Header", "test-value", ParamRequired(), ParamExample("example", "example")), + ) Get(s, "/", controller) Get(group, "/test", controller) - Get(group, "/test2", controller) + route := Get(group, "/test2", controller) - require.Equal(t, group.params, map[string]OpenAPIParam{ - "X-Test-Header": {Name: "X-Test-Header", Description: "test-value", OpenAPIParamOption: OpenAPIParamOption{Required: true, Example: "example", Type: ""}}, - }) + require.Equal(t, "test-value", route.Operation.Parameters.GetByInAndName("header", "X-Test-Header").Description) + require.Equal(t, true, route.Operation.Parameters.GetByInAndName("header", "X-Test-Header").Required) + require.Equal(t, "example", route.Operation.Parameters.GetByInAndName("header", "X-Test-Header").Examples["example"].Value.Value) document := s.OutputOpenAPISpec() t.Log(document.Paths.Find("/").Get.Parameters[0].Value.Name) @@ -464,9 +390,9 @@ func TestGroupHeaderParams(t *testing.T) { OptionHeader("X-Test-Header", "test-value"), ) - Get(group, "/test", controller) + route := Get(group, "/test", controller) - require.Equal(t, map[string]OpenAPIParam{"X-Test-Header": {Name: "X-Test-Header", Description: "test-value", OpenAPIParamOption: OpenAPIParamOption{Required: false, Example: "", Type: HeaderParamType}}}, group.params) + require.Equal(t, "test-value", route.Operation.Parameters.GetByInAndName("header", "X-Test-Header").Description) document := s.OutputOpenAPISpec() require.Equal(t, document.Paths.Find("/api/test").Get.Parameters[0].Value.Name, "Accept") @@ -479,9 +405,9 @@ func TestGroupCookieParams(t *testing.T) { OptionCookie("X-Test-Cookie", "test-value"), ) - Get(group, "/test", controller) + route := Get(group, "/test", controller) - require.Equal(t, group.params, map[string]OpenAPIParam{"X-Test-Cookie": {Name: "X-Test-Cookie", Description: "test-value", OpenAPIParamOption: OpenAPIParamOption{Required: false, Example: "", Type: CookieParamType}}}) + require.Equal(t, "test-value", route.Operation.Parameters.GetByInAndName("cookie", "X-Test-Cookie").Description) document := s.OutputOpenAPISpec() require.Equal(t, document.Paths.Find("/api/test").Get.Parameters[0].Value.Name, "Accept") @@ -494,15 +420,9 @@ func TestGroupQueryParam(t *testing.T) { OptionQuery("X-Test-Query", "test-value"), ) - Get(group, "/test", controller) + route := Get(group, "/test", controller) - require.Equal(t, map[string]OpenAPIParam{ - "X-Test-Query": { - Name: "X-Test-Query", - Description: "test-value", - OpenAPIParamOption: OpenAPIParamOption{Required: false, Example: "", Type: QueryParamType, GoType: "string"}, - }, - }, group.params) + require.Equal(t, "test-value", route.Operation.Parameters.GetByInAndName("query", "X-Test-Query").Description) document := s.OutputOpenAPISpec() require.Equal(t, document.Paths.Find("/api/test").Get.Parameters[0].Value.Name, "Accept") @@ -512,59 +432,56 @@ func TestGroupQueryParam(t *testing.T) { func TestGroupParamsInChildGroup(t *testing.T) { s := NewServer() group := Group(s, "/api", - OptionParam("X-Test-Header", ParamDescription("test-value")), + OptionHeader("X-Test-Header", "test-value"), ) subGroup := Group(group, "/users") - expectedParams := map[string]OpenAPIParam{ - "X-Test-Header": { - Name: "X-Test-Header", - Description: "test-value", - OpenAPIParamOption: OpenAPIParamOption{Required: false, Example: "", Type: ""}, - }, - } - require.Equal(t, expectedParams, group.params) - require.Equal(t, expectedParams, subGroup.params) + route := Get(subGroup, "/test", controller) + + require.Equal(t, "test-value", route.Operation.Parameters.GetByInAndName("header", "X-Test-Header").Description) } func TestGroupParamsNotInParentGroup(t *testing.T) { s := NewServer() parentGroup := Group(s, "/api") group := Group(parentGroup, "/users", - OptionParam("X-Test-Header", ParamDescription("test-value")), + OptionHeader("X-Test-Header", "test-value"), ) + route := Get(group, "/test", controller) - expectedParams := map[string]OpenAPIParam{"X-Test-Header": {Name: "X-Test-Header", Description: "test-value", OpenAPIParamOption: OpenAPIParamOption{Required: false, Example: "", Type: ""}}} - require.Equal(t, map[string]OpenAPIParam{}, parentGroup.params) - require.Equal(t, expectedParams, group.params) + require.Equal(t, "test-value", route.Operation.Parameters.GetByInAndName("header", "X-Test-Header").Description) } func TestGroupParamsNotInSiblingGroup(t *testing.T) { s := NewServer() - group := Group(s, "/api", OptionParam("X-Test-Header", ParamDescription("test-value"))) + group := Group(s, "/api", OptionHeader("X-Test-Header", "test-value")) siblingGroup := Group(s, "/api2") + route1 := Get(group, "/test", controller) + route2 := Get(siblingGroup, "/test", controller) - expectedParams := map[string]OpenAPIParam{"X-Test-Header": {Name: "X-Test-Header", Description: "test-value", OpenAPIParamOption: OpenAPIParamOption{Required: false, Example: "", Type: ""}}} - require.Equal(t, expectedParams, group.params) - require.Equal(t, map[string]OpenAPIParam{}, siblingGroup.params) + require.Equal(t, "test-value", route1.Operation.Parameters.GetByInAndName("header", "X-Test-Header").Description) + require.Nil(t, route2.Operation.Parameters.GetByInAndName("header", "X-Test-Header")) } func TestGroupParamsInMainServerInstance(t *testing.T) { s := NewServer( WithRouteOptions( - OptionParam("X-Test-Header", ParamDescription("test-value")), + OptionHeader("X-Test-Header", "test-value"), ), ) - expectedParams := map[string]OpenAPIParam{"X-Test-Header": {Name: "X-Test-Header", Description: "test-value", OpenAPIParamOption: OpenAPIParamOption{Required: false, Example: "", Type: ""}}} - require.Equal(t, expectedParams, s.params) + route := Get(s, "/test", controller) + + require.Equal(t, "test-value", route.Operation.Parameters.GetByInAndName("header", "X-Test-Header").Description) + // expectedParams := map[string]OpenAPIParam{"X-Test-Header": {Name: "X-Test-Header", Description: "test-value", OpenAPIParamOption: OpenAPIParamOption{Required: false, Example: "", Type: ""}}} + // require.Equal(t, expectedParams, route.Params) } func TestHideGroupAfterGroupParam(t *testing.T) { s := NewServer() group := Group(s, "/api", - OptionParam("X-Test-Header", ParamDescription("test-value")), + OptionHeader("X-Test-Header", "test-value"), ).Hide() Get(group, "/test", controller) From 973e6fc5bea45dacb8f04072ce8cf2d48e17bd4a Mon Sep 17 00:00:00 2001 From: EwenQuim Date: Fri, 6 Dec 2024 17:19:13 +0100 Subject: [PATCH 033/138] Added documentation --- documentation/docs/guides/openapi.md | 48 +++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/documentation/docs/guides/openapi.md b/documentation/docs/guides/openapi.md index d81c4595..bea7eec2 100644 --- a/documentation/docs/guides/openapi.md +++ b/documentation/docs/guides/openapi.md @@ -29,7 +29,7 @@ Result for this simple example at [http://localhost:9999/swagger/index.html](htt The core idea of Fuego is to generate the OpenAPI specification automatically, so you don't have to worry about it. However, you can customize it if you want. -## Operations +## Route Options Each route can be customized to add more information to the OpenAPI specification. @@ -63,6 +63,52 @@ func helloWorld(c fuego.ContextNoBody) (string, error) { } ``` +## Group Options, Options Groups & Custom Options + +You can also customize the OpenAPI specification for a group of routes. + +```go +package main + +import ( + "github.com/go-fuego/fuego" + "github.com/go-fuego/fuego/option" +) + +// Define a reusable group of options +var optionPagination = option.Group( + option.QueryInt("page", "Page number", param.Default(1)), + option.QueryInt("limit", "Items per page", param.Default(10)), +) + +// Custom options for the group +var customOption = func(r *fuego.BaseRoute) { + r.XXX = YYY // Direct access to the route struct to inject custom behavior +} + +func main() { + s := fuego.NewServer() + + api := fuego.Group(s, "/users", + option.Summary("Users routes"), + option.Description("Default description for all Users routes"), + option.Tags("users"), + ) + + fuego.Get(api, "/", helloWorld, + optionPagination, + customOption, + option.Summary("A simple hello world"), // Replace the default summary + ) + + s.Run() +} + +func helloWorld(c fuego.ContextNoBody) (string, error) { + return "Hello, World!", nil +} +``` + ## Output Fuego automatically provides an OpenAPI specification for your API in several ways: From c79047944ee9b1926401cd9945ed9d4fc80b3d5d Mon Sep 17 00:00:00 2001 From: EwenQuim Date: Fri, 6 Dec 2024 19:38:34 +0100 Subject: [PATCH 034/138] Declare all tags used in operations in the OpenAPI spec --- .../lib/testdata/doc/openapi.golden.json | 8 ++++++++ openapi.go | 16 ++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/examples/petstore/lib/testdata/doc/openapi.golden.json b/examples/petstore/lib/testdata/doc/openapi.golden.json index 9d72d6d7..56c957a1 100644 --- a/examples/petstore/lib/testdata/doc/openapi.golden.json +++ b/examples/petstore/lib/testdata/doc/openapi.golden.json @@ -949,5 +949,13 @@ "description": "local server", "url": "http://localhost:9999" } + ], + "tags": [ + { + "name": "pets" + }, + { + "name": "my-tag" + } ] } \ No newline at end of file diff --git a/openapi.go b/openapi.go index 516d5f86..25cf8fbb 100644 --- a/openapi.go +++ b/openapi.go @@ -52,10 +52,26 @@ func (s *Server) Show() *Server { return s } +func declareAllTagsFromOperations(s *Server) { + for _, pathItem := range s.OpenApiSpec.Paths.Map() { + for _, op := range pathItem.Operations() { + for _, tag := range op.Tags { + if s.OpenApiSpec.Tags.Get(tag) == nil { + s.OpenApiSpec.Tags = append(s.OpenApiSpec.Tags, &openapi3.Tag{ + Name: tag, + }) + } + } + } + } +} + // OutputOpenAPISpec takes the OpenAPI spec and outputs it to a JSON file and/or serves it on a URL. // Also serves a Swagger UI. // To modify its behavior, use the [WithOpenAPIConfig] option. func (s *Server) OutputOpenAPISpec() openapi3.T { + declareAllTagsFromOperations(s) + // Validate err := s.OpenApiSpec.Validate(context.Background()) if err != nil { From 63cf58a2c2adc2392baf4d2a4a0426d1a00eb706 Mon Sep 17 00:00:00 2001 From: EwenQuim Date: Mon, 9 Dec 2024 09:31:40 +0100 Subject: [PATCH 035/138] Splits the auto-response declaration and response body into two separate steps --- openapi.go | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/openapi.go b/openapi.go index 25cf8fbb..072a719a 100644 --- a/openapi.go +++ b/openapi.go @@ -189,11 +189,18 @@ func RegisterOpenAPIOperation[T, B any](s *Server, route Route[T, B]) (*openapi3 } // Automatically add non-declared 200 Response - if route.Operation.Responses.Value("200") == nil { + response200 := route.Operation.Responses.Value("200") + if response200 == nil { + response := openapi3.NewResponse().WithDescription("OK") + route.Operation.AddResponse(200, response) + response200 = route.Operation.Responses.Value("200") + } + + // Automatically add non-declared Content for 200 Response + if response200.Value.Content == nil { responseSchema := SchemaTagFromType(s, *new(T)) content := openapi3.NewContentWithSchemaRef(&responseSchema.SchemaRef, []string{"application/json", "application/xml"}) - response := openapi3.NewResponse().WithDescription("OK").WithContent(content) - route.Operation.AddResponse(200, response) + response200.Value.WithContent(content) } // Automatically add non-declared Path parameters From 1e6d931908a80d221917894b9b3dfdc222279c88 Mon Sep 17 00:00:00 2001 From: EwenQuim Date: Mon, 9 Dec 2024 15:17:08 +0100 Subject: [PATCH 036/138] AddDescription update and test --- option.go | 2 +- option_test.go | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/option.go b/option.go index dfa0cf85..7f2a72df 100644 --- a/option.go +++ b/option.go @@ -225,7 +225,7 @@ func OptionDescription(description string) func(*BaseRoute) { // like the controller function name and the package name. func OptionAddDescription(description string) func(*BaseRoute) { return func(r *BaseRoute) { - r.Operation.Description += description + r.Operation.Description += "\n\n" + description } } diff --git a/option_test.go b/option_test.go index 21244f84..600d628e 100644 --- a/option_test.go +++ b/option_test.go @@ -682,3 +682,16 @@ func TestSecurity(t *testing.T) { require.Equal(t, []string{"basic"}, security["ApiKey"]) }) } + +func TestOptionAddDescription(t *testing.T) { + t.Run("Declare a description for the route with multiple descriptions", func(t *testing.T) { + s := fuego.NewServer() + + route := fuego.Get(s, "/test", helloWorld, + fuego.OptionDescription("test description"), + fuego.OptionAddDescription("another description"), + ) + + require.Equal(t, "controller: `github.com/go-fuego/fuego_test.helloWorld`\n\n---\n\ntest description\n\nanother description", route.Operation.Description) + }) +} From f79650d89b6906107d72fac37a7edddffe808e3e Mon Sep 17 00:00:00 2001 From: EwenQuim Date: Mon, 9 Dec 2024 15:44:56 +0100 Subject: [PATCH 037/138] Updated all deps --- cmd/fuego/go.mod | 2 +- cmd/fuego/go.sum | 4 ++-- examples/acme-tls/go.mod | 2 +- examples/acme-tls/go.sum | 4 ++-- examples/basic/go.mod | 2 +- examples/basic/go.sum | 4 ++-- examples/custom-serializer/go.mod | 2 +- examples/custom-serializer/go.sum | 4 ++-- examples/full-app-gourmet/go.mod | 6 +++--- examples/generate-opengraph-image/go.mod | 4 ++-- examples/generate-opengraph-image/go.sum | 8 ++++---- examples/hello-world/go.mod | 2 +- examples/hello-world/go.sum | 4 ++-- examples/openapi/go.mod | 2 +- examples/openapi/go.sum | 4 ++-- middleware/basicauth/go.mod | 2 +- middleware/basicauth/go.sum | 4 ++-- 17 files changed, 30 insertions(+), 30 deletions(-) diff --git a/cmd/fuego/go.mod b/cmd/fuego/go.mod index c4e58669..8bdac651 100644 --- a/cmd/fuego/go.mod +++ b/cmd/fuego/go.mod @@ -5,7 +5,7 @@ go 1.22.2 toolchain go1.22.5 require ( - github.com/go-fuego/fuego v0.15.1 + github.com/go-fuego/fuego v0.16.1 github.com/stretchr/testify v1.10.0 github.com/urfave/cli/v2 v2.27.5 golang.org/x/text v0.21.0 diff --git a/cmd/fuego/go.sum b/cmd/fuego/go.sum index 64ae7d5c..b085dd5d 100644 --- a/cmd/fuego/go.sum +++ b/cmd/fuego/go.sum @@ -6,8 +6,8 @@ github.com/gabriel-vasile/mimetype v1.4.7 h1:SKFKl7kD0RiPdbht0s7hFtjl489WcQ1VyPW github.com/gabriel-vasile/mimetype v1.4.7/go.mod h1:GDlAgAyIRT27BhFl53XNAFtfjzOkLaF35JdEG0P7LtU= github.com/getkin/kin-openapi v0.128.0 h1:jqq3D9vC9pPq1dGcOCv7yOp1DaEe7c/T1vzcLbITSp4= github.com/getkin/kin-openapi v0.128.0/go.mod h1:OZrfXzUfGrNbsKj+xmFBx6E5c6yH3At/tAKSc2UszXM= -github.com/go-fuego/fuego v0.15.1 h1:9ESspiRFeUmSl2YdZzL5VE+8F2sGYSTBRkGJEfvoLXc= -github.com/go-fuego/fuego v0.15.1/go.mod h1:XMpAQQnZsoMON0UD6ncvzj6YukGQlNECDcINJt49zx4= +github.com/go-fuego/fuego v0.16.1 h1:G+sDF55BjFI7FH7dd07HDx4jfNPxXEeab+YKuLjj5zY= +github.com/go-fuego/fuego v0.16.1/go.mod h1:ARPlRxY+RgbahF6ZvnjsESGQd3h/jCw8ksCJxKLbgjY= github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= diff --git a/examples/acme-tls/go.mod b/examples/acme-tls/go.mod index 0766be02..9eb714b9 100644 --- a/examples/acme-tls/go.mod +++ b/examples/acme-tls/go.mod @@ -4,7 +4,7 @@ go 1.22.2 require ( github.com/caddyserver/certmagic v0.21.4 - github.com/go-fuego/fuego v0.15.1 + github.com/go-fuego/fuego v0.16.1 ) require ( diff --git a/examples/acme-tls/go.sum b/examples/acme-tls/go.sum index a8f554f3..359b7ea9 100644 --- a/examples/acme-tls/go.sum +++ b/examples/acme-tls/go.sum @@ -8,8 +8,8 @@ github.com/gabriel-vasile/mimetype v1.4.7 h1:SKFKl7kD0RiPdbht0s7hFtjl489WcQ1VyPW github.com/gabriel-vasile/mimetype v1.4.7/go.mod h1:GDlAgAyIRT27BhFl53XNAFtfjzOkLaF35JdEG0P7LtU= github.com/getkin/kin-openapi v0.128.0 h1:jqq3D9vC9pPq1dGcOCv7yOp1DaEe7c/T1vzcLbITSp4= github.com/getkin/kin-openapi v0.128.0/go.mod h1:OZrfXzUfGrNbsKj+xmFBx6E5c6yH3At/tAKSc2UszXM= -github.com/go-fuego/fuego v0.15.1 h1:9ESspiRFeUmSl2YdZzL5VE+8F2sGYSTBRkGJEfvoLXc= -github.com/go-fuego/fuego v0.15.1/go.mod h1:XMpAQQnZsoMON0UD6ncvzj6YukGQlNECDcINJt49zx4= +github.com/go-fuego/fuego v0.16.1 h1:G+sDF55BjFI7FH7dd07HDx4jfNPxXEeab+YKuLjj5zY= +github.com/go-fuego/fuego v0.16.1/go.mod h1:ARPlRxY+RgbahF6ZvnjsESGQd3h/jCw8ksCJxKLbgjY= github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= diff --git a/examples/basic/go.mod b/examples/basic/go.mod index d5b869de..4b57f340 100644 --- a/examples/basic/go.mod +++ b/examples/basic/go.mod @@ -4,7 +4,7 @@ go 1.22.2 require ( github.com/go-chi/chi/v5 v5.1.0 - github.com/go-fuego/fuego v0.15.1 + github.com/go-fuego/fuego v0.16.1 github.com/rs/cors v1.11.1 ) diff --git a/examples/basic/go.sum b/examples/basic/go.sum index 6936a3f1..3b64f69f 100644 --- a/examples/basic/go.sum +++ b/examples/basic/go.sum @@ -6,8 +6,8 @@ github.com/getkin/kin-openapi v0.128.0 h1:jqq3D9vC9pPq1dGcOCv7yOp1DaEe7c/T1vzcLb github.com/getkin/kin-openapi v0.128.0/go.mod h1:OZrfXzUfGrNbsKj+xmFBx6E5c6yH3At/tAKSc2UszXM= github.com/go-chi/chi/v5 v5.1.0 h1:acVI1TYaD+hhedDJ3r54HyA6sExp3HfXq7QWEEY/xMw= github.com/go-chi/chi/v5 v5.1.0/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= -github.com/go-fuego/fuego v0.15.1 h1:9ESspiRFeUmSl2YdZzL5VE+8F2sGYSTBRkGJEfvoLXc= -github.com/go-fuego/fuego v0.15.1/go.mod h1:XMpAQQnZsoMON0UD6ncvzj6YukGQlNECDcINJt49zx4= +github.com/go-fuego/fuego v0.16.1 h1:G+sDF55BjFI7FH7dd07HDx4jfNPxXEeab+YKuLjj5zY= +github.com/go-fuego/fuego v0.16.1/go.mod h1:ARPlRxY+RgbahF6ZvnjsESGQd3h/jCw8ksCJxKLbgjY= github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= diff --git a/examples/custom-serializer/go.mod b/examples/custom-serializer/go.mod index 4b946860..6c96474d 100644 --- a/examples/custom-serializer/go.mod +++ b/examples/custom-serializer/go.mod @@ -3,7 +3,7 @@ module github.com/go-fuego/fuego/examples/custom-serializer go 1.22.2 require ( - github.com/go-fuego/fuego v0.15.1 + github.com/go-fuego/fuego v0.16.1 github.com/json-iterator/go v1.1.12 ) diff --git a/examples/custom-serializer/go.sum b/examples/custom-serializer/go.sum index 0cc71adc..f4f2dd9c 100644 --- a/examples/custom-serializer/go.sum +++ b/examples/custom-serializer/go.sum @@ -5,8 +5,8 @@ github.com/gabriel-vasile/mimetype v1.4.7 h1:SKFKl7kD0RiPdbht0s7hFtjl489WcQ1VyPW github.com/gabriel-vasile/mimetype v1.4.7/go.mod h1:GDlAgAyIRT27BhFl53XNAFtfjzOkLaF35JdEG0P7LtU= github.com/getkin/kin-openapi v0.128.0 h1:jqq3D9vC9pPq1dGcOCv7yOp1DaEe7c/T1vzcLbITSp4= github.com/getkin/kin-openapi v0.128.0/go.mod h1:OZrfXzUfGrNbsKj+xmFBx6E5c6yH3At/tAKSc2UszXM= -github.com/go-fuego/fuego v0.15.1 h1:9ESspiRFeUmSl2YdZzL5VE+8F2sGYSTBRkGJEfvoLXc= -github.com/go-fuego/fuego v0.15.1/go.mod h1:XMpAQQnZsoMON0UD6ncvzj6YukGQlNECDcINJt49zx4= +github.com/go-fuego/fuego v0.16.1 h1:G+sDF55BjFI7FH7dd07HDx4jfNPxXEeab+YKuLjj5zY= +github.com/go-fuego/fuego v0.16.1/go.mod h1:ARPlRxY+RgbahF6ZvnjsESGQd3h/jCw8ksCJxKLbgjY= github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= diff --git a/examples/full-app-gourmet/go.mod b/examples/full-app-gourmet/go.mod index 5f021cae..9b1ff8c7 100644 --- a/examples/full-app-gourmet/go.mod +++ b/examples/full-app-gourmet/go.mod @@ -7,10 +7,10 @@ toolchain go1.23.3 require ( github.com/a-h/templ v0.2.793 github.com/go-chi/chi/v5 v5.1.0 - github.com/go-fuego/fuego v0.15.1 - github.com/go-fuego/fuego/extra/markdown v0.0.0-20241206012402-4c4bc8bfe6ef + github.com/go-fuego/fuego v0.16.1 + github.com/go-fuego/fuego/extra/markdown v0.0.0-20241209141708-1e6d931908a8 github.com/go-fuego/fuego/middleware/basicauth v0.15.1 - github.com/go-fuego/fuego/middleware/cache v0.0.0-20241206012402-4c4bc8bfe6ef + github.com/go-fuego/fuego/middleware/cache v0.0.0-20241209141708-1e6d931908a8 github.com/golang-jwt/jwt/v5 v5.2.1 github.com/golang-migrate/migrate/v4 v4.18.1 github.com/google/uuid v1.6.0 diff --git a/examples/generate-opengraph-image/go.mod b/examples/generate-opengraph-image/go.mod index 6c34b457..9854281b 100644 --- a/examples/generate-opengraph-image/go.mod +++ b/examples/generate-opengraph-image/go.mod @@ -4,8 +4,8 @@ go 1.23.3 require ( github.com/getkin/kin-openapi v0.128.0 - github.com/go-fuego/fuego v0.15.1 - github.com/go-fuego/fuego/middleware/cache v0.0.0-20241206012402-4c4bc8bfe6ef + github.com/go-fuego/fuego v0.16.1 + github.com/go-fuego/fuego/middleware/cache v0.0.0-20241209141708-1e6d931908a8 github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 golang.org/x/image v0.23.0 ) diff --git a/examples/generate-opengraph-image/go.sum b/examples/generate-opengraph-image/go.sum index 35251208..eae22087 100644 --- a/examples/generate-opengraph-image/go.sum +++ b/examples/generate-opengraph-image/go.sum @@ -4,10 +4,10 @@ github.com/gabriel-vasile/mimetype v1.4.7 h1:SKFKl7kD0RiPdbht0s7hFtjl489WcQ1VyPW github.com/gabriel-vasile/mimetype v1.4.7/go.mod h1:GDlAgAyIRT27BhFl53XNAFtfjzOkLaF35JdEG0P7LtU= github.com/getkin/kin-openapi v0.128.0 h1:jqq3D9vC9pPq1dGcOCv7yOp1DaEe7c/T1vzcLbITSp4= github.com/getkin/kin-openapi v0.128.0/go.mod h1:OZrfXzUfGrNbsKj+xmFBx6E5c6yH3At/tAKSc2UszXM= -github.com/go-fuego/fuego v0.15.1 h1:9ESspiRFeUmSl2YdZzL5VE+8F2sGYSTBRkGJEfvoLXc= -github.com/go-fuego/fuego v0.15.1/go.mod h1:XMpAQQnZsoMON0UD6ncvzj6YukGQlNECDcINJt49zx4= -github.com/go-fuego/fuego/middleware/cache v0.0.0-20241206012402-4c4bc8bfe6ef h1:hnjtw+FC2yykYN0lat+Ato7080yuNDl9ZAsSt7JCsfQ= -github.com/go-fuego/fuego/middleware/cache v0.0.0-20241206012402-4c4bc8bfe6ef/go.mod h1:OOX9YhxWG5dOkldwf+zzeBK/ef3uDPXZPSuZwA1w4Qg= +github.com/go-fuego/fuego v0.16.1 h1:G+sDF55BjFI7FH7dd07HDx4jfNPxXEeab+YKuLjj5zY= +github.com/go-fuego/fuego v0.16.1/go.mod h1:ARPlRxY+RgbahF6ZvnjsESGQd3h/jCw8ksCJxKLbgjY= +github.com/go-fuego/fuego/middleware/cache v0.0.0-20241209141708-1e6d931908a8 h1:7hIXyQTtRGo1YhYz+PYNQ5hU3BCJWgHKf3dF9PhAUqk= +github.com/go-fuego/fuego/middleware/cache v0.0.0-20241209141708-1e6d931908a8/go.mod h1:/9X4N39tE56XMv484IlTOMVL9WC+od7nyoG0yDg60Mo= github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= diff --git a/examples/hello-world/go.mod b/examples/hello-world/go.mod index 2f1cde62..3b020b6f 100644 --- a/examples/hello-world/go.mod +++ b/examples/hello-world/go.mod @@ -2,7 +2,7 @@ module github.com/go-fuego/fuego/examples/hello-world go 1.22.2 -require github.com/go-fuego/fuego v0.15.1 +require github.com/go-fuego/fuego v0.16.1 require ( github.com/gabriel-vasile/mimetype v1.4.7 // indirect diff --git a/examples/hello-world/go.sum b/examples/hello-world/go.sum index c54bcf23..e9853e49 100644 --- a/examples/hello-world/go.sum +++ b/examples/hello-world/go.sum @@ -4,8 +4,8 @@ github.com/gabriel-vasile/mimetype v1.4.7 h1:SKFKl7kD0RiPdbht0s7hFtjl489WcQ1VyPW github.com/gabriel-vasile/mimetype v1.4.7/go.mod h1:GDlAgAyIRT27BhFl53XNAFtfjzOkLaF35JdEG0P7LtU= github.com/getkin/kin-openapi v0.128.0 h1:jqq3D9vC9pPq1dGcOCv7yOp1DaEe7c/T1vzcLbITSp4= github.com/getkin/kin-openapi v0.128.0/go.mod h1:OZrfXzUfGrNbsKj+xmFBx6E5c6yH3At/tAKSc2UszXM= -github.com/go-fuego/fuego v0.15.1 h1:9ESspiRFeUmSl2YdZzL5VE+8F2sGYSTBRkGJEfvoLXc= -github.com/go-fuego/fuego v0.15.1/go.mod h1:XMpAQQnZsoMON0UD6ncvzj6YukGQlNECDcINJt49zx4= +github.com/go-fuego/fuego v0.16.1 h1:G+sDF55BjFI7FH7dd07HDx4jfNPxXEeab+YKuLjj5zY= +github.com/go-fuego/fuego v0.16.1/go.mod h1:ARPlRxY+RgbahF6ZvnjsESGQd3h/jCw8ksCJxKLbgjY= github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= diff --git a/examples/openapi/go.mod b/examples/openapi/go.mod index 0d87d966..6e39842b 100644 --- a/examples/openapi/go.mod +++ b/examples/openapi/go.mod @@ -2,7 +2,7 @@ module github.com/go-fuego/fuego/examples/openapi go 1.22.2 -require github.com/go-fuego/fuego v0.15.1 +require github.com/go-fuego/fuego v0.16.1 require ( github.com/gabriel-vasile/mimetype v1.4.7 // indirect diff --git a/examples/openapi/go.sum b/examples/openapi/go.sum index c54bcf23..e9853e49 100644 --- a/examples/openapi/go.sum +++ b/examples/openapi/go.sum @@ -4,8 +4,8 @@ github.com/gabriel-vasile/mimetype v1.4.7 h1:SKFKl7kD0RiPdbht0s7hFtjl489WcQ1VyPW github.com/gabriel-vasile/mimetype v1.4.7/go.mod h1:GDlAgAyIRT27BhFl53XNAFtfjzOkLaF35JdEG0P7LtU= github.com/getkin/kin-openapi v0.128.0 h1:jqq3D9vC9pPq1dGcOCv7yOp1DaEe7c/T1vzcLbITSp4= github.com/getkin/kin-openapi v0.128.0/go.mod h1:OZrfXzUfGrNbsKj+xmFBx6E5c6yH3At/tAKSc2UszXM= -github.com/go-fuego/fuego v0.15.1 h1:9ESspiRFeUmSl2YdZzL5VE+8F2sGYSTBRkGJEfvoLXc= -github.com/go-fuego/fuego v0.15.1/go.mod h1:XMpAQQnZsoMON0UD6ncvzj6YukGQlNECDcINJt49zx4= +github.com/go-fuego/fuego v0.16.1 h1:G+sDF55BjFI7FH7dd07HDx4jfNPxXEeab+YKuLjj5zY= +github.com/go-fuego/fuego v0.16.1/go.mod h1:ARPlRxY+RgbahF6ZvnjsESGQd3h/jCw8ksCJxKLbgjY= github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= diff --git a/middleware/basicauth/go.mod b/middleware/basicauth/go.mod index 7fea7139..f6e9efa6 100644 --- a/middleware/basicauth/go.mod +++ b/middleware/basicauth/go.mod @@ -3,7 +3,7 @@ module github.com/go-fuego/fuego/middleware/basicauth go 1.22.6 require ( - github.com/go-fuego/fuego v0.15.1 + github.com/go-fuego/fuego v0.16.1 github.com/stretchr/testify v1.10.0 ) diff --git a/middleware/basicauth/go.sum b/middleware/basicauth/go.sum index c54bcf23..e9853e49 100644 --- a/middleware/basicauth/go.sum +++ b/middleware/basicauth/go.sum @@ -4,8 +4,8 @@ github.com/gabriel-vasile/mimetype v1.4.7 h1:SKFKl7kD0RiPdbht0s7hFtjl489WcQ1VyPW github.com/gabriel-vasile/mimetype v1.4.7/go.mod h1:GDlAgAyIRT27BhFl53XNAFtfjzOkLaF35JdEG0P7LtU= github.com/getkin/kin-openapi v0.128.0 h1:jqq3D9vC9pPq1dGcOCv7yOp1DaEe7c/T1vzcLbITSp4= github.com/getkin/kin-openapi v0.128.0/go.mod h1:OZrfXzUfGrNbsKj+xmFBx6E5c6yH3At/tAKSc2UszXM= -github.com/go-fuego/fuego v0.15.1 h1:9ESspiRFeUmSl2YdZzL5VE+8F2sGYSTBRkGJEfvoLXc= -github.com/go-fuego/fuego v0.15.1/go.mod h1:XMpAQQnZsoMON0UD6ncvzj6YukGQlNECDcINJt49zx4= +github.com/go-fuego/fuego v0.16.1 h1:G+sDF55BjFI7FH7dd07HDx4jfNPxXEeab+YKuLjj5zY= +github.com/go-fuego/fuego v0.16.1/go.mod h1:ARPlRxY+RgbahF6ZvnjsESGQd3h/jCw8ksCJxKLbgjY= github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= From 3342bf3d2480116e9e4b81d5dfe5fedbf8a1c105 Mon Sep 17 00:00:00 2001 From: dylanhitt Date: Wed, 20 Nov 2024 12:02:35 -0500 Subject: [PATCH 038/138] feat: add ErrorWithDetail --- errors.go | 25 ++++++++++++++++++++----- errors_test.go | 23 ++++++++++++++++++++--- examples/basic/main.go | 20 ++++++++++++++++++++ 3 files changed, 60 insertions(+), 8 deletions(-) diff --git a/errors.go b/errors.go index 75ffcb07..d4adaf41 100644 --- a/errors.go +++ b/errors.go @@ -14,6 +14,11 @@ type ErrorWithStatus interface { StatusCode() int } +type ErrorWithDetail interface { + error + DetailMsg() string +} + // HTTPError is the error response used by the serialization part of the framework. type HTTPError struct { Err error `json:"-" xml:"-"` // Developer readable error message. Not shown to the user to avoid security leaks. @@ -40,7 +45,7 @@ func (e HTTPError) Error() string { title = "HTTP Error" } } - return fmt.Sprintf("%d %s: %s", code, title, e.Detail) + return fmt.Sprintf("%d %s: %s", code, title, e.DetailMsg()) } func (e HTTPError) StatusCode() int { @@ -50,6 +55,10 @@ func (e HTTPError) StatusCode() int { return e.Status } +func (e HTTPError) DetailMsg() string { + return e.Detail +} + func (e HTTPError) Unwrap() error { return e.Err } // BadRequestError is an error used to return a 400 status code. @@ -122,11 +131,11 @@ func (e NotAcceptableError) StatusCode() int { return http.StatusNotAcceptable } func (e NotAcceptableError) Unwrap() error { return HTTPError(e) } // ErrorHandler is the default error handler used by the framework. -// If the error is an [HTTPError] that is error is returned. -// If the error adheres to the [ErrorWithStatus] interface +// If the error is an [HTTPError] that error is returned. +// If the error adheres to the [ErrorWithStatus] and/or [ErrorWithDetail] interface // the error is transformed to a [HTTPError]. // If the error is not an [HTTPError] nor does it adhere to an -// interface the error is returned. +// interface the error is returned as is. func ErrorHandler(err error) error { var errorStatus ErrorWithStatus switch { @@ -154,11 +163,17 @@ func handleHTTPError(err error) HTTPError { errResponse.Status = errorStatus.StatusCode() } + // Check for detail + var errorDetail ErrorWithDetail + if errors.As(err, &errorDetail) { + errResponse.Detail = errorDetail.DetailMsg() + } + if errResponse.Title == "" { errResponse.Title = http.StatusText(errResponse.Status) } - slog.Error("Error "+errResponse.Title, "status", errResponse.StatusCode(), "detail", errResponse.Detail, "error", errResponse.Err) + slog.Error("Error "+errResponse.Title, "status", errResponse.StatusCode(), "detail", errResponse.DetailMsg(), "error", errResponse.Err) return errResponse } diff --git a/errors_test.go b/errors_test.go index b49c9a77..c8f65da1 100644 --- a/errors_test.go +++ b/errors_test.go @@ -10,12 +10,17 @@ import ( type myError struct { status int + err HTTPError + detail string } var _ ErrorWithStatus = myError{} +var _ ErrorWithDetail = myError{} -func (e myError) Error() string { return "test error" } -func (e myError) StatusCode() int { return e.status } +func (e myError) Error() string { return "test error" } +func (e myError) StatusCode() int { return e.status } +func (e myError) DetailMsg() string { return e.detail } +func (e myError) Unwrap() error { return HTTPError(e.err) } func TestErrorHandler(t *testing.T) { t.Run("basic", func(t *testing.T) { @@ -49,7 +54,7 @@ func TestErrorHandler(t *testing.T) { require.ErrorContains(t, err, "Internal Server Error") }) - t.Run("error with status ", func(t *testing.T) { + t.Run("error with status", func(t *testing.T) { err := myError{ status: http.StatusNotFound, } @@ -60,6 +65,18 @@ func TestErrorHandler(t *testing.T) { require.Equal(t, http.StatusNotFound, errResponse.(HTTPError).StatusCode()) }) + t.Run("error with detail", func(t *testing.T) { + err := myError{ + detail: "my detail", + } + errResponse := ErrorHandler(err) + require.ErrorAs(t, errResponse, &HTTPError{}) + require.Contains(t, errResponse.Error(), "Internal Server Error") + require.Contains(t, errResponse.Error(), "500") + require.Contains(t, errResponse.Error(), "my detail") + require.Equal(t, http.StatusInternalServerError, errResponse.(HTTPError).StatusCode()) + }) + t.Run("conflict error", func(t *testing.T) { err := ConflictError{ Err: errors.New("Conflict"), diff --git a/examples/basic/main.go b/examples/basic/main.go index 84833dc8..5ae6a49a 100644 --- a/examples/basic/main.go +++ b/examples/basic/main.go @@ -22,6 +22,22 @@ type MyResponse struct { BestFramework string `json:"best"` } +type MyError struct { + Err error `json:"error"` + Message string `json:"message"` +} + +var _ fuego.ErrorWithStatus = MyError{} +var _ fuego.ErrorWithDetail = MyError{} + +func (e MyError) Error() string { return e.Err.Error() } + +func (e MyError) StatusCode() int { return http.StatusTeapot } + +func (e MyError) DetailMsg() string { + return strings.Split(e.Error(), " ")[1] +} + func main() { s := fuego.NewServer( fuego.WithAddr("localhost:8088"), @@ -59,6 +75,10 @@ func main() { w.Write([]byte("Hello, World!")) }) + fuego.Get(s, "/custom-err", func(c *fuego.ContextNoBody) (string, error) { + return "hello", MyError{Err: errors.New("my error")} + }) + s.Run() } From bd0f8bb4259c26ba82508cb13c7ba5896deb6578 Mon Sep 17 00:00:00 2001 From: dylanhitt Date: Fri, 6 Dec 2024 13:55:29 -0500 Subject: [PATCH 039/138] chore: update error handling docs --- documentation/docs/guides/errors.md | 80 ++++++++++++++++++++++++++--- errors.go | 19 ++++--- server.go | 1 + 3 files changed, 86 insertions(+), 14 deletions(-) diff --git a/documentation/docs/guides/errors.md b/documentation/docs/guides/errors.md index 98eb8e85..a163eaf7 100644 --- a/documentation/docs/guides/errors.md +++ b/documentation/docs/guides/errors.md @@ -4,22 +4,85 @@ Error handling is a crucial part of any application. It is important to handle e ## Error handling in Fuego -Fuego [controllers](./controllers) returns a value and an error. If the error is not `nil`, it means that an error occurred while processing the request. The error will be returned to the client as a JSON response. +Fuego [controllers](./controllers) returns a value and an error. If the error is not `nil`, +it means that an error occurred while processing the request. +The error will be returned to the client as a JSON or XML response. -By default, Fuego implements [RFC 9457](https://www.rfc-editor.org/rfc/rfc9457), which defines a standard error format for HTTP APIs. We strongly recommend following this standard, but you can also use your own errors. +The default error handler will transform any error that implements the +`fuego.ErrorWithStatus` or `fuego.ErrorWithDetail` interfaces into a `fuego.HTTPError`. The `fuego.HTTPError` implements +[RFC 9457](https://www.rfc-editor.org/rfc/rfc9457), which defines a standard error format for HTTP APIs. +We strongly recommend following this standard, but you can also use your own errors. -The error type returned as JSON is `fuego.HTTPError`. It has a `Status` and a `Info` field. The `Status` field is an integer that represents the error code. The `Info` field is a string that contains a human-readable error message. +The default `fuego.ErrorHandler` can be overridden using `fuego.WithErrorHandler` at fuego Server creation time. -If your error implements `Status() int` and `Info()` methods, the error will include the status code and the error message in the `fuego.HTTPError` response. +The error type of `fuego.HTTPError` is returned as JSON or XML depending on the content-type specified. +It's structure is the following: + +```go +// HTTPError is the error response used by the serialization part of the framework. +type HTTPError struct { + // Developer readable error message. Not shown to the user to avoid security leaks. + Err error `json:"-" xml:"-"` + // URL of the error type. Can be used to lookup the error in a documentation + Type string `json:"type,omitempty" xml:"type,omitempty" description:"URL of the error type. Can be used to lookup the error in a documentation"` + // Short title of the error + Title string `json:"title,omitempty" xml:"title,omitempty" description:"Short title of the error"` + // HTTP status code. If using a different type than [HTTPError], for example [BadRequestError], + // this will be automatically overridden after Fuego error handling. + Status int `json:"status,omitempty" xml:"status,omitempty" description:"HTTP status code" example:"403"` + // Human readable error message + Detail string `json:"detail,omitempty" xml:"detail,omitempty" description:"Human readable error message"` + Instance string `json:"instance,omitempty" xml:"instance,omitempty"` + Errors []ErrorItem `json:"errors,omitempty" xml:"errors,omitempty"` +} +``` + +If your error implements `fuego.ErrorWithStatus` or `fuego.ErrorWithDetail` +the error will be returned as a `fuego.HTTPError`. + +```go +// ErrorWithStatus is an interface that can be implemented by an error to provide +// a status code +type ErrorWithStatus interface { + error + StatusCode() int +} + +// ErrorWithDetail is an interface that can be implemented by an error to provide +// an additional detail message about the error +type ErrorWithDetail interface { + error + DetailMsg() string +} +``` + +Example: ```go type MyCustomError struct { - Status int - Message string + Err error `json:"error"` + Message string `json:"message"` +} + +var _ fuego.ErrorWithStatus = MyCustomError{} +var _ fuego.ErrorWithDetail = MyCustomError{} + +func (e MyCustomError) Error() string { return e.Err.Error() } + +func (e MyCustomError) StatusCode() int { return http.StatusTeapot } + +func (e MyCustomError) DetailMsg() string { + return strings.Split(e.Error(), " ")[1] } +``` -func (e MyCustomError) Status() int { - return e.Status +Alternatively, you can always use `fuego.HTTPError` directly such as: + +```go +err := fuego.HTTPError{ + Title: "unauthorized access", + Detail: "wrong username or password", + Status: http.StatusUnauthorized, } ``` @@ -33,3 +96,4 @@ Fuego provides a set of default errors that you can use in your application. - `fuego.NotFoundError`: 404 Not Found - `fuego.ConflictError`: 409 Conflict - `fuego.InternalServerError`: 500 Internal Server Error +- `fuego.NotAcceptableError`: 406 Not Acceptable diff --git a/errors.go b/errors.go index d4adaf41..526c0f29 100644 --- a/errors.go +++ b/errors.go @@ -8,12 +8,14 @@ import ( ) // ErrorWithStatus is an interface that can be implemented by an error to provide -// additional information about the error. +// a status code type ErrorWithStatus interface { error StatusCode() int } +// ErrorWithDetail is an interface that can be implemented by an error to provide +// an additional detail message about the error type ErrorWithDetail interface { error DetailMsg() string @@ -21,11 +23,16 @@ type ErrorWithDetail interface { // HTTPError is the error response used by the serialization part of the framework. type HTTPError struct { - Err error `json:"-" xml:"-"` // Developer readable error message. Not shown to the user to avoid security leaks. - Type string `json:"type,omitempty" xml:"type,omitempty" description:"URL of the error type. Can be used to lookup the error in a documentation"` // URL of the error type. Can be used to lookup the error in a documentation - Title string `json:"title,omitempty" xml:"title,omitempty" description:"Short title of the error"` // Short title of the error - Status int `json:"status,omitempty" xml:"status,omitempty" description:"HTTP status code" example:"403"` // HTTP status code. If using a different type than [HTTPError], for example [BadRequestError], this will be automatically overridden after Fuego error handling. - Detail string `json:"detail,omitempty" xml:"detail,omitempty" description:"Human readable error message"` // Human readable error message + // Developer readable error message. Not shown to the user to avoid security leaks. + Err error `json:"-" xml:"-"` + // URL of the error type. Can be used to lookup the error in a documentation + Type string `json:"type,omitempty" xml:"type,omitempty" description:"URL of the error type. Can be used to lookup the error in a documentation"` + // Short title of the error + Title string `json:"title,omitempty" xml:"title,omitempty" description:"Short title of the error"` + // HTTP status code. If using a different type than [HTTPError], for example [BadRequestError], this will be automatically overridden after Fuego error handling. + Status int `json:"status,omitempty" xml:"status,omitempty" description:"HTTP status code" example:"403"` + // Human readable error message + Detail string `json:"detail,omitempty" xml:"detail,omitempty" description:"Human readable error message"` Instance string `json:"instance,omitempty" xml:"instance,omitempty"` Errors []ErrorItem `json:"errors,omitempty" xml:"errors,omitempty"` } diff --git a/server.go b/server.go index 6daba7ee..a0215c23 100644 --- a/server.go +++ b/server.go @@ -370,6 +370,7 @@ func WithErrorSerializer(serializer ErrorSender) func(*Server) { return func(c *Server) { c.SerializeError = serializer } } +// WithErrorHandler sets a customer error handler for the server func WithErrorHandler(errorHandler func(err error) error) func(*Server) { return func(c *Server) { c.ErrorHandler = errorHandler } } From 2ceec34fc7110a3503709619fac874274163851c Mon Sep 17 00:00:00 2001 From: dylanhitt Date: Fri, 6 Dec 2024 14:49:03 -0500 Subject: [PATCH 040/138] chore: custom-errors as its own example --- examples/basic/main.go | 20 ---------- examples/custom-errors/go.mod | 32 ++++++++++++++++ examples/custom-errors/go.sum | 69 ++++++++++++++++++++++++++++++++++ examples/custom-errors/main.go | 46 +++++++++++++++++++++++ 4 files changed, 147 insertions(+), 20 deletions(-) create mode 100644 examples/custom-errors/go.mod create mode 100644 examples/custom-errors/go.sum create mode 100644 examples/custom-errors/main.go diff --git a/examples/basic/main.go b/examples/basic/main.go index 5ae6a49a..84833dc8 100644 --- a/examples/basic/main.go +++ b/examples/basic/main.go @@ -22,22 +22,6 @@ type MyResponse struct { BestFramework string `json:"best"` } -type MyError struct { - Err error `json:"error"` - Message string `json:"message"` -} - -var _ fuego.ErrorWithStatus = MyError{} -var _ fuego.ErrorWithDetail = MyError{} - -func (e MyError) Error() string { return e.Err.Error() } - -func (e MyError) StatusCode() int { return http.StatusTeapot } - -func (e MyError) DetailMsg() string { - return strings.Split(e.Error(), " ")[1] -} - func main() { s := fuego.NewServer( fuego.WithAddr("localhost:8088"), @@ -75,10 +59,6 @@ func main() { w.Write([]byte("Hello, World!")) }) - fuego.Get(s, "/custom-err", func(c *fuego.ContextNoBody) (string, error) { - return "hello", MyError{Err: errors.New("my error")} - }) - s.Run() } diff --git a/examples/custom-errors/go.mod b/examples/custom-errors/go.mod new file mode 100644 index 00000000..d5b869de --- /dev/null +++ b/examples/custom-errors/go.mod @@ -0,0 +1,32 @@ +module github.com/go-fuego/fuego/examples/basic + +go 1.22.2 + +require ( + github.com/go-chi/chi/v5 v5.1.0 + github.com/go-fuego/fuego v0.15.1 + github.com/rs/cors v1.11.1 +) + +require ( + github.com/gabriel-vasile/mimetype v1.4.7 // indirect + github.com/getkin/kin-openapi v0.128.0 // indirect + github.com/go-openapi/jsonpointer v0.21.0 // indirect + github.com/go-openapi/swag v0.23.0 // indirect + github.com/go-playground/locales v0.14.1 // indirect + github.com/go-playground/universal-translator v0.18.1 // indirect + github.com/go-playground/validator/v10 v10.23.0 // indirect + github.com/golang-jwt/jwt/v5 v5.2.1 // indirect + github.com/gorilla/schema v1.4.1 // indirect + github.com/invopop/yaml v0.3.1 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/leodido/go-urn v1.4.0 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect + github.com/perimeterx/marshmallow v1.1.5 // indirect + golang.org/x/crypto v0.30.0 // indirect + golang.org/x/net v0.32.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/text v0.21.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/examples/custom-errors/go.sum b/examples/custom-errors/go.sum new file mode 100644 index 00000000..6936a3f1 --- /dev/null +++ b/examples/custom-errors/go.sum @@ -0,0 +1,69 @@ +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/gabriel-vasile/mimetype v1.4.7 h1:SKFKl7kD0RiPdbht0s7hFtjl489WcQ1VyPW8ZzUMYCA= +github.com/gabriel-vasile/mimetype v1.4.7/go.mod h1:GDlAgAyIRT27BhFl53XNAFtfjzOkLaF35JdEG0P7LtU= +github.com/getkin/kin-openapi v0.128.0 h1:jqq3D9vC9pPq1dGcOCv7yOp1DaEe7c/T1vzcLbITSp4= +github.com/getkin/kin-openapi v0.128.0/go.mod h1:OZrfXzUfGrNbsKj+xmFBx6E5c6yH3At/tAKSc2UszXM= +github.com/go-chi/chi/v5 v5.1.0 h1:acVI1TYaD+hhedDJ3r54HyA6sExp3HfXq7QWEEY/xMw= +github.com/go-chi/chi/v5 v5.1.0/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= +github.com/go-fuego/fuego v0.15.1 h1:9ESspiRFeUmSl2YdZzL5VE+8F2sGYSTBRkGJEfvoLXc= +github.com/go-fuego/fuego v0.15.1/go.mod h1:XMpAQQnZsoMON0UD6ncvzj6YukGQlNECDcINJt49zx4= +github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= +github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= +github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= +github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= +github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= +github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= +github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= +github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= +github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= +github.com/go-playground/validator/v10 v10.23.0 h1:/PwmTwZhS0dPkav3cdK9kV1FsAmrL8sThn8IHr/sO+o= +github.com/go-playground/validator/v10 v10.23.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= +github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= +github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= +github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= +github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= +github.com/gorilla/schema v1.4.1 h1:jUg5hUjCSDZpNGLuXQOgIWGdlgrIdYvgQ0wZtdK1M3E= +github.com/gorilla/schema v1.4.1/go.mod h1:Dg5SSm5PV60mhF2NFaTV1xuYYj8tV8NOPRo4FggUMnM= +github.com/invopop/yaml v0.3.1 h1:f0+ZpmhfBSS4MhG+4HYseMdJhoeeopbSKbq5Rpeelso= +github.com/invopop/yaml v0.3.1/go.mod h1:PMOp3nn4/12yEZUFfmOuNHJsZToEEOwoWsT+D81KkeA= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= +github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= +github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= +github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA= +github.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/thejerf/slogassert v0.3.4 h1:VoTsXixRbXMrRSSxDjYTiEDCM4VWbsYPW5rB/hX24kM= +github.com/thejerf/slogassert v0.3.4/go.mod h1:0zn9ISLVKo1aPMTqcGfG1o6dWwt+Rk574GlUxHD4rs8= +github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= +github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= +golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY= +golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= +golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/examples/custom-errors/main.go b/examples/custom-errors/main.go new file mode 100644 index 00000000..268714e7 --- /dev/null +++ b/examples/custom-errors/main.go @@ -0,0 +1,46 @@ +package main + +import ( + "errors" + "net/http" + "strings" + + chiMiddleware "github.com/go-chi/chi/v5/middleware" + "github.com/rs/cors" + + "github.com/go-fuego/fuego" + "github.com/go-fuego/fuego/option" +) + +type MyError struct { + Err error `json:"error"` + Message string `json:"message"` +} + +var _ fuego.ErrorWithStatus = MyError{} +var _ fuego.ErrorWithDetail = MyError{} + +func (e MyError) Error() string { return e.Err.Error() } + +func (e MyError) StatusCode() int { return http.StatusTeapot } + +func (e MyError) DetailMsg() string { + return strings.Split(e.Error(), " ")[1] +} + +func main() { + s := fuego.NewServer( + fuego.WithAddr("localhost:8088"), + ) + + fuego.Use(s, cors.Default().Handler) + fuego.Use(s, chiMiddleware.Compress(5, "text/html", "text/css")) + + fuego.Get(s, "/custom-err", func(c *fuego.ContextNoBody) (string, error) { + return "hello", MyError{Err: errors.New("my error")} + }, + option.AddError(http.StatusTeapot, "my custom teapot error", MyError{}), + ) + + s.Run() +} From f42f6eb38c4c24b9bb02931c1cd716b94f93e3b3 Mon Sep 17 00:00:00 2001 From: dylanhitt Date: Fri, 6 Dec 2024 19:06:15 -0500 Subject: [PATCH 041/138] chore: go work for custom-errors --- examples/custom-errors/go.mod | 2 +- go.work | 1 + middleware/cache/go.mod | 8 ++++---- middleware/cache/go.sum | 12 ++++-------- testing-from-outside/go.mod | 6 +++--- testing-from-outside/go.sum | 9 +++------ 6 files changed, 16 insertions(+), 22 deletions(-) diff --git a/examples/custom-errors/go.mod b/examples/custom-errors/go.mod index d5b869de..6b645fc2 100644 --- a/examples/custom-errors/go.mod +++ b/examples/custom-errors/go.mod @@ -1,4 +1,4 @@ -module github.com/go-fuego/fuego/examples/basic +module github.com/go-fuego/fuego/examples/custom-errors go 1.22.2 diff --git a/go.work b/go.work index 0d2d1f60..d6686f05 100644 --- a/go.work +++ b/go.work @@ -5,6 +5,7 @@ use ( ./cmd/fuego ./examples/acme-tls ./examples/basic + ./examples/custom-errors ./examples/custom-serializer ./examples/full-app-gourmet ./examples/generate-opengraph-image diff --git a/middleware/cache/go.mod b/middleware/cache/go.mod index 4324829b..ff325c4c 100644 --- a/middleware/cache/go.mod +++ b/middleware/cache/go.mod @@ -26,9 +26,9 @@ require ( github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - golang.org/x/crypto v0.29.0 // indirect - golang.org/x/net v0.31.0 // indirect - golang.org/x/sys v0.27.0 // indirect - golang.org/x/text v0.20.0 // indirect + golang.org/x/crypto v0.30.0 // indirect + golang.org/x/net v0.32.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/text v0.21.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/middleware/cache/go.sum b/middleware/cache/go.sum index 455cd44a..1955bf17 100644 --- a/middleware/cache/go.sum +++ b/middleware/cache/go.sum @@ -52,14 +52,10 @@ github.com/thejerf/slogassert v0.3.4 h1:VoTsXixRbXMrRSSxDjYTiEDCM4VWbsYPW5rB/hX2 github.com/thejerf/slogassert v0.3.4/go.mod h1:0zn9ISLVKo1aPMTqcGfG1o6dWwt+Rk574GlUxHD4rs8= github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= -golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ= -golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg= -golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo= -golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM= -golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= -golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug= -golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= +golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY= +golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/testing-from-outside/go.mod b/testing-from-outside/go.mod index ec10aa5d..092cc79c 100644 --- a/testing-from-outside/go.mod +++ b/testing-from-outside/go.mod @@ -27,9 +27,9 @@ require ( github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - golang.org/x/crypto v0.29.0 // indirect - golang.org/x/net v0.31.0 // indirect - golang.org/x/sys v0.27.0 // indirect + golang.org/x/crypto v0.30.0 // indirect + golang.org/x/net v0.32.0 // indirect + golang.org/x/sys v0.28.0 // indirect golang.org/x/text v0.21.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/testing-from-outside/go.sum b/testing-from-outside/go.sum index 0d195b30..242c29f1 100644 --- a/testing-from-outside/go.sum +++ b/testing-from-outside/go.sum @@ -52,12 +52,9 @@ github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOf github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= -golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ= -golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg= -golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo= -golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM= -golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= -golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY= +golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= From 7fde0a0f57f108ffa7dab894a41a21b29b20cb16 Mon Sep 17 00:00:00 2001 From: EwenQuim Date: Mon, 9 Dec 2024 23:01:13 +0100 Subject: [PATCH 042/138] Format code --- errors_test.go | 6 ++++-- examples/custom-errors/main.go | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/errors_test.go b/errors_test.go index c8f65da1..0fea5b14 100644 --- a/errors_test.go +++ b/errors_test.go @@ -14,8 +14,10 @@ type myError struct { detail string } -var _ ErrorWithStatus = myError{} -var _ ErrorWithDetail = myError{} +var ( + _ ErrorWithStatus = myError{} + _ ErrorWithDetail = myError{} +) func (e myError) Error() string { return "test error" } func (e myError) StatusCode() int { return e.status } diff --git a/examples/custom-errors/main.go b/examples/custom-errors/main.go index 268714e7..a088d891 100644 --- a/examples/custom-errors/main.go +++ b/examples/custom-errors/main.go @@ -17,8 +17,10 @@ type MyError struct { Message string `json:"message"` } -var _ fuego.ErrorWithStatus = MyError{} -var _ fuego.ErrorWithDetail = MyError{} +var ( + _ fuego.ErrorWithStatus = MyError{} + _ fuego.ErrorWithDetail = MyError{} +) func (e MyError) Error() string { return e.Err.Error() } From 4384a2b04588058a2f86dda5f2a19866284f6e79 Mon Sep 17 00:00:00 2001 From: EwenQuim Date: Mon, 9 Dec 2024 15:32:53 +0100 Subject: [PATCH 043/138] Default status code --- examples/petstore/controllers/pets.go | 1 + examples/petstore/controllers/pets_test.go | 15 ++++--- .../lib/testdata/doc/openapi.golden.json | 4 +- mux.go | 1 + openapi.go | 22 ++++++---- option.go | 7 ++++ option/option.go | 2 + option_test.go | 41 +++++++++++++++++++ serve.go | 4 ++ 9 files changed, 80 insertions(+), 17 deletions(-) diff --git a/examples/petstore/controllers/pets.go b/examples/petstore/controllers/pets.go index 6a8a63cd..8ca7245e 100644 --- a/examples/petstore/controllers/pets.go +++ b/examples/petstore/controllers/pets.go @@ -46,6 +46,7 @@ func (rs PetsResources) Routes(s *fuego.Server) { fuego.Get(petsGroup, "/by-age", rs.getAllPetsByAge, option.Description("Returns an array of pets grouped by age")) fuego.Post(petsGroup, "/", rs.postPets, + option.DefaultStatusCode(201), option.AddError(409, "Conflict: Pet with the same name already exists", PetsError{}), ) diff --git a/examples/petstore/controllers/pets_test.go b/examples/petstore/controllers/pets_test.go index 919b9921..d70478d3 100644 --- a/examples/petstore/controllers/pets_test.go +++ b/examples/petstore/controllers/pets_test.go @@ -51,7 +51,10 @@ func TestPostPets(t *testing.T) { s.Mux.ServeHTTP(w, r) - require.Equal(t, http.StatusOK, w.Code) + require.Equal(t, http.StatusCreated, w.Code) + petId := w.Body.String() + t.Log(petId) + require.NotEmpty(t, petId) }) } @@ -63,7 +66,7 @@ func TestGetPets(t *testing.T) { r := httptest.NewRequest("POST", "/pets/", strings.NewReader(`{"name": "kitkat"}`)) s.Mux.ServeHTTP(w, r) t.Log(w.Body.String()) - require.Equal(t, http.StatusOK, w.Code) + require.Equal(t, http.StatusCreated, w.Code) w = httptest.NewRecorder() r = httptest.NewRequest("GET", "/pets/pet-1", nil) @@ -83,7 +86,7 @@ func TestGetAllPestByAge(t *testing.T) { r := httptest.NewRequest("POST", "/pets/", strings.NewReader(`{"name": "kitkat"}`)) s.Mux.ServeHTTP(w, r) t.Log(w.Body.String()) - require.Equal(t, http.StatusOK, w.Code) + require.Equal(t, http.StatusCreated, w.Code) w = httptest.NewRecorder() r = httptest.NewRequest("GET", "/pets/by-age", nil) @@ -103,7 +106,7 @@ func TestGetPetsByName(t *testing.T) { r := httptest.NewRequest("POST", "/pets/", strings.NewReader(`{"name": "kitkat"}`)) s.Mux.ServeHTTP(w, r) t.Log(w.Body.String()) - require.Equal(t, http.StatusOK, w.Code) + require.Equal(t, http.StatusCreated, w.Code) w = httptest.NewRecorder() r = httptest.NewRequest("GET", "/pets/by-name/kitkat", nil) @@ -123,7 +126,7 @@ func TestPutPets(t *testing.T) { r := httptest.NewRequest("POST", "/pets/", strings.NewReader(`{"name": "kitkat"}`)) s.Mux.ServeHTTP(w, r) t.Log(w.Body.String()) - require.Equal(t, http.StatusOK, w.Code) + require.Equal(t, http.StatusCreated, w.Code) w = httptest.NewRecorder() r = httptest.NewRequest("PUT", "/pets/pet-1", strings.NewReader(`{"name": "snickers"}`)) @@ -143,7 +146,7 @@ func TestDeletePets(t *testing.T) { r := httptest.NewRequest("POST", "/pets/", strings.NewReader(`{"name": "kitkat"}`)) s.Mux.ServeHTTP(w, r) t.Log(w.Body.String()) - require.Equal(t, http.StatusOK, w.Code) + require.Equal(t, http.StatusCreated, w.Code) w = httptest.NewRecorder() r = httptest.NewRequest("DELETE", "/pets/pet-1", nil) diff --git a/examples/petstore/lib/testdata/doc/openapi.golden.json b/examples/petstore/lib/testdata/doc/openapi.golden.json index 56c957a1..853aa99f 100644 --- a/examples/petstore/lib/testdata/doc/openapi.golden.json +++ b/examples/petstore/lib/testdata/doc/openapi.golden.json @@ -306,7 +306,7 @@ "required": true }, "responses": { - "200": { + "201": { "content": { "application/json": { "schema": { @@ -319,7 +319,7 @@ } } }, - "description": "OK" + "description": "Created" }, "400": { "content": { diff --git a/mux.go b/mux.go index b07c8e21..1a7aa23a 100644 --- a/mux.go +++ b/mux.go @@ -59,6 +59,7 @@ type BaseRoute struct { Middlewares []func(http.Handler) http.Handler AcceptedContentTypes []string // Content types accepted for the request body. If nil, all content types (*/*) are accepted. Hidden bool // If true, the route will not be documented in the OpenAPI spec + DefaultStatusCode int // Default status code for the response mainRouter *Server // ref to the main router, used to register the route in the OpenAPI spec } diff --git a/openapi.go b/openapi.go index 072a719a..dc40087f 100644 --- a/openapi.go +++ b/openapi.go @@ -188,19 +188,23 @@ func RegisterOpenAPIOperation[T, B any](s *Server, route Route[T, B]) (*openapi3 addResponseIfNotSet(s, route.Operation, openAPIGlobalResponse.Code, openAPIGlobalResponse.Description, openAPIGlobalResponse.ErrorType) } - // Automatically add non-declared 200 Response - response200 := route.Operation.Responses.Value("200") - if response200 == nil { - response := openapi3.NewResponse().WithDescription("OK") - route.Operation.AddResponse(200, response) - response200 = route.Operation.Responses.Value("200") + // Automatically add non-declared 200 (or other) Response + if route.DefaultStatusCode == 0 { + route.DefaultStatusCode = 200 + } + defaultStatusCode := strconv.Itoa(route.DefaultStatusCode) + responseDefault := route.Operation.Responses.Value(defaultStatusCode) + if responseDefault == nil { + response := openapi3.NewResponse().WithDescription(http.StatusText(route.DefaultStatusCode)) + route.Operation.AddResponse(route.DefaultStatusCode, response) + responseDefault = route.Operation.Responses.Value(defaultStatusCode) } - // Automatically add non-declared Content for 200 Response - if response200.Value.Content == nil { + // Automatically add non-declared Content for 200 (or other) Response + if responseDefault.Value.Content == nil { responseSchema := SchemaTagFromType(s, *new(T)) content := openapi3.NewContentWithSchemaRef(&responseSchema.SchemaRef, []string{"application/json", "application/xml"}) - response200.Value.WithContent(content) + responseDefault.Value.WithContent(content) } // Automatically add non-declared Path parameters diff --git a/option.go b/option.go index 7f2a72df..1ec14a1e 100644 --- a/option.go +++ b/option.go @@ -287,6 +287,13 @@ func OptionHide() func(*BaseRoute) { } } +// Hide hides the route from the OpenAPI spec. +func OptionDefaultStatusCode(defaultStatusCode int) func(*BaseRoute) { + return func(r *BaseRoute) { + r.DefaultStatusCode = defaultStatusCode + } +} + // OptionSecurity configures security requirements to the route. // // Single Scheme (AND Logic): diff --git a/option/option.go b/option/option.go index fcaebaff..151dffda 100644 --- a/option/option.go +++ b/option/option.go @@ -143,3 +143,5 @@ var RequestContentType = fuego.OptionRequestContentType // Hide hides the route from the OpenAPI spec. var Hide = fuego.OptionHide + +var DefaultStatusCode = fuego.OptionDefaultStatusCode diff --git a/option_test.go b/option_test.go index 600d628e..197abdd0 100644 --- a/option_test.go +++ b/option_test.go @@ -695,3 +695,44 @@ func TestOptionAddDescription(t *testing.T) { require.Equal(t, "controller: `github.com/go-fuego/fuego_test.helloWorld`\n\n---\n\ntest description\n\nanother description", route.Operation.Description) }) } + +func TestDefaultStatusCode(t *testing.T) { + t.Run("Declare a default status code for the route", func(t *testing.T) { + s := fuego.NewServer() + + route := fuego.Post(s, "/test", helloWorld, + fuego.OptionDefaultStatusCode(201), + ) + + r := httptest.NewRequest(http.MethodPost, "/test", nil) + w := httptest.NewRecorder() + + s.Mux.ServeHTTP(w, r) + + require.Equal(t, 201, w.Code) + require.Equal(t, "hello world", w.Body.String()) + require.Equal(t, 201, route.DefaultStatusCode) + require.NotNil(t, route.Operation.Responses.Value("201").Value) + }) + + t.Run("Declare a default status code for the route but bypass it in the controller", func(t *testing.T) { + s := fuego.NewServer() + + route := fuego.Post(s, "/test", func(c fuego.ContextNoBody) (string, error) { + c.SetStatus(200) + return "hello world", nil + }, + fuego.OptionDefaultStatusCode(201), + ) + + r := httptest.NewRequest(http.MethodPost, "/test", nil) + w := httptest.NewRecorder() + + s.Mux.ServeHTTP(w, r) + + require.Equal(t, 200, w.Code) + require.Equal(t, "hello world", w.Body.String()) + require.Equal(t, 201, route.DefaultStatusCode, "default status code should not be changed") + require.NotNil(t, route.Operation.Responses.Value("201").Value, "default status is still in the spec even if code is not used") + }) +} diff --git a/serve.go b/serve.go index 91fdba90..b410b284 100644 --- a/serve.go +++ b/serve.go @@ -139,6 +139,10 @@ func HTTPHandler[ReturnType, Body any, Contextable ctx[Body]](s *Server, control return } + if route.DefaultStatusCode != 0 { + w.WriteHeader(route.DefaultStatusCode) + } + // TRANSFORM OUT timeTransformOut := time.Now() ans, err = transformOut(r.Context(), ans) From 3e952714733bc437af918f9c29368faa7de47367 Mon Sep 17 00:00:00 2001 From: EwenQuim Date: Mon, 9 Dec 2024 23:14:48 +0100 Subject: [PATCH 044/138] docs: Fixes comment on OptionDefaultStatusCode --- option.go | 2 +- option/option.go | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/option.go b/option.go index 1ec14a1e..f4dd058c 100644 --- a/option.go +++ b/option.go @@ -287,7 +287,7 @@ func OptionHide() func(*BaseRoute) { } } -// Hide hides the route from the OpenAPI spec. +// OptionDefaultStatusCode sets the default status code for the route. func OptionDefaultStatusCode(defaultStatusCode int) func(*BaseRoute) { return func(r *BaseRoute) { r.DefaultStatusCode = defaultStatusCode diff --git a/option/option.go b/option/option.go index 151dffda..6abe07b3 100644 --- a/option/option.go +++ b/option/option.go @@ -144,4 +144,5 @@ var RequestContentType = fuego.OptionRequestContentType // Hide hides the route from the OpenAPI spec. var Hide = fuego.OptionHide +// DefaultStatusCode sets the default status code for the route. var DefaultStatusCode = fuego.OptionDefaultStatusCode From d0ece7c93b7329843639309b8748834977357863 Mon Sep 17 00:00:00 2001 From: EwenQuim Date: Tue, 10 Dec 2024 15:25:31 +0100 Subject: [PATCH 045/138] feat: Prevents empty tags from being added to routes When a group is created with an empty path, the tag should not be added to the route. --- mux.go | 4 ++-- mux_test.go | 11 +++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/mux.go b/mux.go index 1a7aa23a..2fcccb0e 100644 --- a/mux.go +++ b/mux.go @@ -35,8 +35,8 @@ func Group(s *Server, path string, routeOptions ...func(*BaseRoute)) *Server { newServer := &ss newServer.basePath += path - if !s.disableAutoGroupTags { - newServer.routeOptions = append(s.routeOptions, OptionTags(strings.TrimLeft(path, "/"))) + if autoTag := strings.TrimLeft(path, "/"); !s.disableAutoGroupTags && autoTag != "" { + newServer.routeOptions = append(s.routeOptions, OptionTags(autoTag)) } newServer.mainRouter = s diff --git a/mux_test.go b/mux_test.go index 9f13693c..7d5f5b48 100644 --- a/mux_test.go +++ b/mux_test.go @@ -467,6 +467,17 @@ func TestGroupTagsOnRoute(t *testing.T) { require.Equal(t, []string{"my-server-tag", "my-route-tag"}, route.Operation.Tags) }) + + t.Run("do not add empty tag group", func(t *testing.T) { + s := NewServer() + groupEmpty := Group(s, "") + groupSlash := Group(s, "/") + routeEmpty := Get(groupEmpty, "/empty", dummyController) + routeSlash := Get(groupSlash, "/slash", dummyController) + + require.Nil(t, routeEmpty.Operation.Tags) + require.Nil(t, routeSlash.Operation.Tags) + }) } func TestHideOpenapiRoutes(t *testing.T) { From 3bf4734c2939349768fc1a1753fbc437fb716320 Mon Sep 17 00:00:00 2001 From: EwenQuim Date: Mon, 9 Dec 2024 11:14:30 +0100 Subject: [PATCH 046/138] Sets response headers in the OpenAPI spec --- examples/petstore/controllers/pets.go | 1 + .../lib/testdata/doc/openapi.golden.json | 14 +++++- option.go | 45 ++++++++++++++++++- option/option.go | 14 +++++- option_test.go | 15 +++++++ 5 files changed, 85 insertions(+), 4 deletions(-) diff --git a/examples/petstore/controllers/pets.go b/examples/petstore/controllers/pets.go index 8ca7245e..a0316097 100644 --- a/examples/petstore/controllers/pets.go +++ b/examples/petstore/controllers/pets.go @@ -42,6 +42,7 @@ func (rs PetsResources) Routes(s *fuego.Server) { optionPagination, option.Tags("my-tag"), option.Description("Get all pets"), + option.ResponseHeader("X-Total-Count", "Total number of pets", param.Example("42 pets", "42")), ) fuego.Get(petsGroup, "/by-age", rs.getAllPetsByAge, option.Description("Returns an array of pets grouped by age")) diff --git a/examples/petstore/lib/testdata/doc/openapi.golden.json b/examples/petstore/lib/testdata/doc/openapi.golden.json index 853aa99f..eaeb538c 100644 --- a/examples/petstore/lib/testdata/doc/openapi.golden.json +++ b/examples/petstore/lib/testdata/doc/openapi.golden.json @@ -431,7 +431,19 @@ } } }, - "description": "OK" + "description": "OK", + "headers": { + "X-Total-Count": { + "examples": { + "42 pets": { + "value": "42" + } + }, + "schema": { + "type": "string" + } + } + } }, "400": { "content": { diff --git a/option.go b/option.go index f4dd058c..33428ab7 100644 --- a/option.go +++ b/option.go @@ -149,8 +149,42 @@ func panicsIfNotCorrectType(openapiParam *openapi3.Parameter, exampleValue any) return exampleValue } -// Registers a parameter for the route. Prefer using the [Query], [QueryInt], [Header], [Cookie] shortcuts. -func OptionParam(name string, options ...func(*OpenAPIParam)) func(*BaseRoute) { +// Declare a response header for the route. +// This will be added to the OpenAPI spec, under the 200 response. +// Example: +// +// ResponseHeader("Content-Range", "Pagination range", ParamExample("42 pets", "unit 0-9/42"), ParamDescription("https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Range")) +// ResponseHeader("Set-Cookie", "Session cookie", ParamExample("session abc123", "session=abc123; Expires=Wed, 09 Jun 2021 10:18:14 GMT")) +// +// The list of options is in the param package. +func OptionResponseHeader(name, description string, options ...func(*OpenAPIParam)) func(*BaseRoute) { + _, openapiParam := buildParam(name, options...) + + openapiParam.Name = "" + openapiParam.In = "" + + return func(r *BaseRoute) { + response200 := r.Operation.Responses.Value("200") + if response200 == nil { + response := openapi3.NewResponse().WithDescription("OK") + r.Operation.AddResponse(200, response) + response200 = r.Operation.Responses.Value("200") + } + + response200headers := response200.Value.Headers + if response200headers == nil { + response200.Value.Headers = make(map[string]*openapi3.HeaderRef) + } + + response200.Value.Headers[name] = &openapi3.HeaderRef{ + Value: &openapi3.Header{ + Parameter: *openapiParam, + }, + } + } +} + +func buildParam(name string, options ...func(*OpenAPIParam)) (OpenAPIParam, *openapi3.Parameter) { param := OpenAPIParam{ Name: name, } @@ -187,6 +221,13 @@ func OptionParam(name string, options ...func(*OpenAPIParam)) func(*BaseRoute) { openapiParam.Examples[name] = &openapi3.ExampleRef{Value: exampleOpenAPI} } + return param, openapiParam +} + +// Registers a parameter for the route. Prefer using the [Query], [QueryInt], [Header], [Cookie] shortcuts. +func OptionParam(name string, options ...func(*OpenAPIParam)) func(*BaseRoute) { + param, openapiParam := buildParam(name, options...) + return func(r *BaseRoute) { r.Operation.AddParameter(openapiParam) if r.Params == nil { diff --git a/option/option.go b/option/option.go index 6abe07b3..21610d66 100644 --- a/option/option.go +++ b/option/option.go @@ -75,7 +75,19 @@ var Cookie = fuego.OptionCookie // The list of options is in the param package. var Path = fuego.OptionPath -// Registers a parameter for the route. Prefer using the [Query], [QueryInt], [Header], [Cookie] shortcuts. +// Declare a response header for the route. +// This will be added to the OpenAPI spec, under the 200 response. +// Example: +// +// ResponseHeader("Content-Range", "Pagination range", ParamExample("42 pets", "unit 0-9/42"), ParamDescription("https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Range")) +// ResponseHeader("Set-Cookie", "Session cookie", ParamExample("session abc123", "session=abc123; Expires=Wed, 09 Jun 2021 10:18:14 GMT")) +// +// The list of options is in the param package. +var ResponseHeader = fuego.OptionResponseHeader + +// Registers a parameter for the route. +// +// Deprecated: Use [Query], [QueryInt], [Header], [Cookie], [Path] instead. var Param = fuego.OptionParam // Tags adds one or more tags to the route. diff --git a/option_test.go b/option_test.go index 197abdd0..f0f358ee 100644 --- a/option_test.go +++ b/option_test.go @@ -445,6 +445,21 @@ func TestHide(t *testing.T) { }) } +func TestOptionResponseHeader(t *testing.T) { + t.Run("Declare a response header for the route", func(t *testing.T) { + s := fuego.NewServer() + + route := fuego.Get(s, "/test", helloWorld, + fuego.OptionResponseHeader("X-Test", "test header", param.Required(), param.Example("test", "My Header"), param.Default("test"), param.Description("test description")), + ) + + require.NotNil(t, route) + require.NotNil(t, route.Operation.Responses.Value("200").Value.Headers["X-Test"]) + require.Equal(t, "My Header", route.Operation.Responses.Value("200").Value.Headers["X-Test"].Value.Examples["test"].Value.Value) + require.Equal(t, "test description", route.Operation.Responses.Value("200").Value.Headers["X-Test"].Value.Description) + }) +} + func TestSecurity(t *testing.T) { t.Run("single security requirement with defined scheme", func(t *testing.T) { s := fuego.NewServer( From caac67699f9a00315b289fd48f561bd1f71e9562 Mon Sep 17 00:00:00 2001 From: EwenQuim Date: Mon, 9 Dec 2024 15:16:32 +0100 Subject: [PATCH 047/138] Supports multiple status codes for response headers --- examples/petstore/controllers/pets.go | 2 +- .../lib/testdata/doc/openapi.golden.json | 48 +++++++++++++++++-- openapi_operations.go | 11 ++++- option.go | 39 ++++++++------- option/option.go | 2 +- option_test.go | 15 +++++- param.go | 9 ++++ param/param.go | 20 +++++++- 8 files changed, 119 insertions(+), 27 deletions(-) diff --git a/examples/petstore/controllers/pets.go b/examples/petstore/controllers/pets.go index a0316097..e3bfecab 100644 --- a/examples/petstore/controllers/pets.go +++ b/examples/petstore/controllers/pets.go @@ -13,6 +13,7 @@ import ( var optionPagination = option.Group( option.QueryInt("per_page", "Number of items per page", param.Required()), option.QueryInt("page", "Page number", param.Default(1), param.Example("1st page", 1), param.Example("42nd page", 42), param.Example("100th page", 100)), + option.ResponseHeader("Content-Range", "Total number of pets", param.StatusCodes(200, 206), param.Example("42 pets", "0-10/42")), ) type PetsResources struct { @@ -42,7 +43,6 @@ func (rs PetsResources) Routes(s *fuego.Server) { optionPagination, option.Tags("my-tag"), option.Description("Get all pets"), - option.ResponseHeader("X-Total-Count", "Total number of pets", param.Example("42 pets", "42")), ) fuego.Get(petsGroup, "/by-age", rs.getAllPetsByAge, option.Description("Returns an array of pets grouped by age")) diff --git a/examples/petstore/lib/testdata/doc/openapi.golden.json b/examples/petstore/lib/testdata/doc/openapi.golden.json index eaeb538c..bed2ff64 100644 --- a/examples/petstore/lib/testdata/doc/openapi.golden.json +++ b/examples/petstore/lib/testdata/doc/openapi.golden.json @@ -243,7 +243,34 @@ } } }, - "description": "OK" + "description": "OK", + "headers": { + "Content-Range": { + "examples": { + "42 pets": { + "value": "0-10/42" + } + }, + "schema": { + "type": "string" + } + } + } + }, + "206": { + "description": "OK", + "headers": { + "Content-Range": { + "examples": { + "42 pets": { + "value": "0-10/42" + } + }, + "schema": { + "type": "string" + } + } + } }, "400": { "content": { @@ -433,10 +460,25 @@ }, "description": "OK", "headers": { - "X-Total-Count": { + "Content-Range": { + "examples": { + "42 pets": { + "value": "0-10/42" + } + }, + "schema": { + "type": "string" + } + } + } + }, + "206": { + "description": "OK", + "headers": { + "Content-Range": { "examples": { "42 pets": { - "value": "42" + "value": "0-10/42" } }, "schema": { diff --git a/openapi_operations.go b/openapi_operations.go index d182bec5..10e20073 100644 --- a/openapi_operations.go +++ b/openapi_operations.go @@ -24,11 +24,18 @@ type OpenAPIParam struct { type OpenAPIParamOption struct { Required bool Nullable bool - Default any // Default value for the parameter + // Default value for the parameter. + // Type is checked at start-time. + Default any Example string Examples map[string]any Type ParamType - GoType string // integer, string, bool + // integer, string, bool + GoType string + // Status codes for which this parameter is required. + // Only used for response parameters. + // If empty, it is required for 200 status codes. + StatusCodes []int } // Param registers a parameter for the route. diff --git a/option.go b/option.go index 33428ab7..f9eed7f9 100644 --- a/option.go +++ b/option.go @@ -150,7 +150,7 @@ func panicsIfNotCorrectType(openapiParam *openapi3.Parameter, exampleValue any) } // Declare a response header for the route. -// This will be added to the OpenAPI spec, under the 200 response. +// This will be added to the OpenAPI spec, under the given default status code response. // Example: // // ResponseHeader("Content-Range", "Pagination range", ParamExample("42 pets", "unit 0-9/42"), ParamDescription("https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Range")) @@ -158,28 +158,35 @@ func panicsIfNotCorrectType(openapiParam *openapi3.Parameter, exampleValue any) // // The list of options is in the param package. func OptionResponseHeader(name, description string, options ...func(*OpenAPIParam)) func(*BaseRoute) { - _, openapiParam := buildParam(name, options...) + apiParam, openapiParam := buildParam(name, options...) openapiParam.Name = "" openapiParam.In = "" + if len(apiParam.StatusCodes) == 0 { + apiParam.StatusCodes = []int{200} + } + return func(r *BaseRoute) { - response200 := r.Operation.Responses.Value("200") - if response200 == nil { - response := openapi3.NewResponse().WithDescription("OK") - r.Operation.AddResponse(200, response) - response200 = r.Operation.Responses.Value("200") - } + for _, code := range apiParam.StatusCodes { + codeString := strconv.Itoa(code) + responseForCurrentCode := r.Operation.Responses.Value(codeString) + if responseForCurrentCode == nil { + response := openapi3.NewResponse().WithDescription("OK") + r.Operation.AddResponse(code, response) + responseForCurrentCode = r.Operation.Responses.Value(codeString) + } - response200headers := response200.Value.Headers - if response200headers == nil { - response200.Value.Headers = make(map[string]*openapi3.HeaderRef) - } + responseForCurrentCodeHeaders := responseForCurrentCode.Value.Headers + if responseForCurrentCodeHeaders == nil { + responseForCurrentCode.Value.Headers = make(map[string]*openapi3.HeaderRef) + } - response200.Value.Headers[name] = &openapi3.HeaderRef{ - Value: &openapi3.Header{ - Parameter: *openapiParam, - }, + responseForCurrentCode.Value.Headers[name] = &openapi3.HeaderRef{ + Value: &openapi3.Header{ + Parameter: *openapiParam, + }, + } } } } diff --git a/option/option.go b/option/option.go index 21610d66..050bcb06 100644 --- a/option/option.go +++ b/option/option.go @@ -76,7 +76,7 @@ var Cookie = fuego.OptionCookie var Path = fuego.OptionPath // Declare a response header for the route. -// This will be added to the OpenAPI spec, under the 200 response. +// This will be added to the OpenAPI spec, under the given default status code response. // Example: // // ResponseHeader("Content-Range", "Pagination range", ParamExample("42 pets", "unit 0-9/42"), ParamDescription("https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Range")) diff --git a/option_test.go b/option_test.go index f0f358ee..6586e98a 100644 --- a/option_test.go +++ b/option_test.go @@ -450,14 +450,25 @@ func TestOptionResponseHeader(t *testing.T) { s := fuego.NewServer() route := fuego.Get(s, "/test", helloWorld, - fuego.OptionResponseHeader("X-Test", "test header", param.Required(), param.Example("test", "My Header"), param.Default("test"), param.Description("test description")), + fuego.OptionResponseHeader("X-Test", "test header", param.Example("test", "My Header"), param.Default("test"), param.Description("test description")), ) - require.NotNil(t, route) require.NotNil(t, route.Operation.Responses.Value("200").Value.Headers["X-Test"]) require.Equal(t, "My Header", route.Operation.Responses.Value("200").Value.Headers["X-Test"].Value.Examples["test"].Value.Value) require.Equal(t, "test description", route.Operation.Responses.Value("200").Value.Headers["X-Test"].Value.Description) }) + + t.Run("Declare a response header for the route with multiple status codes", func(t *testing.T) { + s := fuego.NewServer() + + route := fuego.Get(s, "/test", helloWorld, + fuego.OptionResponseHeader("X-Test", "test header", param.StatusCodes(200, 206)), + ) + + require.NotNil(t, route.Operation.Responses.Value("200").Value.Headers["X-Test"]) + require.NotNil(t, route.Operation.Responses.Value("206").Value.Headers["X-Test"]) + require.Nil(t, route.Operation.Responses.Value("400").Value.Headers["X-Test"]) + }) } func TestSecurity(t *testing.T) { diff --git a/param.go b/param.go index c441e709..a679e254 100644 --- a/param.go +++ b/param.go @@ -51,3 +51,12 @@ func ParamExample(exampleName string, value any) func(param *OpenAPIParam) { param.Examples[exampleName] = value } } + +// StatusCodes sets the status codes for which this parameter is required. +// Only used for response parameters. +// If empty, it is required for 200 status codes. +func ParamStatusCodes(codes ...int) func(param *OpenAPIParam) { + return func(param *OpenAPIParam) { + param.StatusCodes = codes + } +} diff --git a/param/param.go b/param/param.go index ad5dbd47..132c2927 100644 --- a/param/param.go +++ b/param/param.go @@ -2,18 +2,34 @@ package param import "github.com/go-fuego/fuego" +// Required sets the parameter as required. +// If the parameter is not present, the request will fail. var Required = fuego.ParamRequired +// Nullable sets the parameter as nullable. var Nullable = fuego.ParamNullable -var String = fuego.ParamString - +// Integer sets the parameter type to integer. +// The query parameter is transmitted as a string in the URL, but it is parsed as an integer. +// Please prefer QueryInt for clarity. var Integer = fuego.ParamInteger +// Bool sets the parameter type to boolean. +// The query parameter is transmitted as a string in the URL, but it is parsed as a boolean. +// Please prefer QueryBool for clarity. var Bool = fuego.ParamBool +// Description sets the description for the parameter. var Description = fuego.ParamDescription +// Default sets the default value for the parameter. +// Type is checked at start-time. var Default = fuego.ParamDefault +// Example adds an example to the parameter. As per the OpenAPI 3.0 standard, the example must be given a name. var Example = fuego.ParamExample + +// StatusCodes sets the status codes for which this parameter is required. +// Only used for response parameters. +// If empty, it is required for 200 status codes. +var StatusCodes = fuego.ParamStatusCodes From 19a76d1a892dd61f98abb9fcf4e5bc1c787d3847 Mon Sep 17 00:00:00 2001 From: EwenQuim Date: Wed, 11 Dec 2024 15:01:28 +0100 Subject: [PATCH 048/138] 2025 roadmap announcement in README --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 878d20de..6c3abd10 100644 --- a/README.md +++ b/README.md @@ -12,13 +12,13 @@ > The framework for busy Go developers -**Build your API or web application in minutes!** +🚀 **Explore and contribute to our [2025 Roadmap](https://github.com/go-fuego/fuego/discussions/263)!** 🚀 -Go framework generating OpenAPI documentation from code. +Production-ready Go API framework generating OpenAPI documentation from code. Inspired by Nest, built for Go developers. -Also empowers `html/template`, `a-h/templ` and `maragudk/gomponents`: -see [the example](./examples/full-app-gourmet) - actually running [in prod](https://gourmet.quimerch.com)! +Also empowers templating with `html/template`, `a-h/templ` and `maragudk/gomponents`: +see [the example](./examples/full-app-gourmet) [running live](https://gourmet.quimerch.com). ## Sponsors From 8a613313c19f4adfa6bc4f008e584d6a8c6eb7bd Mon Sep 17 00:00:00 2001 From: EwenQuim Date: Fri, 13 Dec 2024 09:30:19 +0100 Subject: [PATCH 049/138] deps: Bumps all dependencies --- cmd/fuego/go.mod | 2 +- cmd/fuego/go.sum | 4 ++-- examples/acme-tls/go.mod | 2 +- examples/acme-tls/go.sum | 4 ++-- examples/basic/go.mod | 2 +- examples/basic/go.sum | 4 ++-- examples/custom-errors/go.mod | 4 ++-- examples/custom-errors/go.sum | 8 ++++---- examples/custom-serializer/go.mod | 2 +- examples/custom-serializer/go.sum | 4 ++-- examples/full-app-gourmet/go.mod | 8 ++++---- examples/full-app-gourmet/go.sum | 8 ++++---- examples/generate-opengraph-image/go.mod | 4 ++-- examples/generate-opengraph-image/go.sum | 8 ++++---- examples/hello-world/go.mod | 2 +- examples/hello-world/go.sum | 4 ++-- examples/openapi/go.mod | 2 +- examples/openapi/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- middleware/basicauth/go.mod | 2 +- middleware/basicauth/go.sum | 4 ++-- middleware/cache/go.sum | 4 ++++ testing-from-outside/go.sum | 3 +++ 24 files changed, 51 insertions(+), 44 deletions(-) diff --git a/cmd/fuego/go.mod b/cmd/fuego/go.mod index 8bdac651..b5a2d247 100644 --- a/cmd/fuego/go.mod +++ b/cmd/fuego/go.mod @@ -32,7 +32,7 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect - golang.org/x/crypto v0.30.0 // indirect + golang.org/x/crypto v0.31.0 // indirect golang.org/x/net v0.32.0 // indirect golang.org/x/sys v0.28.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/cmd/fuego/go.sum b/cmd/fuego/go.sum index b085dd5d..5a13b80d 100644 --- a/cmd/fuego/go.sum +++ b/cmd/fuego/go.sum @@ -58,8 +58,8 @@ github.com/urfave/cli/v2 v2.27.5 h1:WoHEJLdsXr6dDWoJgMq/CboDmyY/8HMMH1fTECbih+w= github.com/urfave/cli/v2 v2.27.5/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ= github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4= github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM= -golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY= -golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs= golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= diff --git a/examples/acme-tls/go.mod b/examples/acme-tls/go.mod index 9eb714b9..c40b192a 100644 --- a/examples/acme-tls/go.mod +++ b/examples/acme-tls/go.mod @@ -31,7 +31,7 @@ require ( github.com/zeebo/blake3 v0.2.4 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect - golang.org/x/crypto v0.30.0 // indirect + golang.org/x/crypto v0.31.0 // indirect golang.org/x/mod v0.22.0 // indirect golang.org/x/net v0.32.0 // indirect golang.org/x/sync v0.10.0 // indirect diff --git a/examples/acme-tls/go.sum b/examples/acme-tls/go.sum index 359b7ea9..ece17be1 100644 --- a/examples/acme-tls/go.sum +++ b/examples/acme-tls/go.sum @@ -76,8 +76,8 @@ go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY= -golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4= golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= diff --git a/examples/basic/go.mod b/examples/basic/go.mod index 4b57f340..b0ca4cc2 100644 --- a/examples/basic/go.mod +++ b/examples/basic/go.mod @@ -24,7 +24,7 @@ require ( github.com/mailru/easyjson v0.7.7 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect - golang.org/x/crypto v0.30.0 // indirect + golang.org/x/crypto v0.31.0 // indirect golang.org/x/net v0.32.0 // indirect golang.org/x/sys v0.28.0 // indirect golang.org/x/text v0.21.0 // indirect diff --git a/examples/basic/go.sum b/examples/basic/go.sum index 3b64f69f..4116f07a 100644 --- a/examples/basic/go.sum +++ b/examples/basic/go.sum @@ -54,8 +54,8 @@ github.com/thejerf/slogassert v0.3.4 h1:VoTsXixRbXMrRSSxDjYTiEDCM4VWbsYPW5rB/hX2 github.com/thejerf/slogassert v0.3.4/go.mod h1:0zn9ISLVKo1aPMTqcGfG1o6dWwt+Rk574GlUxHD4rs8= github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= -golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY= -golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs= golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= diff --git a/examples/custom-errors/go.mod b/examples/custom-errors/go.mod index 6b645fc2..2ec98ad0 100644 --- a/examples/custom-errors/go.mod +++ b/examples/custom-errors/go.mod @@ -4,7 +4,7 @@ go 1.22.2 require ( github.com/go-chi/chi/v5 v5.1.0 - github.com/go-fuego/fuego v0.15.1 + github.com/go-fuego/fuego v0.16.1 github.com/rs/cors v1.11.1 ) @@ -24,7 +24,7 @@ require ( github.com/mailru/easyjson v0.7.7 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect - golang.org/x/crypto v0.30.0 // indirect + golang.org/x/crypto v0.31.0 // indirect golang.org/x/net v0.32.0 // indirect golang.org/x/sys v0.28.0 // indirect golang.org/x/text v0.21.0 // indirect diff --git a/examples/custom-errors/go.sum b/examples/custom-errors/go.sum index 6936a3f1..4116f07a 100644 --- a/examples/custom-errors/go.sum +++ b/examples/custom-errors/go.sum @@ -6,8 +6,8 @@ github.com/getkin/kin-openapi v0.128.0 h1:jqq3D9vC9pPq1dGcOCv7yOp1DaEe7c/T1vzcLb github.com/getkin/kin-openapi v0.128.0/go.mod h1:OZrfXzUfGrNbsKj+xmFBx6E5c6yH3At/tAKSc2UszXM= github.com/go-chi/chi/v5 v5.1.0 h1:acVI1TYaD+hhedDJ3r54HyA6sExp3HfXq7QWEEY/xMw= github.com/go-chi/chi/v5 v5.1.0/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= -github.com/go-fuego/fuego v0.15.1 h1:9ESspiRFeUmSl2YdZzL5VE+8F2sGYSTBRkGJEfvoLXc= -github.com/go-fuego/fuego v0.15.1/go.mod h1:XMpAQQnZsoMON0UD6ncvzj6YukGQlNECDcINJt49zx4= +github.com/go-fuego/fuego v0.16.1 h1:G+sDF55BjFI7FH7dd07HDx4jfNPxXEeab+YKuLjj5zY= +github.com/go-fuego/fuego v0.16.1/go.mod h1:ARPlRxY+RgbahF6ZvnjsESGQd3h/jCw8ksCJxKLbgjY= github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= @@ -54,8 +54,8 @@ github.com/thejerf/slogassert v0.3.4 h1:VoTsXixRbXMrRSSxDjYTiEDCM4VWbsYPW5rB/hX2 github.com/thejerf/slogassert v0.3.4/go.mod h1:0zn9ISLVKo1aPMTqcGfG1o6dWwt+Rk574GlUxHD4rs8= github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= -golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY= -golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs= golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= diff --git a/examples/custom-serializer/go.mod b/examples/custom-serializer/go.mod index 6c96474d..465b365c 100644 --- a/examples/custom-serializer/go.mod +++ b/examples/custom-serializer/go.mod @@ -25,7 +25,7 @@ require ( github.com/modern-go/reflect2 v1.0.2 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect - golang.org/x/crypto v0.30.0 // indirect + golang.org/x/crypto v0.31.0 // indirect golang.org/x/net v0.32.0 // indirect golang.org/x/sys v0.28.0 // indirect golang.org/x/text v0.21.0 // indirect diff --git a/examples/custom-serializer/go.sum b/examples/custom-serializer/go.sum index f4f2dd9c..cfa75374 100644 --- a/examples/custom-serializer/go.sum +++ b/examples/custom-serializer/go.sum @@ -61,8 +61,8 @@ github.com/thejerf/slogassert v0.3.4 h1:VoTsXixRbXMrRSSxDjYTiEDCM4VWbsYPW5rB/hX2 github.com/thejerf/slogassert v0.3.4/go.mod h1:0zn9ISLVKo1aPMTqcGfG1o6dWwt+Rk574GlUxHD4rs8= github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= -golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY= -golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs= golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= diff --git a/examples/full-app-gourmet/go.mod b/examples/full-app-gourmet/go.mod index 9b1ff8c7..cdcc098d 100644 --- a/examples/full-app-gourmet/go.mod +++ b/examples/full-app-gourmet/go.mod @@ -8,9 +8,9 @@ require ( github.com/a-h/templ v0.2.793 github.com/go-chi/chi/v5 v5.1.0 github.com/go-fuego/fuego v0.16.1 - github.com/go-fuego/fuego/extra/markdown v0.0.0-20241209141708-1e6d931908a8 + github.com/go-fuego/fuego/extra/markdown v0.0.0-20241211140128-19a76d1a892d github.com/go-fuego/fuego/middleware/basicauth v0.15.1 - github.com/go-fuego/fuego/middleware/cache v0.0.0-20241209141708-1e6d931908a8 + github.com/go-fuego/fuego/middleware/cache v0.0.0-20241211140128-19a76d1a892d github.com/golang-jwt/jwt/v5 v5.2.1 github.com/golang-migrate/migrate/v4 v4.18.1 github.com/google/uuid v1.6.0 @@ -48,8 +48,8 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect go.uber.org/atomic v1.11.0 // indirect - golang.org/x/crypto v0.30.0 // indirect - golang.org/x/exp v0.0.0-20241204233417-43b7b7cde48d // indirect + golang.org/x/crypto v0.31.0 // indirect + golang.org/x/exp v0.0.0-20241210194714-1829a127f884 // indirect golang.org/x/net v0.32.0 // indirect golang.org/x/sys v0.28.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/examples/full-app-gourmet/go.sum b/examples/full-app-gourmet/go.sum index f25602eb..0d7d36fc 100644 --- a/examples/full-app-gourmet/go.sum +++ b/examples/full-app-gourmet/go.sum @@ -89,10 +89,10 @@ github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0 github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY= -golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= -golang.org/x/exp v0.0.0-20241204233417-43b7b7cde48d h1:0olWaB5pg3+oychR51GUVCEsGkeCU/2JxjBgIo4f3M0= -golang.org/x/exp v0.0.0-20241204233417-43b7b7cde48d/go.mod h1:qj5a5QZpwLU2NLQudwIN5koi3beDhSAlJwa67PuM98c= +golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/exp v0.0.0-20241210194714-1829a127f884 h1:Y/Mj/94zIQQGHVSv1tTtQBDaQaJe62U9bkDZKKyhPCU= +golang.org/x/exp v0.0.0-20241210194714-1829a127f884/go.mod h1:qj5a5QZpwLU2NLQudwIN5koi3beDhSAlJwa67PuM98c= golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4= golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= diff --git a/examples/generate-opengraph-image/go.mod b/examples/generate-opengraph-image/go.mod index 9854281b..57f4f92b 100644 --- a/examples/generate-opengraph-image/go.mod +++ b/examples/generate-opengraph-image/go.mod @@ -5,7 +5,7 @@ go 1.23.3 require ( github.com/getkin/kin-openapi v0.128.0 github.com/go-fuego/fuego v0.16.1 - github.com/go-fuego/fuego/middleware/cache v0.0.0-20241209141708-1e6d931908a8 + github.com/go-fuego/fuego/middleware/cache v0.0.0-20241211140128-19a76d1a892d github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 golang.org/x/image v0.23.0 ) @@ -26,7 +26,7 @@ require ( github.com/mailru/easyjson v0.7.7 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect - golang.org/x/crypto v0.30.0 // indirect + golang.org/x/crypto v0.31.0 // indirect golang.org/x/net v0.32.0 // indirect golang.org/x/sys v0.28.0 // indirect golang.org/x/text v0.21.0 // indirect diff --git a/examples/generate-opengraph-image/go.sum b/examples/generate-opengraph-image/go.sum index eae22087..20c0ea61 100644 --- a/examples/generate-opengraph-image/go.sum +++ b/examples/generate-opengraph-image/go.sum @@ -6,8 +6,8 @@ github.com/getkin/kin-openapi v0.128.0 h1:jqq3D9vC9pPq1dGcOCv7yOp1DaEe7c/T1vzcLb github.com/getkin/kin-openapi v0.128.0/go.mod h1:OZrfXzUfGrNbsKj+xmFBx6E5c6yH3At/tAKSc2UszXM= github.com/go-fuego/fuego v0.16.1 h1:G+sDF55BjFI7FH7dd07HDx4jfNPxXEeab+YKuLjj5zY= github.com/go-fuego/fuego v0.16.1/go.mod h1:ARPlRxY+RgbahF6ZvnjsESGQd3h/jCw8ksCJxKLbgjY= -github.com/go-fuego/fuego/middleware/cache v0.0.0-20241209141708-1e6d931908a8 h1:7hIXyQTtRGo1YhYz+PYNQ5hU3BCJWgHKf3dF9PhAUqk= -github.com/go-fuego/fuego/middleware/cache v0.0.0-20241209141708-1e6d931908a8/go.mod h1:/9X4N39tE56XMv484IlTOMVL9WC+od7nyoG0yDg60Mo= +github.com/go-fuego/fuego/middleware/cache v0.0.0-20241211140128-19a76d1a892d h1:5ltEcAZGWJ8atk1MGYcgHrsJC6MWoUrAQ8xs20bt9hY= +github.com/go-fuego/fuego/middleware/cache v0.0.0-20241211140128-19a76d1a892d/go.mod h1:1X75DId7/U/PJ+qPOqQePEyxj8u3FV6MzJw7oc+INL8= github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= @@ -56,8 +56,8 @@ github.com/thejerf/slogassert v0.3.4 h1:VoTsXixRbXMrRSSxDjYTiEDCM4VWbsYPW5rB/hX2 github.com/thejerf/slogassert v0.3.4/go.mod h1:0zn9ISLVKo1aPMTqcGfG1o6dWwt+Rk574GlUxHD4rs8= github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= -golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY= -golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/image v0.23.0 h1:HseQ7c2OpPKTPVzNjG5fwJsOTCiiwS4QdsYi5XU6H68= golang.org/x/image v0.23.0/go.mod h1:wJJBTdLfCCf3tiHa1fNxpZmUI4mmoZvwMCPP0ddoNKY= golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= diff --git a/examples/hello-world/go.mod b/examples/hello-world/go.mod index 3b020b6f..68c7b73c 100644 --- a/examples/hello-world/go.mod +++ b/examples/hello-world/go.mod @@ -20,7 +20,7 @@ require ( github.com/mailru/easyjson v0.7.7 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect - golang.org/x/crypto v0.30.0 // indirect + golang.org/x/crypto v0.31.0 // indirect golang.org/x/net v0.32.0 // indirect golang.org/x/sys v0.28.0 // indirect golang.org/x/text v0.21.0 // indirect diff --git a/examples/hello-world/go.sum b/examples/hello-world/go.sum index e9853e49..07dcf4ad 100644 --- a/examples/hello-world/go.sum +++ b/examples/hello-world/go.sum @@ -50,8 +50,8 @@ github.com/thejerf/slogassert v0.3.4 h1:VoTsXixRbXMrRSSxDjYTiEDCM4VWbsYPW5rB/hX2 github.com/thejerf/slogassert v0.3.4/go.mod h1:0zn9ISLVKo1aPMTqcGfG1o6dWwt+Rk574GlUxHD4rs8= github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= -golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY= -golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs= golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= diff --git a/examples/openapi/go.mod b/examples/openapi/go.mod index 6e39842b..a981b0b3 100644 --- a/examples/openapi/go.mod +++ b/examples/openapi/go.mod @@ -20,7 +20,7 @@ require ( github.com/mailru/easyjson v0.7.7 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect - golang.org/x/crypto v0.30.0 // indirect + golang.org/x/crypto v0.31.0 // indirect golang.org/x/net v0.32.0 // indirect golang.org/x/sys v0.28.0 // indirect golang.org/x/text v0.21.0 // indirect diff --git a/examples/openapi/go.sum b/examples/openapi/go.sum index e9853e49..07dcf4ad 100644 --- a/examples/openapi/go.sum +++ b/examples/openapi/go.sum @@ -50,8 +50,8 @@ github.com/thejerf/slogassert v0.3.4 h1:VoTsXixRbXMrRSSxDjYTiEDCM4VWbsYPW5rB/hX2 github.com/thejerf/slogassert v0.3.4/go.mod h1:0zn9ISLVKo1aPMTqcGfG1o6dWwt+Rk574GlUxHD4rs8= github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= -golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY= -golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs= golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= diff --git a/go.mod b/go.mod index 7a0e8573..c7555029 100644 --- a/go.mod +++ b/go.mod @@ -28,7 +28,7 @@ require ( github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - golang.org/x/crypto v0.30.0 // indirect + golang.org/x/crypto v0.31.0 // indirect golang.org/x/net v0.32.0 // indirect golang.org/x/sys v0.28.0 // indirect golang.org/x/text v0.21.0 // indirect diff --git a/go.sum b/go.sum index 0d6b0cf2..ae553362 100644 --- a/go.sum +++ b/go.sum @@ -50,8 +50,8 @@ github.com/thejerf/slogassert v0.3.4 h1:VoTsXixRbXMrRSSxDjYTiEDCM4VWbsYPW5rB/hX2 github.com/thejerf/slogassert v0.3.4/go.mod h1:0zn9ISLVKo1aPMTqcGfG1o6dWwt+Rk574GlUxHD4rs8= github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= -golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY= -golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs= golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= diff --git a/middleware/basicauth/go.mod b/middleware/basicauth/go.mod index f6e9efa6..b2cc896b 100644 --- a/middleware/basicauth/go.mod +++ b/middleware/basicauth/go.mod @@ -25,7 +25,7 @@ require ( github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - golang.org/x/crypto v0.30.0 // indirect + golang.org/x/crypto v0.31.0 // indirect golang.org/x/net v0.32.0 // indirect golang.org/x/sys v0.28.0 // indirect golang.org/x/text v0.21.0 // indirect diff --git a/middleware/basicauth/go.sum b/middleware/basicauth/go.sum index e9853e49..07dcf4ad 100644 --- a/middleware/basicauth/go.sum +++ b/middleware/basicauth/go.sum @@ -50,8 +50,8 @@ github.com/thejerf/slogassert v0.3.4 h1:VoTsXixRbXMrRSSxDjYTiEDCM4VWbsYPW5rB/hX2 github.com/thejerf/slogassert v0.3.4/go.mod h1:0zn9ISLVKo1aPMTqcGfG1o6dWwt+Rk574GlUxHD4rs8= github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= -golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY= -golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs= golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= diff --git a/middleware/cache/go.sum b/middleware/cache/go.sum index 1955bf17..d677c627 100644 --- a/middleware/cache/go.sum +++ b/middleware/cache/go.sum @@ -53,9 +53,13 @@ github.com/thejerf/slogassert v0.3.4/go.mod h1:0zn9ISLVKo1aPMTqcGfG1o6dWwt+Rk574 github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY= +golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= +golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs= golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/testing-from-outside/go.sum b/testing-from-outside/go.sum index 242c29f1..04ad0449 100644 --- a/testing-from-outside/go.sum +++ b/testing-from-outside/go.sum @@ -53,8 +53,11 @@ github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY= +golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= +golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs= golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= From e912a128592d9ea9834c26e3575be6bc803eac15 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 13 Dec 2024 08:35:56 +0000 Subject: [PATCH 050/138] chore(deps): bump the npm_and_yarn group across 1 directory with 16 updates Bumps the npm_and_yarn group with 12 updates in the /documentation directory: | Package | From | To | | --- | --- | --- | | [body-parser](https://github.com/expressjs/body-parser) | `1.20.1` | `1.20.3` | | [express](https://github.com/expressjs/express) | `4.18.2` | `4.21.2` | | [braces](https://github.com/micromatch/braces) | `3.0.2` | `3.0.3` | | [cross-spawn](https://github.com/moxystudio/node-cross-spawn) | `7.0.3` | `7.0.6` | | [dompurify](https://github.com/cure53/DOMPurify) | `3.0.8` | `3.2.3` | | [follow-redirects](https://github.com/follow-redirects/follow-redirects) | `1.15.5` | `1.15.9` | | [http-proxy-middleware](https://github.com/chimurai/http-proxy-middleware) | `2.0.6` | `2.0.7` | | [mermaid](https://github.com/mermaid-js/mermaid) | `10.8.0` | `10.9.3` | | [micromatch](https://github.com/micromatch/micromatch) | `4.0.5` | `4.0.8` | | [nanoid](https://github.com/ai/nanoid) | `3.3.7` | `3.3.8` | | [webpack](https://github.com/webpack/webpack) | `5.89.0` | `5.97.1` | | [webpack-dev-middleware](https://github.com/webpack/webpack-dev-middleware) | `5.3.3` | `5.3.4` | Updates `body-parser` from 1.20.1 to 1.20.3 - [Release notes](https://github.com/expressjs/body-parser/releases) - [Changelog](https://github.com/expressjs/body-parser/blob/master/HISTORY.md) - [Commits](https://github.com/expressjs/body-parser/compare/1.20.1...1.20.3) Updates `express` from 4.18.2 to 4.21.2 - [Release notes](https://github.com/expressjs/express/releases) - [Changelog](https://github.com/expressjs/express/blob/4.21.2/History.md) - [Commits](https://github.com/expressjs/express/compare/4.18.2...4.21.2) Updates `braces` from 3.0.2 to 3.0.3 - [Changelog](https://github.com/micromatch/braces/blob/master/CHANGELOG.md) - [Commits](https://github.com/micromatch/braces/compare/3.0.2...3.0.3) Updates `cookie` from 0.5.0 to 0.7.1 - [Release notes](https://github.com/jshttp/cookie/releases) - [Commits](https://github.com/jshttp/cookie/compare/v0.5.0...v0.7.1) Updates `cross-spawn` from 7.0.3 to 7.0.6 - [Changelog](https://github.com/moxystudio/node-cross-spawn/blob/master/CHANGELOG.md) - [Commits](https://github.com/moxystudio/node-cross-spawn/compare/v7.0.3...v7.0.6) Updates `dompurify` from 3.0.8 to 3.2.3 - [Release notes](https://github.com/cure53/DOMPurify/releases) - [Commits](https://github.com/cure53/DOMPurify/compare/3.0.8...3.2.3) Updates `express` from 4.18.2 to 4.21.2 - [Release notes](https://github.com/expressjs/express/releases) - [Changelog](https://github.com/expressjs/express/blob/4.21.2/History.md) - [Commits](https://github.com/expressjs/express/compare/4.18.2...4.21.2) Updates `path-to-regexp` from 0.1.7 to 0.1.12 - [Release notes](https://github.com/pillarjs/path-to-regexp/releases) - [Changelog](https://github.com/pillarjs/path-to-regexp/blob/master/History.md) - [Commits](https://github.com/pillarjs/path-to-regexp/compare/v0.1.7...v0.1.12) Updates `follow-redirects` from 1.15.5 to 1.15.9 - [Release notes](https://github.com/follow-redirects/follow-redirects/releases) - [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.15.5...v1.15.9) Updates `http-proxy-middleware` from 2.0.6 to 2.0.7 - [Release notes](https://github.com/chimurai/http-proxy-middleware/releases) - [Changelog](https://github.com/chimurai/http-proxy-middleware/blob/v2.0.7/CHANGELOG.md) - [Commits](https://github.com/chimurai/http-proxy-middleware/compare/v2.0.6...v2.0.7) Updates `mermaid` from 10.8.0 to 10.9.3 - [Release notes](https://github.com/mermaid-js/mermaid/releases) - [Changelog](https://github.com/mermaid-js/mermaid/blob/develop/CHANGELOG.md) - [Commits](https://github.com/mermaid-js/mermaid/compare/v10.8.0...v10.9.3) Updates `micromatch` from 4.0.5 to 4.0.8 - [Release notes](https://github.com/micromatch/micromatch/releases) - [Changelog](https://github.com/micromatch/micromatch/blob/master/CHANGELOG.md) - [Commits](https://github.com/micromatch/micromatch/compare/4.0.5...4.0.8) Updates `nanoid` from 3.3.7 to 3.3.8 - [Release notes](https://github.com/ai/nanoid/releases) - [Changelog](https://github.com/ai/nanoid/blob/main/CHANGELOG.md) - [Commits](https://github.com/ai/nanoid/compare/3.3.7...3.3.8) Updates `send` from 0.18.0 to 0.19.0 - [Release notes](https://github.com/pillarjs/send/releases) - [Changelog](https://github.com/pillarjs/send/blob/master/HISTORY.md) - [Commits](https://github.com/pillarjs/send/compare/0.18.0...0.19.0) Updates `serve-static` from 1.15.0 to 1.16.2 - [Release notes](https://github.com/expressjs/serve-static/releases) - [Changelog](https://github.com/expressjs/serve-static/blob/v1.16.2/HISTORY.md) - [Commits](https://github.com/expressjs/serve-static/compare/v1.15.0...v1.16.2) Updates `webpack` from 5.89.0 to 5.97.1 - [Release notes](https://github.com/webpack/webpack/releases) - [Commits](https://github.com/webpack/webpack/compare/v5.89.0...v5.97.1) Updates `webpack-dev-middleware` from 5.3.3 to 5.3.4 - [Release notes](https://github.com/webpack/webpack-dev-middleware/releases) - [Changelog](https://github.com/webpack/webpack-dev-middleware/blob/v5.3.4/CHANGELOG.md) - [Commits](https://github.com/webpack/webpack-dev-middleware/compare/v5.3.3...v5.3.4) --- updated-dependencies: - dependency-name: body-parser dependency-type: indirect dependency-group: npm_and_yarn - dependency-name: express dependency-type: indirect dependency-group: npm_and_yarn - dependency-name: braces dependency-type: indirect dependency-group: npm_and_yarn - dependency-name: cookie dependency-type: indirect dependency-group: npm_and_yarn - dependency-name: cross-spawn dependency-type: indirect dependency-group: npm_and_yarn - dependency-name: dompurify dependency-type: indirect dependency-group: npm_and_yarn - dependency-name: express dependency-type: indirect dependency-group: npm_and_yarn - dependency-name: path-to-regexp dependency-type: indirect dependency-group: npm_and_yarn - dependency-name: follow-redirects dependency-type: indirect dependency-group: npm_and_yarn - dependency-name: http-proxy-middleware dependency-type: indirect dependency-group: npm_and_yarn - dependency-name: mermaid dependency-type: indirect dependency-group: npm_and_yarn - dependency-name: micromatch dependency-type: indirect dependency-group: npm_and_yarn - dependency-name: nanoid dependency-type: indirect dependency-group: npm_and_yarn - dependency-name: send dependency-type: indirect dependency-group: npm_and_yarn - dependency-name: serve-static dependency-type: indirect dependency-group: npm_and_yarn - dependency-name: webpack dependency-type: indirect dependency-group: npm_and_yarn - dependency-name: webpack-dev-middleware dependency-type: indirect dependency-group: npm_and_yarn ... Signed-off-by: dependabot[bot] --- documentation/package-lock.json | 733 ++++++++++++++++++++------------ 1 file changed, 451 insertions(+), 282 deletions(-) diff --git a/documentation/package-lock.json b/documentation/package-lock.json index 7b679209..b065d723 100644 --- a/documentation/package-lock.json +++ b/documentation/package-lock.json @@ -3413,9 +3413,9 @@ } }, "node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==" + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==" }, "node_modules/@types/estree-jsx": { "version": "1.0.4", @@ -3707,133 +3707,133 @@ "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==" }, "node_modules/@webassemblyjs/ast": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", - "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", + "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", "dependencies": { - "@webassemblyjs/helper-numbers": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + "@webassemblyjs/helper-numbers": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2" } }, "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", - "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==" + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", + "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==" }, "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", - "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==" + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", + "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==" }, "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz", - "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==" + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", + "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==" }, "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", - "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", + "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.11.6", - "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/floating-point-hex-parser": "1.13.2", + "@webassemblyjs/helper-api-error": "1.13.2", "@xtuc/long": "4.2.2" } }, "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", - "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==" + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", + "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==" }, "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz", - "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", + "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/wasm-gen": "1.14.1" } }, "node_modules/@webassemblyjs/ieee754": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", - "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", + "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", "dependencies": { "@xtuc/ieee754": "^1.2.0" } }, "node_modules/@webassemblyjs/leb128": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", - "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", + "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", "dependencies": { "@xtuc/long": "4.2.2" } }, "node_modules/@webassemblyjs/utf8": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", - "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==" + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", + "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==" }, "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz", - "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", + "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/helper-wasm-section": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6", - "@webassemblyjs/wasm-opt": "1.11.6", - "@webassemblyjs/wasm-parser": "1.11.6", - "@webassemblyjs/wast-printer": "1.11.6" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/helper-wasm-section": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-opt": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1", + "@webassemblyjs/wast-printer": "1.14.1" } }, "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz", - "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", + "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" } }, "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz", - "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", + "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6", - "@webassemblyjs/wasm-parser": "1.11.6" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1" } }, "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz", - "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", + "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-api-error": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-api-error": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" } }, "node_modules/@webassemblyjs/wast-printer": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz", - "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", + "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", "dependencies": { - "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/ast": "1.14.1", "@xtuc/long": "4.2.2" } }, @@ -3884,9 +3884,9 @@ } }, "node_modules/acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", "bin": { "acorn": "bin/acorn" }, @@ -3894,14 +3894,6 @@ "node": ">=0.4.0" } }, - "node_modules/acorn-import-assertions": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", - "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", - "peerDependencies": { - "acorn": "^8" - } - }, "node_modules/acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", @@ -4299,20 +4291,20 @@ } }, "node_modules/body-parser": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", - "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", "dependencies": { "bytes": "3.1.2", - "content-type": "~1.0.4", + "content-type": "~1.0.5", "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", "http-errors": "2.0.0", "iconv-lite": "0.4.24", "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.1", + "qs": "6.13.0", + "raw-body": "2.5.2", "type-is": "~1.6.18", "unpipe": "1.0.0" }, @@ -4387,20 +4379,20 @@ } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" } }, "node_modules/browserslist": { - "version": "4.22.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz", - "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==", + "version": "4.24.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz", + "integrity": "sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==", "funding": [ { "type": "opencollective", @@ -4416,10 +4408,10 @@ } ], "dependencies": { - "caniuse-lite": "^1.0.30001565", - "electron-to-chromium": "^1.4.601", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.13" + "caniuse-lite": "^1.0.30001669", + "electron-to-chromium": "^1.5.41", + "node-releases": "^2.0.18", + "update-browserslist-db": "^1.1.1" }, "bin": { "browserslist": "cli.js" @@ -4478,13 +4470,44 @@ } }, "node_modules/call-bind": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", - "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", "dependencies": { - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.1", - "set-function-length": "^1.1.1" + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.1.tgz", + "integrity": "sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.2.tgz", + "integrity": "sha512-0lk0PHFe/uz0vl527fG9CgdE9WdafjDbCXvBbs+LUv000TVt2Jjhqbs4Jwm8gz070w8xXyEAxrPOMullsxXeGg==", + "dependencies": { + "call-bind": "^1.0.8", + "get-intrinsic": "^1.2.5" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -4530,9 +4553,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001579", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001579.tgz", - "integrity": "sha512-u5AUVkixruKHJjw/pj9wISlcMpgFWzSrczLZbrqBSxukQixmg0SJ5sZTpvaFvxU0HoQKd4yoyAogyrAz9pzJnA==", + "version": "1.0.30001688", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001688.tgz", + "integrity": "sha512-Nmqpru91cuABu/DTCXbM2NSRHzM2uVHfPnhJ/1zEAJx/ILBRVmz3pzH4N7DZqbdG0gWClsCC05Oj0mJ/1AWMbA==", "funding": [ { "type": "opencollective", @@ -5001,9 +5024,9 @@ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==" }, "node_modules/cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", "engines": { "node": ">= 0.6" } @@ -5148,9 +5171,9 @@ } }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -5997,16 +6020,19 @@ } }, "node_modules/define-data-property": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", - "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", "dependencies": { - "get-intrinsic": "^1.2.1", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/define-lazy-prop": { @@ -6369,9 +6395,9 @@ } }, "node_modules/dompurify": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.0.8.tgz", - "integrity": "sha512-b7uwreMYL2eZhrSCRC4ahLTeZcPZxSmYfmcQGXGkXiZSNW1X85v+SDM5KsWcpivIiUBH47Ji7NtyUdpLeF5JZQ==" + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.1.6.tgz", + "integrity": "sha512-cTOAhc36AalkjtBpfG6O8JimdTMWNXjiePT2xQH/ppBGi/4uIpmj8eKyIkMJErXWARyINV/sB38yf8JCLF5pbQ==" }, "node_modules/domutils": { "version": "3.1.0", @@ -6417,6 +6443,19 @@ "node": ">=8" } }, + "node_modules/dunder-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.0.tgz", + "integrity": "sha512-9+Sj30DIu+4KvHqMfLUGLFYL2PkURSYMVXJyXe92nFRvlYq5hBjLEhblKB+vkd/WVlUYMWigiY07T91Fkk0+4A==", + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/duplexer": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", @@ -6433,9 +6472,9 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/electron-to-chromium": { - "version": "1.4.637", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.637.tgz", - "integrity": "sha512-G7j3UCOukFtxVO1vWrPQUoDk3kL70mtvjc/DC/k2o7lE0wAdq+Vwp1ipagOow+BH0uVztFysLWbkM/RTIrbK3w==" + "version": "1.5.73", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.73.tgz", + "integrity": "sha512-8wGNxG9tAG5KhGd3eeA0o6ixhiNdgr0DcHWm85XPCphwZgD1lIEoi6t3VERayWao7SF7AAZTw6oARGJeVjH8Kg==" }, "node_modules/elkjs": { "version": "0.9.1", @@ -6470,17 +6509,17 @@ } }, "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", "engines": { "node": ">= 0.8" } }, "node_modules/enhanced-resolve": { - "version": "5.15.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", - "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==", + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", + "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" @@ -6508,15 +6547,42 @@ "is-arrayish": "^0.2.1" } }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/es-module-lexer": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.4.1.tgz", "integrity": "sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==" }, + "node_modules/es-object-atoms": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", + "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "engines": { "node": ">=6" } @@ -6760,36 +6826,36 @@ } }, "node_modules/express": { - "version": "4.18.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", - "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", + "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.20.1", + "body-parser": "1.20.3", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.5.0", + "cookie": "0.7.1", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "etag": "~1.8.1", - "finalhandler": "1.2.0", + "finalhandler": "1.3.1", "fresh": "0.5.2", "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", + "merge-descriptors": "1.0.3", "methods": "~1.1.2", "on-finished": "2.4.1", "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", + "path-to-regexp": "0.1.12", "proxy-addr": "~2.0.7", - "qs": "6.11.0", + "qs": "6.13.0", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", + "send": "0.19.0", + "serve-static": "1.16.2", "setprototypeof": "1.2.0", "statuses": "2.0.1", "type-is": "~1.6.18", @@ -6798,6 +6864,10 @@ }, "engines": { "node": ">= 0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/express/node_modules/content-disposition": { @@ -6825,9 +6895,9 @@ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "node_modules/express/node_modules/path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", + "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==" }, "node_modules/express/node_modules/range-parser": { "version": "1.2.1", @@ -7001,9 +7071,9 @@ } }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -7012,12 +7082,12 @@ } }, "node_modules/finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", "dependencies": { "debug": "2.6.9", - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "on-finished": "2.4.1", "parseurl": "~1.3.3", @@ -7080,9 +7150,9 @@ } }, "node_modules/follow-redirects": { - "version": "1.15.5", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", - "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==", + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", "funding": [ { "type": "individual", @@ -7352,14 +7422,23 @@ } }, "node_modules/get-intrinsic": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", - "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", - "dependencies": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.6.tgz", + "integrity": "sha512-qxsEs+9A+u85HhllWJJFicJfPDhRmjzoYdl64aMWW9yRIJmSyxdn8IEkuIM530/7T+lv0TIHd8L6Q/ra0tEoeA==", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "dunder-proto": "^1.0.0", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -7506,11 +7585,11 @@ } }, "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dependencies": { - "get-intrinsic": "^1.1.3" + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -7618,31 +7697,20 @@ } }, "node_modules/has-property-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", - "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "dependencies": { - "get-intrinsic": "^1.2.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", - "engines": { - "node": ">= 0.4" + "es-define-property": "^1.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", "engines": { "node": ">= 0.4" }, @@ -7667,9 +7735,9 @@ } }, "node_modules/hasown": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", - "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "dependencies": { "function-bind": "^1.1.2" }, @@ -8277,9 +8345,9 @@ } }, "node_modules/http-proxy-middleware": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", - "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==", + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.7.tgz", + "integrity": "sha512-fgVY8AV7qU7z/MmXJ/rxwbrtQH4jBQ9m7kp3llF0liB7glmFeVZFBepQb32T3y8n8k2+AEYuMPCpinYW+/CuRA==", "dependencies": { "@types/http-proxy": "^1.17.8", "http-proxy": "^1.18.1", @@ -8922,6 +8990,29 @@ "graceful-fs": "^4.1.6" } }, + "node_modules/katex": { + "version": "0.16.15", + "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.15.tgz", + "integrity": "sha512-yE9YJIEAk2aZ+FL/G8r+UGw0CTUzEA8ZFy6E+8tc3spHUKq3qBnzCkI1CQwGoI9atJhVyFPEypQsTY7mJ1Pi9w==", + "funding": [ + "https://opencollective.com/katex", + "https://github.com/sponsors/katex" + ], + "dependencies": { + "commander": "^8.3.0" + }, + "bin": { + "katex": "cli.js" + } + }, + "node_modules/katex/node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "engines": { + "node": ">= 12" + } + }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", @@ -9142,6 +9233,14 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/math-intrinsics": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.0.0.tgz", + "integrity": "sha512-4MqMiKP90ybymYvsut0CH2g4XWbfLtmlCkXmtmdcDCxNB+mQcu1w/1+L/VD7vi/PSv7X2JYV7SCcR+jiPXnQtA==", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/mdast-util-directive": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/mdast-util-directive/-/mdast-util-directive-3.0.0.tgz", @@ -9545,9 +9644,12 @@ } }, "node_modules/merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "node_modules/merge-stream": { "version": "2.0.0", @@ -9563,9 +9665,9 @@ } }, "node_modules/mermaid": { - "version": "10.8.0", - "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-10.8.0.tgz", - "integrity": "sha512-9CzfSreRjdDJxX796+jW4zjEq0DVw5xVF0nWsqff8OTbrt+ml0TZ5PyYUjjUZJa2NYxYJZZXewEquxGiM8qZEA==", + "version": "10.9.3", + "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-10.9.3.tgz", + "integrity": "sha512-V80X1isSEvAewIL3xhmz/rVmc27CVljcsbWxkxlWJWY/1kQa4XOABqpDl2qQLGKzpKm6WbTfUEKImBlUfFYArw==", "dependencies": { "@braintree/sanitize-url": "^6.0.1", "@types/d3-scale": "^4.0.3", @@ -9576,8 +9678,9 @@ "d3-sankey": "^0.12.3", "dagre-d3-es": "7.0.10", "dayjs": "^1.11.7", - "dompurify": "^3.0.5", + "dompurify": "^3.0.5 <3.1.7", "elkjs": "^0.9.0", + "katex": "^0.16.9", "khroma": "^2.0.0", "lodash-es": "^4.17.21", "mdast-util-from-markdown": "^1.3.0", @@ -11708,11 +11811,11 @@ ] }, "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dependencies": { - "braces": "^3.0.2", + "braces": "^3.0.3", "picomatch": "^2.3.1" }, "engines": { @@ -11853,9 +11956,9 @@ } }, "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "version": "3.3.8", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", + "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", "funding": [ { "type": "github", @@ -11914,9 +12017,9 @@ } }, "node_modules/node-releases": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==" + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==" }, "node_modules/non-layered-tidy-tree-layout": { "version": "2.0.2", @@ -12005,9 +12108,12 @@ } }, "node_modules/object-inspect": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", - "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "version": "1.13.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz", + "integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==", + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -12361,9 +12467,9 @@ } }, "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==" }, "node_modules/picomatch": { "version": "2.3.1", @@ -13166,11 +13272,11 @@ } }, "node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", "dependencies": { - "side-channel": "^1.0.4" + "side-channel": "^1.0.6" }, "engines": { "node": ">=0.6" @@ -13234,9 +13340,9 @@ } }, "node_modules/raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", @@ -14380,9 +14486,9 @@ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "node_modules/send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", "dependencies": { "debug": "2.6.9", "depd": "2.0.0", @@ -14415,6 +14521,14 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, + "node_modules/send/node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/send/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -14527,29 +14641,30 @@ } }, "node_modules/serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", "dependencies": { - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "parseurl": "~1.3.3", - "send": "0.18.0" + "send": "0.19.0" }, "engines": { "node": ">= 0.8.0" } }, "node_modules/set-function-length": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.0.tgz", - "integrity": "sha512-4DBHDoyHlM1IRPGYcoxexgh67y4ueR53FKV1yyxwFMY7aCqcN/38M1+SwZ/qJQ8iLv7+ck385ot4CcisOAPT9w==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", "dependencies": { - "define-data-property": "^1.1.1", + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.2", + "get-intrinsic": "^1.2.4", "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.1" + "has-property-descriptors": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -14620,13 +14735,68 @@ } }, "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -15627,9 +15797,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.0.13", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", - "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", + "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", "funding": [ { "type": "opencollective", @@ -15645,8 +15815,8 @@ } ], "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" + "escalade": "^3.2.0", + "picocolors": "^1.1.0" }, "bin": { "update-browserslist-db": "cli.js" @@ -15944,9 +16114,9 @@ } }, "node_modules/watchpack": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", - "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz", + "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==", "dependencies": { "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.1.2" @@ -15978,33 +16148,32 @@ "integrity": "sha512-BSR9wyRsy/KOValMgd5kMyr3JzpdeoR9KVId8u5GVlTTAtNChlsE4yTxeY7zMdNSyOmoKBv8NH2qeRY9Tg+IaA==" }, "node_modules/webpack": { - "version": "5.89.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.89.0.tgz", - "integrity": "sha512-qyfIC10pOr70V+jkmud8tMfajraGCZMBWJtrmuBymQKCrLTRejBI8STDp1MCyZu/QTdZSeacCQYpYNQVOzX5kw==", - "dependencies": { - "@types/eslint-scope": "^3.7.3", - "@types/estree": "^1.0.0", - "@webassemblyjs/ast": "^1.11.5", - "@webassemblyjs/wasm-edit": "^1.11.5", - "@webassemblyjs/wasm-parser": "^1.11.5", - "acorn": "^8.7.1", - "acorn-import-assertions": "^1.9.0", - "browserslist": "^4.14.5", + "version": "5.97.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.97.1.tgz", + "integrity": "sha512-EksG6gFY3L1eFMROS/7Wzgrii5mBAFe4rIr3r2BTfo7bcc+DWwFZ4OJ/miOuHJO/A85HwyI4eQ0F6IKXesO7Fg==", + "dependencies": { + "@types/eslint-scope": "^3.7.7", + "@types/estree": "^1.0.6", + "@webassemblyjs/ast": "^1.14.1", + "@webassemblyjs/wasm-edit": "^1.14.1", + "@webassemblyjs/wasm-parser": "^1.14.1", + "acorn": "^8.14.0", + "browserslist": "^4.24.0", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.15.0", + "enhanced-resolve": "^5.17.1", "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.9", + "graceful-fs": "^4.2.11", "json-parse-even-better-errors": "^2.3.1", "loader-runner": "^4.2.0", "mime-types": "^2.1.27", "neo-async": "^2.6.2", "schema-utils": "^3.2.0", "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.3.7", - "watchpack": "^2.4.0", + "terser-webpack-plugin": "^5.3.10", + "watchpack": "^2.4.1", "webpack-sources": "^3.2.3" }, "bin": { @@ -16058,9 +16227,9 @@ } }, "node_modules/webpack-dev-middleware": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz", - "integrity": "sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA==", + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz", + "integrity": "sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q==", "dependencies": { "colorette": "^2.0.10", "memfs": "^3.4.3", From 1daa1b3ebf1ca2ef02bd99a98d1ab71bd97995b9 Mon Sep 17 00:00:00 2001 From: EwenQuim Date: Fri, 13 Dec 2024 09:50:01 +0100 Subject: [PATCH 051/138] deps: Bumps all dependencies --- examples/full-app-gourmet/go.mod | 4 ++-- examples/generate-opengraph-image/go.mod | 2 +- examples/generate-opengraph-image/go.sum | 4 ++-- middleware/cache/go.mod | 2 +- middleware/cache/go.sum | 4 ++-- testing-from-outside/go.mod | 2 +- testing-from-outside/go.sum | 4 ++-- 7 files changed, 11 insertions(+), 11 deletions(-) diff --git a/examples/full-app-gourmet/go.mod b/examples/full-app-gourmet/go.mod index cdcc098d..2bf4e00d 100644 --- a/examples/full-app-gourmet/go.mod +++ b/examples/full-app-gourmet/go.mod @@ -8,9 +8,9 @@ require ( github.com/a-h/templ v0.2.793 github.com/go-chi/chi/v5 v5.1.0 github.com/go-fuego/fuego v0.16.1 - github.com/go-fuego/fuego/extra/markdown v0.0.0-20241211140128-19a76d1a892d + github.com/go-fuego/fuego/extra/markdown v0.0.0-20241213083019-8a613313c19f github.com/go-fuego/fuego/middleware/basicauth v0.15.1 - github.com/go-fuego/fuego/middleware/cache v0.0.0-20241211140128-19a76d1a892d + github.com/go-fuego/fuego/middleware/cache v0.0.0-20241213083019-8a613313c19f github.com/golang-jwt/jwt/v5 v5.2.1 github.com/golang-migrate/migrate/v4 v4.18.1 github.com/google/uuid v1.6.0 diff --git a/examples/generate-opengraph-image/go.mod b/examples/generate-opengraph-image/go.mod index 57f4f92b..c572ad4e 100644 --- a/examples/generate-opengraph-image/go.mod +++ b/examples/generate-opengraph-image/go.mod @@ -5,7 +5,7 @@ go 1.23.3 require ( github.com/getkin/kin-openapi v0.128.0 github.com/go-fuego/fuego v0.16.1 - github.com/go-fuego/fuego/middleware/cache v0.0.0-20241211140128-19a76d1a892d + github.com/go-fuego/fuego/middleware/cache v0.0.0-20241213083019-8a613313c19f github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 golang.org/x/image v0.23.0 ) diff --git a/examples/generate-opengraph-image/go.sum b/examples/generate-opengraph-image/go.sum index 20c0ea61..60bffdc5 100644 --- a/examples/generate-opengraph-image/go.sum +++ b/examples/generate-opengraph-image/go.sum @@ -6,8 +6,8 @@ github.com/getkin/kin-openapi v0.128.0 h1:jqq3D9vC9pPq1dGcOCv7yOp1DaEe7c/T1vzcLb github.com/getkin/kin-openapi v0.128.0/go.mod h1:OZrfXzUfGrNbsKj+xmFBx6E5c6yH3At/tAKSc2UszXM= github.com/go-fuego/fuego v0.16.1 h1:G+sDF55BjFI7FH7dd07HDx4jfNPxXEeab+YKuLjj5zY= github.com/go-fuego/fuego v0.16.1/go.mod h1:ARPlRxY+RgbahF6ZvnjsESGQd3h/jCw8ksCJxKLbgjY= -github.com/go-fuego/fuego/middleware/cache v0.0.0-20241211140128-19a76d1a892d h1:5ltEcAZGWJ8atk1MGYcgHrsJC6MWoUrAQ8xs20bt9hY= -github.com/go-fuego/fuego/middleware/cache v0.0.0-20241211140128-19a76d1a892d/go.mod h1:1X75DId7/U/PJ+qPOqQePEyxj8u3FV6MzJw7oc+INL8= +github.com/go-fuego/fuego/middleware/cache v0.0.0-20241213083019-8a613313c19f h1:dMjv20u2/oP/SjGBmlx2GsKFGha0Zax80FRUztI+ZNg= +github.com/go-fuego/fuego/middleware/cache v0.0.0-20241213083019-8a613313c19f/go.mod h1:1X75DId7/U/PJ+qPOqQePEyxj8u3FV6MzJw7oc+INL8= github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= diff --git a/middleware/cache/go.mod b/middleware/cache/go.mod index ff325c4c..ccd63626 100644 --- a/middleware/cache/go.mod +++ b/middleware/cache/go.mod @@ -26,7 +26,7 @@ require ( github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - golang.org/x/crypto v0.30.0 // indirect + golang.org/x/crypto v0.31.0 // indirect golang.org/x/net v0.32.0 // indirect golang.org/x/sys v0.28.0 // indirect golang.org/x/text v0.21.0 // indirect diff --git a/middleware/cache/go.sum b/middleware/cache/go.sum index d677c627..2ca2e4a5 100644 --- a/middleware/cache/go.sum +++ b/middleware/cache/go.sum @@ -52,8 +52,8 @@ github.com/thejerf/slogassert v0.3.4 h1:VoTsXixRbXMrRSSxDjYTiEDCM4VWbsYPW5rB/hX2 github.com/thejerf/slogassert v0.3.4/go.mod h1:0zn9ISLVKo1aPMTqcGfG1o6dWwt+Rk574GlUxHD4rs8= github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= -golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY= -golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs= golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= diff --git a/testing-from-outside/go.mod b/testing-from-outside/go.mod index 092cc79c..13696dfa 100644 --- a/testing-from-outside/go.mod +++ b/testing-from-outside/go.mod @@ -27,7 +27,7 @@ require ( github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - golang.org/x/crypto v0.30.0 // indirect + golang.org/x/crypto v0.31.0 // indirect golang.org/x/net v0.32.0 // indirect golang.org/x/sys v0.28.0 // indirect golang.org/x/text v0.21.0 // indirect diff --git a/testing-from-outside/go.sum b/testing-from-outside/go.sum index 04ad0449..f60f9073 100644 --- a/testing-from-outside/go.sum +++ b/testing-from-outside/go.sum @@ -52,8 +52,8 @@ github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOf github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= -golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY= -golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs= golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= From 4dc3f5cfc98265f9b02f6bfef29e312857a6ed83 Mon Sep 17 00:00:00 2001 From: EwenQuim Date: Wed, 11 Dec 2024 01:29:59 +0100 Subject: [PATCH 052/138] Decorrelates openapi registration from server --- examples/petstore/lib/server_test.go | 2 +- .../lib/testdata/doc/openapi.golden.json | 2 +- mux.go | 2 +- mux_test.go | 16 ++-- openapi.go | 83 ++++++++++++++----- openapi_operations.go | 2 +- openapi_test.go | 2 +- option.go | 8 +- option_test.go | 16 ++-- server.go | 17 ++-- server_test.go | 40 ++++----- 11 files changed, 115 insertions(+), 75 deletions(-) diff --git a/examples/petstore/lib/server_test.go b/examples/petstore/lib/server_test.go index 0d990920..9260b76e 100644 --- a/examples/petstore/lib/server_test.go +++ b/examples/petstore/lib/server_test.go @@ -21,7 +21,7 @@ func TestPetstoreOpenAPIGeneration(t *testing.T) { ) server.OutputOpenAPISpec() - err := server.OpenApiSpec.Validate(context.Background()) + err := server.OpenAPIzer.OpenAPIDescription().Validate(context.Background()) require.NoError(t, err) generatedSpec, err := os.ReadFile("testdata/doc/openapi.json") diff --git a/examples/petstore/lib/testdata/doc/openapi.golden.json b/examples/petstore/lib/testdata/doc/openapi.golden.json index bed2ff64..16eaede4 100644 --- a/examples/petstore/lib/testdata/doc/openapi.golden.json +++ b/examples/petstore/lib/testdata/doc/openapi.golden.json @@ -1,5 +1,4 @@ { - "openapi": "3.1.0", "components": { "schemas": { "HTTPError": { @@ -149,6 +148,7 @@ "title": "OpenAPI", "version": "0.0.1" }, + "openapi": "3.1.0", "paths": { "/pets/": { "get": { diff --git a/mux.go b/mux.go index 2fcccb0e..4e208370 100644 --- a/mux.go +++ b/mux.go @@ -112,7 +112,7 @@ func Register[T, B any](s *Server, route Route[T, B], controller http.Handler, o route.Path = s.basePath + route.Path var err error - route.Operation, err = RegisterOpenAPIOperation(s, route) + route.Operation, err = RegisterOpenAPIOperation(s.OpenAPIzer, route) if err != nil { slog.Warn("error documenting openapi operation", "error", err) } diff --git a/mux_test.go b/mux_test.go index 7d5f5b48..f63c8b96 100644 --- a/mux_test.go +++ b/mux_test.go @@ -488,8 +488,8 @@ func TestHideOpenapiRoutes(t *testing.T) { Get(s, "/test", func(ctx *ContextNoBody) (string, error) { return "", nil }) require.Equal(t, s.DisableOpenapi, true) - require.True(t, s.OpenApiSpec.Paths.Find("/not-hidden") != nil) - require.True(t, s.OpenApiSpec.Paths.Find("/test") == nil) + require.True(t, s.OpenAPIzer.OpenAPIDescription().Paths.Find("/not-hidden") != nil) + require.True(t, s.OpenAPIzer.OpenAPIDescription().Paths.Find("/test") == nil) }) t.Run("hide group", func(t *testing.T) { @@ -500,8 +500,8 @@ func TestHideOpenapiRoutes(t *testing.T) { Get(g, "/test", func(ctx *ContextNoBody) (string, error) { return "", nil }) require.Equal(t, g.DisableOpenapi, true) - require.True(t, s.OpenApiSpec.Paths.Find("/not-hidden") != nil) - require.True(t, s.OpenApiSpec.Paths.Find("/group/test") == nil) + require.True(t, s.OpenAPIzer.OpenAPIDescription().Paths.Find("/not-hidden") != nil) + require.True(t, s.OpenAPIzer.OpenAPIDescription().Paths.Find("/group/test") == nil) }) t.Run("hide group but not other group", func(t *testing.T) { @@ -514,8 +514,8 @@ func TestHideOpenapiRoutes(t *testing.T) { require.Equal(t, true, g.DisableOpenapi) require.Equal(t, false, g2.DisableOpenapi) - require.True(t, s.OpenApiSpec.Paths.Find("/group/test") == nil) - require.True(t, s.OpenApiSpec.Paths.Find("/group2/test") != nil) + require.True(t, s.OpenAPIzer.OpenAPIDescription().Paths.Find("/group/test") == nil) + require.True(t, s.OpenAPIzer.OpenAPIDescription().Paths.Find("/group2/test") != nil) }) t.Run("hide group but show sub group", func(t *testing.T) { @@ -527,8 +527,8 @@ func TestHideOpenapiRoutes(t *testing.T) { Get(g2, "/test", func(ctx *ContextNoBody) (string, error) { return "test", nil }) require.Equal(t, true, g.DisableOpenapi) - require.True(t, s.OpenApiSpec.Paths.Find("/group/test") == nil) - require.True(t, s.OpenApiSpec.Paths.Find("/group/sub/test") != nil) + require.True(t, s.OpenAPIzer.OpenAPIDescription().Paths.Find("/group/test") == nil) + require.True(t, s.OpenAPIzer.OpenAPIDescription().Paths.Find("/group/sub/test") != nil) }) } diff --git a/openapi.go b/openapi.go index dc40087f..a1c1f44d 100644 --- a/openapi.go +++ b/openapi.go @@ -16,8 +16,45 @@ import ( "strings" "github.com/getkin/kin-openapi/openapi3" + "github.com/getkin/kin-openapi/openapi3gen" ) +type OpenAPIzer interface { + OpenAPIDescription() *openapi3.T + Generator() *openapi3gen.Generator + GlobalOpenAPIResponses() *[]openAPIError +} + +func NewSpec() *Spec { + desc := NewOpenApiSpec() + return &Spec{ + description: &desc, + generator: openapi3gen.NewGenerator(), + globalOpenAPIResponses: &[]openAPIError{}, + } +} + +// Holds the OpenAPI OpenAPIDescription (OAD) and OpenAPI capabilities. +type Spec struct { + description *openapi3.T + generator *openapi3gen.Generator + globalOpenAPIResponses *[]openAPIError +} + +func (d *Spec) OpenAPIDescription() *openapi3.T { + return d.description +} + +func (d *Spec) Generator() *openapi3gen.Generator { + return d.generator +} + +func (d *Spec) GlobalOpenAPIResponses() *[]openAPIError { + return d.globalOpenAPIResponses +} + +var _ OpenAPIzer = &Spec{} + func NewOpenApiSpec() openapi3.T { info := &openapi3.Info{ Title: "OpenAPI", @@ -53,11 +90,11 @@ func (s *Server) Show() *Server { } func declareAllTagsFromOperations(s *Server) { - for _, pathItem := range s.OpenApiSpec.Paths.Map() { + for _, pathItem := range s.OpenAPIzer.OpenAPIDescription().Paths.Map() { for _, op := range pathItem.Operations() { for _, tag := range op.Tags { - if s.OpenApiSpec.Tags.Get(tag) == nil { - s.OpenApiSpec.Tags = append(s.OpenApiSpec.Tags, &openapi3.Tag{ + if s.OpenAPIzer.OpenAPIDescription().Tags.Get(tag) == nil { + s.OpenAPIzer.OpenAPIDescription().Tags = append(s.OpenAPIzer.OpenAPIDescription().Tags, &openapi3.Tag{ Name: tag, }) } @@ -73,7 +110,7 @@ func (s *Server) OutputOpenAPISpec() openapi3.T { declareAllTagsFromOperations(s) // Validate - err := s.OpenApiSpec.Validate(context.Background()) + err := s.OpenAPIzer.OpenAPIDescription().Validate(context.Background()) if err != nil { slog.Error("Error validating spec", "error", err) } @@ -95,14 +132,14 @@ func (s *Server) OutputOpenAPISpec() openapi3.T { } } - return s.OpenApiSpec + return *s.OpenAPIzer.OpenAPIDescription() } func (s *Server) marshalSpec() ([]byte, error) { if s.OpenAPIConfig.PrettyFormatJson { - return json.MarshalIndent(s.OpenApiSpec, "", " ") + return json.MarshalIndent(s.OpenAPIzer.OpenAPIDescription(), "", " ") } - return json.Marshal(s.OpenApiSpec) + return json.Marshal(s.OpenAPIzer.OpenAPIDescription()) } func (s *Server) saveOpenAPIToFile(jsonSpecLocalPath string, jsonSpec []byte) error { @@ -164,7 +201,7 @@ func validateSwaggerUrl(swaggerUrl string) bool { } // RegisterOpenAPIOperation registers an OpenAPI operation. -func RegisterOpenAPIOperation[T, B any](s *Server, route Route[T, B]) (*openapi3.Operation, error) { +func RegisterOpenAPIOperation[T, B any](s OpenAPIzer, route Route[T, B]) (*openapi3.Operation, error) { if route.Operation == nil { route.Operation = openapi3.NewOperation() } @@ -184,7 +221,7 @@ func RegisterOpenAPIOperation[T, B any](s *Server, route Route[T, B]) (*openapi3 } // Response - globals - for _, openAPIGlobalResponse := range s.globalOpenAPIResponses { + for _, openAPIGlobalResponse := range *s.GlobalOpenAPIResponses() { addResponseIfNotSet(s, route.Operation, openAPIGlobalResponse.Code, openAPIGlobalResponse.Description, openAPIGlobalResponse.ErrorType) } @@ -228,7 +265,7 @@ func RegisterOpenAPIOperation[T, B any](s *Server, route Route[T, B]) (*openapi3 } } - s.OpenApiSpec.AddOperation(route.Path, route.Method, route.Operation) + s.OpenAPIDescription().AddOperation(route.Path, route.Method, route.Operation) return route.Operation, nil } @@ -247,10 +284,10 @@ type SchemaTag struct { Name string } -func SchemaTagFromType(s *Server, v any) SchemaTag { +func SchemaTagFromType(s OpenAPIzer, v any) SchemaTag { if v == nil { // ensure we add unknown-interface to our schemas - schema := s.getOrCreateSchema("unknown-interface", struct{}{}) + schema := getOrCreateSchema(s, "unknown-interface", struct{}{}) return SchemaTag{ Name: "unknown-interface", SchemaRef: openapi3.SchemaRef{ @@ -270,7 +307,7 @@ func SchemaTagFromType(s *Server, v any) SchemaTag { // If the type is a slice or array type it will dive into the type as well as // build and openapi3.Schema where Type is array and Ref is set to the proper // components Schema -func dive(s *Server, t reflect.Type, tag SchemaTag, maxDepth int) SchemaTag { +func dive(s OpenAPIzer, t reflect.Type, tag SchemaTag, maxDepth int) SchemaTag { if maxDepth == 0 { return SchemaTag{ Name: "default", @@ -297,7 +334,7 @@ func dive(s *Server, t reflect.Type, tag SchemaTag, maxDepth int) SchemaTag { return dive(s, t.Field(0).Type, tag, maxDepth-1) } tag.Ref = "#/components/schemas/" + tag.Name - tag.Value = s.getOrCreateSchema(tag.Name, reflect.New(t).Interface()) + tag.Value = getOrCreateSchema(s, tag.Name, reflect.New(t).Interface()) return tag } @@ -305,18 +342,18 @@ func dive(s *Server, t reflect.Type, tag SchemaTag, maxDepth int) SchemaTag { // getOrCreateSchema is used to get a schema from the OpenAPI spec. // If the schema does not exist, it will create a new schema and add it to the OpenAPI spec. -func (s *Server) getOrCreateSchema(key string, v any) *openapi3.Schema { - schemaRef, ok := s.OpenApiSpec.Components.Schemas[key] +func getOrCreateSchema(s OpenAPIzer, key string, v any) *openapi3.Schema { + schemaRef, ok := s.OpenAPIDescription().Components.Schemas[key] if !ok { - schemaRef = s.createSchema(key, v) + schemaRef = createSchema(s, key, v) } return schemaRef.Value } // createSchema is used to create a new schema and add it to the OpenAPI spec. // Relies on the openapi3gen package to generate the schema, and adds custom struct tags. -func (s *Server) createSchema(key string, v any) *openapi3.SchemaRef { - schemaRef, err := s.openAPIGenerator.NewSchemaRefForValue(v, s.OpenApiSpec.Components.Schemas) +func createSchema(s OpenAPIzer, key string, v any) *openapi3.SchemaRef { + schemaRef, err := s.Generator().NewSchemaRefForValue(v, s.OpenAPIDescription().Components.Schemas) if err != nil { slog.Error("Error generating schema", "key", key, "error", err) } @@ -327,9 +364,9 @@ func (s *Server) createSchema(key string, v any) *openapi3.SchemaRef { schemaRef.Value.Description = descriptionable.Description() } - s.parseStructTags(reflect.TypeOf(v), schemaRef) + parseStructTags(reflect.TypeOf(v), schemaRef) - s.OpenApiSpec.Components.Schemas[key] = schemaRef + s.OpenAPIDescription().Components.Schemas[key] = schemaRef return schemaRef } @@ -346,7 +383,7 @@ func (s *Server) createSchema(key string, v any) *openapi3.SchemaRef { // - min=1 => minLength=1 (for strings) // - max=100 => max=100 (for integers) // - max=100 => maxLength=100 (for strings) -func (s *Server) parseStructTags(t reflect.Type, schemaRef *openapi3.SchemaRef) { +func parseStructTags(t reflect.Type, schemaRef *openapi3.SchemaRef) { if t.Kind() == reflect.Ptr { t = t.Elem() } @@ -360,7 +397,7 @@ func (s *Server) parseStructTags(t reflect.Type, schemaRef *openapi3.SchemaRef) if field.Anonymous { fieldType := field.Type - s.parseStructTags(fieldType, schemaRef) + parseStructTags(fieldType, schemaRef) continue } diff --git a/openapi_operations.go b/openapi_operations.go index 10e20073..1bd5c4d5 100644 --- a/openapi_operations.go +++ b/openapi_operations.go @@ -62,7 +62,7 @@ func (r Route[ResponseBody, RequestBody]) Param(paramType ParamType, name, descr } // Registers a response for the route, only if error for this code is not already set. -func addResponseIfNotSet(s *Server, operation *openapi3.Operation, code int, description string, errorType ...any) { +func addResponseIfNotSet(s OpenAPIzer, operation *openapi3.Operation, code int, description string, errorType ...any) { var responseSchema SchemaTag if len(errorType) > 0 { diff --git a/openapi_test.go b/openapi_test.go index 89667f92..616c5a4c 100644 --- a/openapi_test.go +++ b/openapi_test.go @@ -545,7 +545,7 @@ func TestDeclareCustom200Response(t *testing.T) { w.Write([]byte("PNG image")) }, optionReturnsPNG) - openAPIResponse := s.OpenApiSpec.Paths.Find("/image").Get.Responses.Value("200") + openAPIResponse := s.OpenAPIzer.OpenAPIDescription().Paths.Find("/image").Get.Responses.Value("200") require.Nil(t, openAPIResponse.Value.Content.Get("application/json")) require.NotNil(t, openAPIResponse.Value.Content.Get("image/png")) require.Equal(t, "Generated image", *openAPIResponse.Value.Description) diff --git a/option.go b/option.go index f9eed7f9..0f263209 100644 --- a/option.go +++ b/option.go @@ -302,9 +302,9 @@ func OptionAddError(code int, description string, errorType ...any) func(*BaseRo } if len(errorType) > 0 { - responseSchema = SchemaTagFromType(r.mainRouter, errorType[0]) + responseSchema = SchemaTagFromType(r.mainRouter.OpenAPIzer, errorType[0]) } else { - responseSchema = SchemaTagFromType(r.mainRouter, HTTPError{}) + responseSchema = SchemaTagFromType(r.mainRouter.OpenAPIzer, HTTPError{}) } content := openapi3.NewContentWithSchemaRef(&responseSchema.SchemaRef, []string{"application/json"}) @@ -374,14 +374,14 @@ func OptionDefaultStatusCode(defaultStatusCode int) func(*BaseRoute) { // }) func OptionSecurity(securityRequirements ...openapi3.SecurityRequirement) func(*BaseRoute) { return func(r *BaseRoute) { - if r.mainRouter.OpenApiSpec.Components == nil { + if r.mainRouter.OpenAPIzer.OpenAPIDescription().Components == nil { panic("zero security schemes have been registered with the server") } // Validate the security scheme exists in components for _, req := range securityRequirements { for schemeName := range req { - if _, exists := r.mainRouter.OpenApiSpec.Components.SecuritySchemes[schemeName]; !exists { + if _, exists := r.mainRouter.OpenAPIzer.OpenAPIDescription().Components.SecuritySchemes[schemeName]; !exists { panic(fmt.Sprintf("security scheme '%s' not defined in components", schemeName)) } } diff --git a/option_test.go b/option_test.go index 6586e98a..1df04900 100644 --- a/option_test.go +++ b/option_test.go @@ -299,8 +299,8 @@ func TestPath(t *testing.T) { fuego.Get(s, "/test/{id}", helloWorld) - require.Equal(t, "id", s.OpenApiSpec.Paths.Find("/test/{id}").Get.Parameters.GetByInAndName("path", "id").Name) - require.Equal(t, "", s.OpenApiSpec.Paths.Find("/test/{id}").Get.Parameters.GetByInAndName("path", "id").Description) + require.Equal(t, "id", s.OpenAPIzer.OpenAPIDescription().Paths.Find("/test/{id}").Get.Parameters.GetByInAndName("path", "id").Name) + require.Equal(t, "", s.OpenAPIzer.OpenAPIDescription().Paths.Find("/test/{id}").Get.Parameters.GetByInAndName("path", "id").Description) }) t.Run("Declare explicitly an existing path parameter for the route", func(t *testing.T) { @@ -310,9 +310,9 @@ func TestPath(t *testing.T) { fuego.OptionPath("id", "some id", param.Example("123", "123"), param.Nullable()), ) - require.Equal(t, "id", s.OpenApiSpec.Paths.Find("/test/{id}").Get.Parameters.GetByInAndName("path", "id").Name) - require.Equal(t, "some id", s.OpenApiSpec.Paths.Find("/test/{id}").Get.Parameters.GetByInAndName("path", "id").Description) - require.Equal(t, true, s.OpenApiSpec.Paths.Find("/test/{id}").Get.Parameters.GetByInAndName("path", "id").Required, "path parameter is forced to be required") + require.Equal(t, "id", s.OpenAPIzer.OpenAPIDescription().Paths.Find("/test/{id}").Get.Parameters.GetByInAndName("path", "id").Name) + require.Equal(t, "some id", s.OpenAPIzer.OpenAPIDescription().Paths.Find("/test/{id}").Get.Parameters.GetByInAndName("path", "id").Description) + require.Equal(t, true, s.OpenAPIzer.OpenAPIDescription().Paths.Find("/test/{id}").Get.Parameters.GetByInAndName("path", "id").Required, "path parameter is forced to be required") }) t.Run("Declare explicitly a non-existing path parameter for the route panics", func(t *testing.T) { @@ -353,7 +353,7 @@ func TestRequestContentType(t *testing.T) { require.NotNil(t, content.Get("application/json")) require.Nil(t, content.Get("application/xml")) require.Equal(t, "#/components/schemas/ReqBody", content.Get("application/json").Schema.Ref) - _, ok := s.OpenApiSpec.Components.RequestBodies["ReqBody"] + _, ok := s.OpenAPIzer.OpenAPIDescription().Components.RequestBodies["ReqBody"] require.False(t, ok) }) @@ -369,7 +369,7 @@ func TestRequestContentType(t *testing.T) { require.Nil(t, content.Get("application/xml")) require.Equal(t, "#/components/schemas/ReqBody", content.Get("application/json").Schema.Ref) require.Equal(t, "#/components/schemas/ReqBody", content.Get("my/content-type").Schema.Ref) - _, ok := s.OpenApiSpec.Components.RequestBodies["ReqBody"] + _, ok := s.OpenAPIzer.OpenAPIDescription().Components.RequestBodies["ReqBody"] require.False(t, ok) }) @@ -385,7 +385,7 @@ func TestRequestContentType(t *testing.T) { require.Nil(t, content.Get("application/xml")) require.NotNil(t, content.Get("my/content-type")) require.Equal(t, "#/components/schemas/ReqBody", content.Get("my/content-type").Schema.Ref) - _, ok := s.OpenApiSpec.Components.RequestBodies["ReqBody"] + _, ok := s.OpenAPIzer.OpenAPIDescription().Components.RequestBodies["ReqBody"] require.False(t, ok) }) } diff --git a/server.go b/server.go index a0215c23..535a0bae 100644 --- a/server.go +++ b/server.go @@ -61,7 +61,8 @@ type Server struct { globalOpenAPIResponses []openAPIError // Global error responses - OpenApiSpec openapi3.T // OpenAPI spec generated by the server + // OpenAPIzer handles the OpenAPI spec generation. + OpenAPIzer Security Security @@ -105,10 +106,10 @@ func NewServer(options ...func(*Server)) *Server { WriteTimeout: 30 * time.Second, IdleTimeout: 30 * time.Second, }, - Mux: http.NewServeMux(), - OpenApiSpec: NewOpenApiSpec(), + Mux: http.NewServeMux(), OpenAPIConfig: defaultOpenAPIConfig, + OpenAPIzer: NewSpec(), openAPIGenerator: openapi3gen.NewGenerator( openapi3gen.UseAllExportedFields(), @@ -137,7 +138,7 @@ func NewServer(options ...func(*Server)) *Server { option(s) } - s.OpenApiSpec.Servers = append(s.OpenApiSpec.Servers, &openapi3.Server{ + s.OpenAPIzer.OpenAPIDescription().Servers = append(s.OpenAPIzer.OpenAPIDescription().Servers, &openapi3.Server{ URL: "http://" + s.Addr, Description: "local server", }) @@ -214,6 +215,8 @@ func WithGlobalResponseTypes(code int, description string, errorType ...any) fun errorType = append(errorType, HTTPError{}) return func(c *Server) { c.globalOpenAPIResponses = append(c.globalOpenAPIResponses, openAPIError{code, description, errorType[0]}) + truc := c.OpenAPIzer.GlobalOpenAPIResponses() + *truc = append(*truc, openAPIError{code, description, errorType[0]}) } } @@ -234,11 +237,11 @@ func WithGlobalResponseTypes(code int, description string, errorType ...any) fun // ) func WithSecurity(schemes openapi3.SecuritySchemes) func(*Server) { return func(s *Server) { - if s.OpenApiSpec.Components.SecuritySchemes == nil { - s.OpenApiSpec.Components.SecuritySchemes = openapi3.SecuritySchemes{} + if s.OpenAPIzer.OpenAPIDescription().Components.SecuritySchemes == nil { + s.OpenAPIzer.OpenAPIDescription().Components.SecuritySchemes = openapi3.SecuritySchemes{} } for name, scheme := range schemes { - s.OpenApiSpec.Components.SecuritySchemes[name] = scheme + s.OpenAPIzer.OpenAPIDescription().Components.SecuritySchemes[name] = scheme } } } diff --git a/server_test.go b/server_test.go index 51d75764..75801820 100644 --- a/server_test.go +++ b/server_test.go @@ -334,7 +334,7 @@ func TestWithRequestContentType(t *testing.T) { require.NotNil(t, content.Get("application/xml")) require.Equal(t, "#/components/schemas/ReqBody", content.Get("application/json").Schema.Ref) require.Equal(t, "#/components/schemas/ReqBody", content.Get("application/xml").Schema.Ref) - _, ok := s.OpenApiSpec.Components.RequestBodies["ReqBody"] + _, ok := s.OpenAPIzer.OpenAPIDescription().Components.RequestBodies["ReqBody"] require.False(t, ok) }) } @@ -503,10 +503,10 @@ func TestWithSecurity(t *testing.T) { }), ) - require.NotNil(t, s.OpenApiSpec.Components.SecuritySchemes) - require.Contains(t, s.OpenApiSpec.Components.SecuritySchemes, "bearerAuth") + require.NotNil(t, s.OpenAPIzer.OpenAPIDescription().Components.SecuritySchemes) + require.Contains(t, s.OpenAPIzer.OpenAPIDescription().Components.SecuritySchemes, "bearerAuth") - scheme := s.OpenApiSpec.Components.SecuritySchemes["bearerAuth"].Value + scheme := s.OpenAPIzer.OpenAPIDescription().Components.SecuritySchemes["bearerAuth"].Value require.Equal(t, "http", scheme.Type) require.Equal(t, "bearer", scheme.Scheme) require.Equal(t, "JWT", scheme.BearerFormat) @@ -530,12 +530,12 @@ func TestWithSecurity(t *testing.T) { }), ) - require.NotNil(t, s.OpenApiSpec.Components.SecuritySchemes) - require.Contains(t, s.OpenApiSpec.Components.SecuritySchemes, "bearerAuth") - require.Contains(t, s.OpenApiSpec.Components.SecuritySchemes, "apiKey") + require.NotNil(t, s.OpenAPIzer.OpenAPIDescription().Components.SecuritySchemes) + require.Contains(t, s.OpenAPIzer.OpenAPIDescription().Components.SecuritySchemes, "bearerAuth") + require.Contains(t, s.OpenAPIzer.OpenAPIDescription().Components.SecuritySchemes, "apiKey") - bearerScheme := s.OpenApiSpec.Components.SecuritySchemes["bearerAuth"].Value - apiKeyScheme := s.OpenApiSpec.Components.SecuritySchemes["apiKey"].Value + bearerScheme := s.OpenAPIzer.OpenAPIDescription().Components.SecuritySchemes["bearerAuth"].Value + apiKeyScheme := s.OpenAPIzer.OpenAPIDescription().Components.SecuritySchemes["apiKey"].Value require.Equal(t, "http", bearerScheme.Type) require.Equal(t, "bearer", bearerScheme.Scheme) @@ -559,16 +559,16 @@ func TestWithSecurity(t *testing.T) { ) // Add another security scheme to the existing server - s.OpenApiSpec.Components.SecuritySchemes["oauth2"] = &openapi3.SecuritySchemeRef{ + s.OpenAPIzer.OpenAPIDescription().Components.SecuritySchemes["oauth2"] = &openapi3.SecuritySchemeRef{ Value: openapi3.NewOIDCSecurityScheme("https://example.com/.well-known/openid-configuration"). WithType("oauth2"), } - require.NotNil(t, s.OpenApiSpec.Components.SecuritySchemes) - require.Contains(t, s.OpenApiSpec.Components.SecuritySchemes, "bearerAuth") - require.Contains(t, s.OpenApiSpec.Components.SecuritySchemes, "oauth2") + require.NotNil(t, s.OpenAPIzer.OpenAPIDescription().Components.SecuritySchemes) + require.Contains(t, s.OpenAPIzer.OpenAPIDescription().Components.SecuritySchemes, "bearerAuth") + require.Contains(t, s.OpenAPIzer.OpenAPIDescription().Components.SecuritySchemes, "oauth2") - oauth2Scheme := s.OpenApiSpec.Components.SecuritySchemes["oauth2"].Value + oauth2Scheme := s.OpenAPIzer.OpenAPIDescription().Components.SecuritySchemes["oauth2"].Value require.Equal(t, "oauth2", oauth2Scheme.Type) require.Equal(t, "https://example.com/.well-known/openid-configuration", oauth2Scheme.OpenIdConnectUrl) }) @@ -593,14 +593,14 @@ func TestWithSecurity(t *testing.T) { }), ) - require.NotNil(t, s.OpenApiSpec.Components.SecuritySchemes) - require.Contains(t, s.OpenApiSpec.Components.SecuritySchemes, "bearerAuth") - require.Contains(t, s.OpenApiSpec.Components.SecuritySchemes, "apiKey") + require.NotNil(t, s.OpenAPIzer.OpenAPIDescription().Components.SecuritySchemes) + require.Contains(t, s.OpenAPIzer.OpenAPIDescription().Components.SecuritySchemes, "bearerAuth") + require.Contains(t, s.OpenAPIzer.OpenAPIDescription().Components.SecuritySchemes, "apiKey") }) t.Run("initialize security schemes if nil", func(t *testing.T) { s := NewServer() - s.OpenApiSpec.Components.SecuritySchemes = nil + s.OpenAPIzer.OpenAPIDescription().Components.SecuritySchemes = nil s = NewServer( WithSecurity(openapi3.SecuritySchemes{ @@ -613,7 +613,7 @@ func TestWithSecurity(t *testing.T) { }), ) - require.NotNil(t, s.OpenApiSpec.Components.SecuritySchemes) - require.Contains(t, s.OpenApiSpec.Components.SecuritySchemes, "bearerAuth") + require.NotNil(t, s.OpenAPIzer.OpenAPIDescription().Components.SecuritySchemes) + require.Contains(t, s.OpenAPIzer.OpenAPIDescription().Components.SecuritySchemes, "bearerAuth") }) } From f6f56a2a230200addb0e2779159c50a4eef14eb6 Mon Sep 17 00:00:00 2001 From: EwenQuim Date: Wed, 11 Dec 2024 01:34:10 +0100 Subject: [PATCH 053/138] Renamed Spec to OpenAPI --- openapi.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/openapi.go b/openapi.go index a1c1f44d..769e3f4a 100644 --- a/openapi.go +++ b/openapi.go @@ -25,9 +25,9 @@ type OpenAPIzer interface { GlobalOpenAPIResponses() *[]openAPIError } -func NewSpec() *Spec { +func NewSpec() *OpenAPI { desc := NewOpenApiSpec() - return &Spec{ + return &OpenAPI{ description: &desc, generator: openapi3gen.NewGenerator(), globalOpenAPIResponses: &[]openAPIError{}, @@ -35,25 +35,25 @@ func NewSpec() *Spec { } // Holds the OpenAPI OpenAPIDescription (OAD) and OpenAPI capabilities. -type Spec struct { +type OpenAPI struct { description *openapi3.T generator *openapi3gen.Generator globalOpenAPIResponses *[]openAPIError } -func (d *Spec) OpenAPIDescription() *openapi3.T { +func (d *OpenAPI) OpenAPIDescription() *openapi3.T { return d.description } -func (d *Spec) Generator() *openapi3gen.Generator { +func (d *OpenAPI) Generator() *openapi3gen.Generator { return d.generator } -func (d *Spec) GlobalOpenAPIResponses() *[]openAPIError { +func (d *OpenAPI) GlobalOpenAPIResponses() *[]openAPIError { return d.globalOpenAPIResponses } -var _ OpenAPIzer = &Spec{} +var _ OpenAPIzer = &OpenAPI{} func NewOpenApiSpec() openapi3.T { info := &openapi3.Info{ From 8bac3d7390e7413a69d5a2a1ffb603a114ab628b Mon Sep 17 00:00:00 2001 From: EwenQuim Date: Wed, 11 Dec 2024 01:36:41 +0100 Subject: [PATCH 054/138] Removed interface and use a direct struct --- examples/full-app-gourmet/server/server.go | 2 +- examples/petstore/lib/server_test.go | 2 +- mux.go | 2 +- mux_test.go | 16 +++--- openapi.go | 60 +++++++++------------- openapi_operations.go | 2 +- openapi_test.go | 4 +- option.go | 10 ++-- option_test.go | 16 +++--- server.go | 20 +++----- server_test.go | 40 +++++++-------- 11 files changed, 79 insertions(+), 95 deletions(-) diff --git a/examples/full-app-gourmet/server/server.go b/examples/full-app-gourmet/server/server.go index 7988c613..abdf2b82 100644 --- a/examples/full-app-gourmet/server/server.go +++ b/examples/full-app-gourmet/server/server.go @@ -41,7 +41,7 @@ func (rs Resources) Setup( // Create server with some options app := fuego.NewServer(options...) - app.OpenApiSpec.Info.Title = "Gourmet API" + app.OpenAPI.Description().Info.Title = "Gourmet API" rs.API.Security = app.Security diff --git a/examples/petstore/lib/server_test.go b/examples/petstore/lib/server_test.go index 9260b76e..9d0b8914 100644 --- a/examples/petstore/lib/server_test.go +++ b/examples/petstore/lib/server_test.go @@ -21,7 +21,7 @@ func TestPetstoreOpenAPIGeneration(t *testing.T) { ) server.OutputOpenAPISpec() - err := server.OpenAPIzer.OpenAPIDescription().Validate(context.Background()) + err := server.OpenAPI.Description().Validate(context.Background()) require.NoError(t, err) generatedSpec, err := os.ReadFile("testdata/doc/openapi.json") diff --git a/mux.go b/mux.go index 4e208370..86cf074f 100644 --- a/mux.go +++ b/mux.go @@ -112,7 +112,7 @@ func Register[T, B any](s *Server, route Route[T, B], controller http.Handler, o route.Path = s.basePath + route.Path var err error - route.Operation, err = RegisterOpenAPIOperation(s.OpenAPIzer, route) + route.Operation, err = RegisterOpenAPIOperation(s.OpenAPI, route) if err != nil { slog.Warn("error documenting openapi operation", "error", err) } diff --git a/mux_test.go b/mux_test.go index f63c8b96..0d73a66e 100644 --- a/mux_test.go +++ b/mux_test.go @@ -488,8 +488,8 @@ func TestHideOpenapiRoutes(t *testing.T) { Get(s, "/test", func(ctx *ContextNoBody) (string, error) { return "", nil }) require.Equal(t, s.DisableOpenapi, true) - require.True(t, s.OpenAPIzer.OpenAPIDescription().Paths.Find("/not-hidden") != nil) - require.True(t, s.OpenAPIzer.OpenAPIDescription().Paths.Find("/test") == nil) + require.True(t, s.OpenAPI.Description().Paths.Find("/not-hidden") != nil) + require.True(t, s.OpenAPI.Description().Paths.Find("/test") == nil) }) t.Run("hide group", func(t *testing.T) { @@ -500,8 +500,8 @@ func TestHideOpenapiRoutes(t *testing.T) { Get(g, "/test", func(ctx *ContextNoBody) (string, error) { return "", nil }) require.Equal(t, g.DisableOpenapi, true) - require.True(t, s.OpenAPIzer.OpenAPIDescription().Paths.Find("/not-hidden") != nil) - require.True(t, s.OpenAPIzer.OpenAPIDescription().Paths.Find("/group/test") == nil) + require.True(t, s.OpenAPI.Description().Paths.Find("/not-hidden") != nil) + require.True(t, s.OpenAPI.Description().Paths.Find("/group/test") == nil) }) t.Run("hide group but not other group", func(t *testing.T) { @@ -514,8 +514,8 @@ func TestHideOpenapiRoutes(t *testing.T) { require.Equal(t, true, g.DisableOpenapi) require.Equal(t, false, g2.DisableOpenapi) - require.True(t, s.OpenAPIzer.OpenAPIDescription().Paths.Find("/group/test") == nil) - require.True(t, s.OpenAPIzer.OpenAPIDescription().Paths.Find("/group2/test") != nil) + require.True(t, s.OpenAPI.Description().Paths.Find("/group/test") == nil) + require.True(t, s.OpenAPI.Description().Paths.Find("/group2/test") != nil) }) t.Run("hide group but show sub group", func(t *testing.T) { @@ -527,8 +527,8 @@ func TestHideOpenapiRoutes(t *testing.T) { Get(g2, "/test", func(ctx *ContextNoBody) (string, error) { return "test", nil }) require.Equal(t, true, g.DisableOpenapi) - require.True(t, s.OpenAPIzer.OpenAPIDescription().Paths.Find("/group/test") == nil) - require.True(t, s.OpenAPIzer.OpenAPIDescription().Paths.Find("/group/sub/test") != nil) + require.True(t, s.OpenAPI.Description().Paths.Find("/group/test") == nil) + require.True(t, s.OpenAPI.Description().Paths.Find("/group/sub/test") != nil) }) } diff --git a/openapi.go b/openapi.go index 769e3f4a..d5c76f20 100644 --- a/openapi.go +++ b/openapi.go @@ -19,18 +19,12 @@ import ( "github.com/getkin/kin-openapi/openapi3gen" ) -type OpenAPIzer interface { - OpenAPIDescription() *openapi3.T - Generator() *openapi3gen.Generator - GlobalOpenAPIResponses() *[]openAPIError -} - -func NewSpec() *OpenAPI { +func NewOpenAPI() *OpenAPI { desc := NewOpenApiSpec() return &OpenAPI{ description: &desc, generator: openapi3gen.NewGenerator(), - globalOpenAPIResponses: &[]openAPIError{}, + globalOpenAPIResponses: []openAPIError{}, } } @@ -38,10 +32,10 @@ func NewSpec() *OpenAPI { type OpenAPI struct { description *openapi3.T generator *openapi3gen.Generator - globalOpenAPIResponses *[]openAPIError + globalOpenAPIResponses []openAPIError } -func (d *OpenAPI) OpenAPIDescription() *openapi3.T { +func (d *OpenAPI) Description() *openapi3.T { return d.description } @@ -49,12 +43,6 @@ func (d *OpenAPI) Generator() *openapi3gen.Generator { return d.generator } -func (d *OpenAPI) GlobalOpenAPIResponses() *[]openAPIError { - return d.globalOpenAPIResponses -} - -var _ OpenAPIzer = &OpenAPI{} - func NewOpenApiSpec() openapi3.T { info := &openapi3.Info{ Title: "OpenAPI", @@ -90,11 +78,11 @@ func (s *Server) Show() *Server { } func declareAllTagsFromOperations(s *Server) { - for _, pathItem := range s.OpenAPIzer.OpenAPIDescription().Paths.Map() { + for _, pathItem := range s.OpenAPI.Description().Paths.Map() { for _, op := range pathItem.Operations() { for _, tag := range op.Tags { - if s.OpenAPIzer.OpenAPIDescription().Tags.Get(tag) == nil { - s.OpenAPIzer.OpenAPIDescription().Tags = append(s.OpenAPIzer.OpenAPIDescription().Tags, &openapi3.Tag{ + if s.OpenAPI.Description().Tags.Get(tag) == nil { + s.OpenAPI.Description().Tags = append(s.OpenAPI.Description().Tags, &openapi3.Tag{ Name: tag, }) } @@ -110,7 +98,7 @@ func (s *Server) OutputOpenAPISpec() openapi3.T { declareAllTagsFromOperations(s) // Validate - err := s.OpenAPIzer.OpenAPIDescription().Validate(context.Background()) + err := s.OpenAPI.Description().Validate(context.Background()) if err != nil { slog.Error("Error validating spec", "error", err) } @@ -132,14 +120,14 @@ func (s *Server) OutputOpenAPISpec() openapi3.T { } } - return *s.OpenAPIzer.OpenAPIDescription() + return *s.OpenAPI.Description() } func (s *Server) marshalSpec() ([]byte, error) { if s.OpenAPIConfig.PrettyFormatJson { - return json.MarshalIndent(s.OpenAPIzer.OpenAPIDescription(), "", " ") + return json.MarshalIndent(s.OpenAPI.Description(), "", " ") } - return json.Marshal(s.OpenAPIzer.OpenAPIDescription()) + return json.Marshal(s.OpenAPI.Description()) } func (s *Server) saveOpenAPIToFile(jsonSpecLocalPath string, jsonSpec []byte) error { @@ -201,7 +189,7 @@ func validateSwaggerUrl(swaggerUrl string) bool { } // RegisterOpenAPIOperation registers an OpenAPI operation. -func RegisterOpenAPIOperation[T, B any](s OpenAPIzer, route Route[T, B]) (*openapi3.Operation, error) { +func RegisterOpenAPIOperation[T, B any](s *OpenAPI, route Route[T, B]) (*openapi3.Operation, error) { if route.Operation == nil { route.Operation = openapi3.NewOperation() } @@ -221,7 +209,7 @@ func RegisterOpenAPIOperation[T, B any](s OpenAPIzer, route Route[T, B]) (*opena } // Response - globals - for _, openAPIGlobalResponse := range *s.GlobalOpenAPIResponses() { + for _, openAPIGlobalResponse := range s.globalOpenAPIResponses { addResponseIfNotSet(s, route.Operation, openAPIGlobalResponse.Code, openAPIGlobalResponse.Description, openAPIGlobalResponse.ErrorType) } @@ -265,7 +253,7 @@ func RegisterOpenAPIOperation[T, B any](s OpenAPIzer, route Route[T, B]) (*opena } } - s.OpenAPIDescription().AddOperation(route.Path, route.Method, route.Operation) + s.Description().AddOperation(route.Path, route.Method, route.Operation) return route.Operation, nil } @@ -284,10 +272,10 @@ type SchemaTag struct { Name string } -func SchemaTagFromType(s OpenAPIzer, v any) SchemaTag { +func SchemaTagFromType(s *OpenAPI, v any) SchemaTag { if v == nil { // ensure we add unknown-interface to our schemas - schema := getOrCreateSchema(s, "unknown-interface", struct{}{}) + schema := s.getOrCreateSchema("unknown-interface", struct{}{}) return SchemaTag{ Name: "unknown-interface", SchemaRef: openapi3.SchemaRef{ @@ -307,7 +295,7 @@ func SchemaTagFromType(s OpenAPIzer, v any) SchemaTag { // If the type is a slice or array type it will dive into the type as well as // build and openapi3.Schema where Type is array and Ref is set to the proper // components Schema -func dive(s OpenAPIzer, t reflect.Type, tag SchemaTag, maxDepth int) SchemaTag { +func dive(s *OpenAPI, t reflect.Type, tag SchemaTag, maxDepth int) SchemaTag { if maxDepth == 0 { return SchemaTag{ Name: "default", @@ -334,7 +322,7 @@ func dive(s OpenAPIzer, t reflect.Type, tag SchemaTag, maxDepth int) SchemaTag { return dive(s, t.Field(0).Type, tag, maxDepth-1) } tag.Ref = "#/components/schemas/" + tag.Name - tag.Value = getOrCreateSchema(s, tag.Name, reflect.New(t).Interface()) + tag.Value = s.getOrCreateSchema(tag.Name, reflect.New(t).Interface()) return tag } @@ -342,18 +330,18 @@ func dive(s OpenAPIzer, t reflect.Type, tag SchemaTag, maxDepth int) SchemaTag { // getOrCreateSchema is used to get a schema from the OpenAPI spec. // If the schema does not exist, it will create a new schema and add it to the OpenAPI spec. -func getOrCreateSchema(s OpenAPIzer, key string, v any) *openapi3.Schema { - schemaRef, ok := s.OpenAPIDescription().Components.Schemas[key] +func (s *OpenAPI) getOrCreateSchema(key string, v any) *openapi3.Schema { + schemaRef, ok := s.Description().Components.Schemas[key] if !ok { - schemaRef = createSchema(s, key, v) + schemaRef = s.createSchema(key, v) } return schemaRef.Value } // createSchema is used to create a new schema and add it to the OpenAPI spec. // Relies on the openapi3gen package to generate the schema, and adds custom struct tags. -func createSchema(s OpenAPIzer, key string, v any) *openapi3.SchemaRef { - schemaRef, err := s.Generator().NewSchemaRefForValue(v, s.OpenAPIDescription().Components.Schemas) +func (s *OpenAPI) createSchema(key string, v any) *openapi3.SchemaRef { + schemaRef, err := s.Generator().NewSchemaRefForValue(v, s.Description().Components.Schemas) if err != nil { slog.Error("Error generating schema", "key", key, "error", err) } @@ -366,7 +354,7 @@ func createSchema(s OpenAPIzer, key string, v any) *openapi3.SchemaRef { parseStructTags(reflect.TypeOf(v), schemaRef) - s.OpenAPIDescription().Components.Schemas[key] = schemaRef + s.Description().Components.Schemas[key] = schemaRef return schemaRef } diff --git a/openapi_operations.go b/openapi_operations.go index 1bd5c4d5..2801d0fc 100644 --- a/openapi_operations.go +++ b/openapi_operations.go @@ -62,7 +62,7 @@ func (r Route[ResponseBody, RequestBody]) Param(paramType ParamType, name, descr } // Registers a response for the route, only if error for this code is not already set. -func addResponseIfNotSet(s OpenAPIzer, operation *openapi3.Operation, code int, description string, errorType ...any) { +func addResponseIfNotSet(s *OpenAPI, operation *openapi3.Operation, code int, description string, errorType ...any) { var responseSchema SchemaTag if len(errorType) > 0 { diff --git a/openapi_test.go b/openapi_test.go index 616c5a4c..9970950e 100644 --- a/openapi_test.go +++ b/openapi_test.go @@ -193,7 +193,7 @@ func Test_tagFromType(t *testing.T) { for _, tc := range tcs { t.Run(tc.name, func(t *testing.T) { - tag := SchemaTagFromType(s, tc.inputType) + tag := SchemaTagFromType(s.OpenAPI, tc.inputType) require.Equal(t, tc.expectedTagValue, tag.Name, tc.description) if tc.expectedTagValueType != nil { require.NotNil(t, tag.Value) @@ -545,7 +545,7 @@ func TestDeclareCustom200Response(t *testing.T) { w.Write([]byte("PNG image")) }, optionReturnsPNG) - openAPIResponse := s.OpenAPIzer.OpenAPIDescription().Paths.Find("/image").Get.Responses.Value("200") + openAPIResponse := s.OpenAPI.Description().Paths.Find("/image").Get.Responses.Value("200") require.Nil(t, openAPIResponse.Value.Content.Get("application/json")) require.NotNil(t, openAPIResponse.Value.Content.Get("image/png")) require.Equal(t, "Generated image", *openAPIResponse.Value.Description) diff --git a/option.go b/option.go index 0f263209..ea5eb647 100644 --- a/option.go +++ b/option.go @@ -200,7 +200,7 @@ func buildParam(name string, options ...func(*OpenAPIParam)) (OpenAPIParam, *ope option(¶m) } - // Applies OpenAPIParam to openapi3.Parameter + // Applies *OpenAPIParam to openapi3.Parameter // Why not use openapi3.NewHeaderParameter(name) directly? // Because we might change the openapi3 library in the future, // and we want to keep the flexibility to change the implementation without changing the API. @@ -302,9 +302,9 @@ func OptionAddError(code int, description string, errorType ...any) func(*BaseRo } if len(errorType) > 0 { - responseSchema = SchemaTagFromType(r.mainRouter.OpenAPIzer, errorType[0]) + responseSchema = SchemaTagFromType(r.mainRouter.OpenAPI, errorType[0]) } else { - responseSchema = SchemaTagFromType(r.mainRouter.OpenAPIzer, HTTPError{}) + responseSchema = SchemaTagFromType(r.mainRouter.OpenAPI, HTTPError{}) } content := openapi3.NewContentWithSchemaRef(&responseSchema.SchemaRef, []string{"application/json"}) @@ -374,14 +374,14 @@ func OptionDefaultStatusCode(defaultStatusCode int) func(*BaseRoute) { // }) func OptionSecurity(securityRequirements ...openapi3.SecurityRequirement) func(*BaseRoute) { return func(r *BaseRoute) { - if r.mainRouter.OpenAPIzer.OpenAPIDescription().Components == nil { + if r.mainRouter.OpenAPI.Description().Components == nil { panic("zero security schemes have been registered with the server") } // Validate the security scheme exists in components for _, req := range securityRequirements { for schemeName := range req { - if _, exists := r.mainRouter.OpenAPIzer.OpenAPIDescription().Components.SecuritySchemes[schemeName]; !exists { + if _, exists := r.mainRouter.OpenAPI.Description().Components.SecuritySchemes[schemeName]; !exists { panic(fmt.Sprintf("security scheme '%s' not defined in components", schemeName)) } } diff --git a/option_test.go b/option_test.go index 1df04900..61196994 100644 --- a/option_test.go +++ b/option_test.go @@ -299,8 +299,8 @@ func TestPath(t *testing.T) { fuego.Get(s, "/test/{id}", helloWorld) - require.Equal(t, "id", s.OpenAPIzer.OpenAPIDescription().Paths.Find("/test/{id}").Get.Parameters.GetByInAndName("path", "id").Name) - require.Equal(t, "", s.OpenAPIzer.OpenAPIDescription().Paths.Find("/test/{id}").Get.Parameters.GetByInAndName("path", "id").Description) + require.Equal(t, "id", s.OpenAPI.Description().Paths.Find("/test/{id}").Get.Parameters.GetByInAndName("path", "id").Name) + require.Equal(t, "", s.OpenAPI.Description().Paths.Find("/test/{id}").Get.Parameters.GetByInAndName("path", "id").Description) }) t.Run("Declare explicitly an existing path parameter for the route", func(t *testing.T) { @@ -310,9 +310,9 @@ func TestPath(t *testing.T) { fuego.OptionPath("id", "some id", param.Example("123", "123"), param.Nullable()), ) - require.Equal(t, "id", s.OpenAPIzer.OpenAPIDescription().Paths.Find("/test/{id}").Get.Parameters.GetByInAndName("path", "id").Name) - require.Equal(t, "some id", s.OpenAPIzer.OpenAPIDescription().Paths.Find("/test/{id}").Get.Parameters.GetByInAndName("path", "id").Description) - require.Equal(t, true, s.OpenAPIzer.OpenAPIDescription().Paths.Find("/test/{id}").Get.Parameters.GetByInAndName("path", "id").Required, "path parameter is forced to be required") + require.Equal(t, "id", s.OpenAPI.Description().Paths.Find("/test/{id}").Get.Parameters.GetByInAndName("path", "id").Name) + require.Equal(t, "some id", s.OpenAPI.Description().Paths.Find("/test/{id}").Get.Parameters.GetByInAndName("path", "id").Description) + require.Equal(t, true, s.OpenAPI.Description().Paths.Find("/test/{id}").Get.Parameters.GetByInAndName("path", "id").Required, "path parameter is forced to be required") }) t.Run("Declare explicitly a non-existing path parameter for the route panics", func(t *testing.T) { @@ -353,7 +353,7 @@ func TestRequestContentType(t *testing.T) { require.NotNil(t, content.Get("application/json")) require.Nil(t, content.Get("application/xml")) require.Equal(t, "#/components/schemas/ReqBody", content.Get("application/json").Schema.Ref) - _, ok := s.OpenAPIzer.OpenAPIDescription().Components.RequestBodies["ReqBody"] + _, ok := s.OpenAPI.Description().Components.RequestBodies["ReqBody"] require.False(t, ok) }) @@ -369,7 +369,7 @@ func TestRequestContentType(t *testing.T) { require.Nil(t, content.Get("application/xml")) require.Equal(t, "#/components/schemas/ReqBody", content.Get("application/json").Schema.Ref) require.Equal(t, "#/components/schemas/ReqBody", content.Get("my/content-type").Schema.Ref) - _, ok := s.OpenAPIzer.OpenAPIDescription().Components.RequestBodies["ReqBody"] + _, ok := s.OpenAPI.Description().Components.RequestBodies["ReqBody"] require.False(t, ok) }) @@ -385,7 +385,7 @@ func TestRequestContentType(t *testing.T) { require.Nil(t, content.Get("application/xml")) require.NotNil(t, content.Get("my/content-type")) require.Equal(t, "#/components/schemas/ReqBody", content.Get("my/content-type").Schema.Ref) - _, ok := s.OpenAPIzer.OpenAPIDescription().Components.RequestBodies["ReqBody"] + _, ok := s.OpenAPI.Description().Components.RequestBodies["ReqBody"] require.False(t, ok) }) } diff --git a/server.go b/server.go index 535a0bae..5a026c89 100644 --- a/server.go +++ b/server.go @@ -59,10 +59,8 @@ type Server struct { mainRouter *Server // Ref to the main router (used for groups) basePath string // Base path of the group - globalOpenAPIResponses []openAPIError // Global error responses - - // OpenAPIzer handles the OpenAPI spec generation. - OpenAPIzer + // OpenAPI handles the OpenAPI spec generation. + OpenAPI *OpenAPI Security Security @@ -109,7 +107,7 @@ func NewServer(options ...func(*Server)) *Server { Mux: http.NewServeMux(), OpenAPIConfig: defaultOpenAPIConfig, - OpenAPIzer: NewSpec(), + OpenAPI: NewOpenAPI(), openAPIGenerator: openapi3gen.NewGenerator( openapi3gen.UseAllExportedFields(), @@ -138,7 +136,7 @@ func NewServer(options ...func(*Server)) *Server { option(s) } - s.OpenAPIzer.OpenAPIDescription().Servers = append(s.OpenAPIzer.OpenAPIDescription().Servers, &openapi3.Server{ + s.OpenAPI.Description().Servers = append(s.OpenAPI.Description().Servers, &openapi3.Server{ URL: "http://" + s.Addr, Description: "local server", }) @@ -214,9 +212,7 @@ func WithCorsMiddleware(corsMiddleware func(http.Handler) http.Handler) func(*Se func WithGlobalResponseTypes(code int, description string, errorType ...any) func(*Server) { errorType = append(errorType, HTTPError{}) return func(c *Server) { - c.globalOpenAPIResponses = append(c.globalOpenAPIResponses, openAPIError{code, description, errorType[0]}) - truc := c.OpenAPIzer.GlobalOpenAPIResponses() - *truc = append(*truc, openAPIError{code, description, errorType[0]}) + c.OpenAPI.globalOpenAPIResponses = append(c.OpenAPI.globalOpenAPIResponses, openAPIError{code, description, errorType[0]}) } } @@ -237,11 +233,11 @@ func WithGlobalResponseTypes(code int, description string, errorType ...any) fun // ) func WithSecurity(schemes openapi3.SecuritySchemes) func(*Server) { return func(s *Server) { - if s.OpenAPIzer.OpenAPIDescription().Components.SecuritySchemes == nil { - s.OpenAPIzer.OpenAPIDescription().Components.SecuritySchemes = openapi3.SecuritySchemes{} + if s.OpenAPI.Description().Components.SecuritySchemes == nil { + s.OpenAPI.Description().Components.SecuritySchemes = openapi3.SecuritySchemes{} } for name, scheme := range schemes { - s.OpenAPIzer.OpenAPIDescription().Components.SecuritySchemes[name] = scheme + s.OpenAPI.Description().Components.SecuritySchemes[name] = scheme } } } diff --git a/server_test.go b/server_test.go index 75801820..671cfc5e 100644 --- a/server_test.go +++ b/server_test.go @@ -334,7 +334,7 @@ func TestWithRequestContentType(t *testing.T) { require.NotNil(t, content.Get("application/xml")) require.Equal(t, "#/components/schemas/ReqBody", content.Get("application/json").Schema.Ref) require.Equal(t, "#/components/schemas/ReqBody", content.Get("application/xml").Schema.Ref) - _, ok := s.OpenAPIzer.OpenAPIDescription().Components.RequestBodies["ReqBody"] + _, ok := s.OpenAPI.Description().Components.RequestBodies["ReqBody"] require.False(t, ok) }) } @@ -503,10 +503,10 @@ func TestWithSecurity(t *testing.T) { }), ) - require.NotNil(t, s.OpenAPIzer.OpenAPIDescription().Components.SecuritySchemes) - require.Contains(t, s.OpenAPIzer.OpenAPIDescription().Components.SecuritySchemes, "bearerAuth") + require.NotNil(t, s.OpenAPI.Description().Components.SecuritySchemes) + require.Contains(t, s.OpenAPI.Description().Components.SecuritySchemes, "bearerAuth") - scheme := s.OpenAPIzer.OpenAPIDescription().Components.SecuritySchemes["bearerAuth"].Value + scheme := s.OpenAPI.Description().Components.SecuritySchemes["bearerAuth"].Value require.Equal(t, "http", scheme.Type) require.Equal(t, "bearer", scheme.Scheme) require.Equal(t, "JWT", scheme.BearerFormat) @@ -530,12 +530,12 @@ func TestWithSecurity(t *testing.T) { }), ) - require.NotNil(t, s.OpenAPIzer.OpenAPIDescription().Components.SecuritySchemes) - require.Contains(t, s.OpenAPIzer.OpenAPIDescription().Components.SecuritySchemes, "bearerAuth") - require.Contains(t, s.OpenAPIzer.OpenAPIDescription().Components.SecuritySchemes, "apiKey") + require.NotNil(t, s.OpenAPI.Description().Components.SecuritySchemes) + require.Contains(t, s.OpenAPI.Description().Components.SecuritySchemes, "bearerAuth") + require.Contains(t, s.OpenAPI.Description().Components.SecuritySchemes, "apiKey") - bearerScheme := s.OpenAPIzer.OpenAPIDescription().Components.SecuritySchemes["bearerAuth"].Value - apiKeyScheme := s.OpenAPIzer.OpenAPIDescription().Components.SecuritySchemes["apiKey"].Value + bearerScheme := s.OpenAPI.Description().Components.SecuritySchemes["bearerAuth"].Value + apiKeyScheme := s.OpenAPI.Description().Components.SecuritySchemes["apiKey"].Value require.Equal(t, "http", bearerScheme.Type) require.Equal(t, "bearer", bearerScheme.Scheme) @@ -559,16 +559,16 @@ func TestWithSecurity(t *testing.T) { ) // Add another security scheme to the existing server - s.OpenAPIzer.OpenAPIDescription().Components.SecuritySchemes["oauth2"] = &openapi3.SecuritySchemeRef{ + s.OpenAPI.Description().Components.SecuritySchemes["oauth2"] = &openapi3.SecuritySchemeRef{ Value: openapi3.NewOIDCSecurityScheme("https://example.com/.well-known/openid-configuration"). WithType("oauth2"), } - require.NotNil(t, s.OpenAPIzer.OpenAPIDescription().Components.SecuritySchemes) - require.Contains(t, s.OpenAPIzer.OpenAPIDescription().Components.SecuritySchemes, "bearerAuth") - require.Contains(t, s.OpenAPIzer.OpenAPIDescription().Components.SecuritySchemes, "oauth2") + require.NotNil(t, s.OpenAPI.Description().Components.SecuritySchemes) + require.Contains(t, s.OpenAPI.Description().Components.SecuritySchemes, "bearerAuth") + require.Contains(t, s.OpenAPI.Description().Components.SecuritySchemes, "oauth2") - oauth2Scheme := s.OpenAPIzer.OpenAPIDescription().Components.SecuritySchemes["oauth2"].Value + oauth2Scheme := s.OpenAPI.Description().Components.SecuritySchemes["oauth2"].Value require.Equal(t, "oauth2", oauth2Scheme.Type) require.Equal(t, "https://example.com/.well-known/openid-configuration", oauth2Scheme.OpenIdConnectUrl) }) @@ -593,14 +593,14 @@ func TestWithSecurity(t *testing.T) { }), ) - require.NotNil(t, s.OpenAPIzer.OpenAPIDescription().Components.SecuritySchemes) - require.Contains(t, s.OpenAPIzer.OpenAPIDescription().Components.SecuritySchemes, "bearerAuth") - require.Contains(t, s.OpenAPIzer.OpenAPIDescription().Components.SecuritySchemes, "apiKey") + require.NotNil(t, s.OpenAPI.Description().Components.SecuritySchemes) + require.Contains(t, s.OpenAPI.Description().Components.SecuritySchemes, "bearerAuth") + require.Contains(t, s.OpenAPI.Description().Components.SecuritySchemes, "apiKey") }) t.Run("initialize security schemes if nil", func(t *testing.T) { s := NewServer() - s.OpenAPIzer.OpenAPIDescription().Components.SecuritySchemes = nil + s.OpenAPI.Description().Components.SecuritySchemes = nil s = NewServer( WithSecurity(openapi3.SecuritySchemes{ @@ -613,7 +613,7 @@ func TestWithSecurity(t *testing.T) { }), ) - require.NotNil(t, s.OpenAPIzer.OpenAPIDescription().Components.SecuritySchemes) - require.Contains(t, s.OpenAPIzer.OpenAPIDescription().Components.SecuritySchemes, "bearerAuth") + require.NotNil(t, s.OpenAPI.Description().Components.SecuritySchemes) + require.Contains(t, s.OpenAPI.Description().Components.SecuritySchemes, "bearerAuth") }) } From a7df7e4103a3e2ef44d620e7e1333a5b5f0c4d95 Mon Sep 17 00:00:00 2001 From: EwenQuim Date: Thu, 12 Dec 2024 09:41:06 +0100 Subject: [PATCH 055/138] Renamed OpenAPI parameter --- openapi.go | 40 ++++++++++++++++++++-------------------- openapi_operations.go | 6 +++--- option.go | 2 +- server.go | 4 ++-- 4 files changed, 26 insertions(+), 26 deletions(-) diff --git a/openapi.go b/openapi.go index d5c76f20..627ec204 100644 --- a/openapi.go +++ b/openapi.go @@ -189,14 +189,14 @@ func validateSwaggerUrl(swaggerUrl string) bool { } // RegisterOpenAPIOperation registers an OpenAPI operation. -func RegisterOpenAPIOperation[T, B any](s *OpenAPI, route Route[T, B]) (*openapi3.Operation, error) { +func RegisterOpenAPIOperation[T, B any](openapi *OpenAPI, route Route[T, B]) (*openapi3.Operation, error) { if route.Operation == nil { route.Operation = openapi3.NewOperation() } // Request Body if route.Operation.RequestBody == nil { - bodyTag := SchemaTagFromType(s, *new(B)) + bodyTag := SchemaTagFromType(openapi, *new(B)) if bodyTag.Name != "unknown-interface" { requestBody := newRequestBody[B](bodyTag, route.AcceptedContentTypes) @@ -209,8 +209,8 @@ func RegisterOpenAPIOperation[T, B any](s *OpenAPI, route Route[T, B]) (*openapi } // Response - globals - for _, openAPIGlobalResponse := range s.globalOpenAPIResponses { - addResponseIfNotSet(s, route.Operation, openAPIGlobalResponse.Code, openAPIGlobalResponse.Description, openAPIGlobalResponse.ErrorType) + for _, openAPIGlobalResponse := range openapi.globalOpenAPIResponses { + addResponseIfNotSet(openapi, route.Operation, openAPIGlobalResponse.Code, openAPIGlobalResponse.Description, openAPIGlobalResponse.ErrorType) } // Automatically add non-declared 200 (or other) Response @@ -227,7 +227,7 @@ func RegisterOpenAPIOperation[T, B any](s *OpenAPI, route Route[T, B]) (*openapi // Automatically add non-declared Content for 200 (or other) Response if responseDefault.Value.Content == nil { - responseSchema := SchemaTagFromType(s, *new(T)) + responseSchema := SchemaTagFromType(openapi, *new(T)) content := openapi3.NewContentWithSchemaRef(&responseSchema.SchemaRef, []string{"application/json", "application/xml"}) responseDefault.Value.WithContent(content) } @@ -253,7 +253,7 @@ func RegisterOpenAPIOperation[T, B any](s *OpenAPI, route Route[T, B]) (*openapi } } - s.Description().AddOperation(route.Path, route.Method, route.Operation) + openapi.Description().AddOperation(route.Path, route.Method, route.Operation) return route.Operation, nil } @@ -272,10 +272,10 @@ type SchemaTag struct { Name string } -func SchemaTagFromType(s *OpenAPI, v any) SchemaTag { +func SchemaTagFromType(openapi *OpenAPI, v any) SchemaTag { if v == nil { // ensure we add unknown-interface to our schemas - schema := s.getOrCreateSchema("unknown-interface", struct{}{}) + schema := openapi.getOrCreateSchema("unknown-interface", struct{}{}) return SchemaTag{ Name: "unknown-interface", SchemaRef: openapi3.SchemaRef{ @@ -285,7 +285,7 @@ func SchemaTagFromType(s *OpenAPI, v any) SchemaTag { } } - return dive(s, reflect.TypeOf(v), SchemaTag{}, 5) + return dive(openapi, reflect.TypeOf(v), SchemaTag{}, 5) } // dive returns a schemaTag which includes the generated openapi3.SchemaRef and @@ -295,7 +295,7 @@ func SchemaTagFromType(s *OpenAPI, v any) SchemaTag { // If the type is a slice or array type it will dive into the type as well as // build and openapi3.Schema where Type is array and Ref is set to the proper // components Schema -func dive(s *OpenAPI, t reflect.Type, tag SchemaTag, maxDepth int) SchemaTag { +func dive(openapi *OpenAPI, t reflect.Type, tag SchemaTag, maxDepth int) SchemaTag { if maxDepth == 0 { return SchemaTag{ Name: "default", @@ -307,10 +307,10 @@ func dive(s *OpenAPI, t reflect.Type, tag SchemaTag, maxDepth int) SchemaTag { switch t.Kind() { case reflect.Ptr, reflect.Map, reflect.Chan, reflect.Func, reflect.UnsafePointer: - return dive(s, t.Elem(), tag, maxDepth-1) + return dive(openapi, t.Elem(), tag, maxDepth-1) case reflect.Slice, reflect.Array: - item := dive(s, t.Elem(), tag, maxDepth-1) + item := dive(openapi, t.Elem(), tag, maxDepth-1) tag.Name = item.Name tag.Value = openapi3.NewArraySchema() tag.Value.Items = &item.SchemaRef @@ -319,10 +319,10 @@ func dive(s *OpenAPI, t reflect.Type, tag SchemaTag, maxDepth int) SchemaTag { default: tag.Name = t.Name() if t.Kind() == reflect.Struct && strings.HasPrefix(tag.Name, "DataOrTemplate") { - return dive(s, t.Field(0).Type, tag, maxDepth-1) + return dive(openapi, t.Field(0).Type, tag, maxDepth-1) } tag.Ref = "#/components/schemas/" + tag.Name - tag.Value = s.getOrCreateSchema(tag.Name, reflect.New(t).Interface()) + tag.Value = openapi.getOrCreateSchema(tag.Name, reflect.New(t).Interface()) return tag } @@ -330,18 +330,18 @@ func dive(s *OpenAPI, t reflect.Type, tag SchemaTag, maxDepth int) SchemaTag { // getOrCreateSchema is used to get a schema from the OpenAPI spec. // If the schema does not exist, it will create a new schema and add it to the OpenAPI spec. -func (s *OpenAPI) getOrCreateSchema(key string, v any) *openapi3.Schema { - schemaRef, ok := s.Description().Components.Schemas[key] +func (openapi *OpenAPI) getOrCreateSchema(key string, v any) *openapi3.Schema { + schemaRef, ok := openapi.Description().Components.Schemas[key] if !ok { - schemaRef = s.createSchema(key, v) + schemaRef = openapi.createSchema(key, v) } return schemaRef.Value } // createSchema is used to create a new schema and add it to the OpenAPI spec. // Relies on the openapi3gen package to generate the schema, and adds custom struct tags. -func (s *OpenAPI) createSchema(key string, v any) *openapi3.SchemaRef { - schemaRef, err := s.Generator().NewSchemaRefForValue(v, s.Description().Components.Schemas) +func (openapi *OpenAPI) createSchema(key string, v any) *openapi3.SchemaRef { + schemaRef, err := openapi.Generator().NewSchemaRefForValue(v, openapi.Description().Components.Schemas) if err != nil { slog.Error("Error generating schema", "key", key, "error", err) } @@ -354,7 +354,7 @@ func (s *OpenAPI) createSchema(key string, v any) *openapi3.SchemaRef { parseStructTags(reflect.TypeOf(v), schemaRef) - s.Description().Components.Schemas[key] = schemaRef + openapi.Description().Components.Schemas[key] = schemaRef return schemaRef } diff --git a/openapi_operations.go b/openapi_operations.go index 2801d0fc..aace4fb1 100644 --- a/openapi_operations.go +++ b/openapi_operations.go @@ -62,13 +62,13 @@ func (r Route[ResponseBody, RequestBody]) Param(paramType ParamType, name, descr } // Registers a response for the route, only if error for this code is not already set. -func addResponseIfNotSet(s *OpenAPI, operation *openapi3.Operation, code int, description string, errorType ...any) { +func addResponseIfNotSet(openapi *OpenAPI, operation *openapi3.Operation, code int, description string, errorType ...any) { var responseSchema SchemaTag if len(errorType) > 0 { - responseSchema = SchemaTagFromType(s, errorType[0]) + responseSchema = SchemaTagFromType(openapi, errorType[0]) } else { - responseSchema = SchemaTagFromType(s, HTTPError{}) + responseSchema = SchemaTagFromType(openapi, HTTPError{}) } content := openapi3.NewContentWithSchemaRef(&responseSchema.SchemaRef, []string{"application/json"}) diff --git a/option.go b/option.go index ea5eb647..8ea40cfa 100644 --- a/option.go +++ b/option.go @@ -200,7 +200,7 @@ func buildParam(name string, options ...func(*OpenAPIParam)) (OpenAPIParam, *ope option(¶m) } - // Applies *OpenAPIParam to openapi3.Parameter + // Applies OpenAPIParam to openapi3.Parameter // Why not use openapi3.NewHeaderParameter(name) directly? // Because we might change the openapi3 library in the future, // and we want to keep the flexibility to change the implementation without changing the API. diff --git a/server.go b/server.go index 5a026c89..8d2cf99b 100644 --- a/server.go +++ b/server.go @@ -104,10 +104,10 @@ func NewServer(options ...func(*Server)) *Server { WriteTimeout: 30 * time.Second, IdleTimeout: 30 * time.Second, }, - Mux: http.NewServeMux(), + Mux: http.NewServeMux(), + OpenAPI: NewOpenAPI(), OpenAPIConfig: defaultOpenAPIConfig, - OpenAPI: NewOpenAPI(), openAPIGenerator: openapi3gen.NewGenerator( openapi3gen.UseAllExportedFields(), From fe68933f312edcdcb72cd4239fc2f4d64cb3e2d6 Mon Sep 17 00:00:00 2001 From: EwenQuim Date: Thu, 12 Dec 2024 10:01:48 +0100 Subject: [PATCH 056/138] Moved RegisterOpenAPIOperation to Route method --- mux.go | 3 +-- openapi.go | 10 ++++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/mux.go b/mux.go index 86cf074f..3a13e7be 100644 --- a/mux.go +++ b/mux.go @@ -111,8 +111,7 @@ func Register[T, B any](s *Server, route Route[T, B], controller http.Handler, o route.Path = s.basePath + route.Path - var err error - route.Operation, err = RegisterOpenAPIOperation(s.OpenAPI, route) + err := route.RegisterOpenAPIOperation(s.OpenAPI) if err != nil { slog.Warn("error documenting openapi operation", "error", err) } diff --git a/openapi.go b/openapi.go index 627ec204..e08ae26e 100644 --- a/openapi.go +++ b/openapi.go @@ -188,7 +188,17 @@ func validateSwaggerUrl(swaggerUrl string) bool { return swaggerUrlRegexp.MatchString(swaggerUrl) } +// RegisterOpenAPIOperation registers the route to the OpenAPI description. +// Modifies the route's Operation. +func (route *Route[ResponseBody, RequestBody]) RegisterOpenAPIOperation(openapi *OpenAPI) error { + operation, err := RegisterOpenAPIOperation(openapi, *route) + route.Operation = operation + return err +} + // RegisterOpenAPIOperation registers an OpenAPI operation. +// +// Deprecated: Use `(*Route[ResponseBody, RequestBody]).RegisterOpenAPIOperation` instead. func RegisterOpenAPIOperation[T, B any](openapi *OpenAPI, route Route[T, B]) (*openapi3.Operation, error) { if route.Operation == nil { route.Operation = openapi3.NewOperation() From e7fde336dc79fee78ce7be7f7a5b2c9e3e32aae1 Mon Sep 17 00:00:00 2001 From: Ewen Quimerc'h <46993939+EwenQuim@users.noreply.github.com> Date: Fri, 13 Dec 2024 19:57:43 +0100 Subject: [PATCH 057/138] Added Security Policy (#269) --- Makefile | 2 +- SECURITY.md | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 SECURITY.md diff --git a/Makefile b/Makefile index 7d6ca163..1c245d57 100644 --- a/Makefile +++ b/Makefile @@ -37,7 +37,7 @@ lint: golangci-lint run ${FIX} ./... lint-markdown: - markdownlint --ignore documentation/node_modules --dot . + markdownlint ${FIX} --ignore documentation/node_modules --dot . # Update golden files golden-update: diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 00000000..eedd94c6 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,25 @@ +# Security Policy + +## Supported Versions + +The following table outlines which versions of Fuego are actively supported with security updates. Please ensure that you are using a supported version to benefit from the latest patches and improvements. + +| Version | Supported | +| ----------------------------------------------- | ---------------------- | +| 0.x.y (x being the latest version released) | :white_check_mark: Yes | +| 0.x.y (x being NOT the latest version released) | :x: No | + +## Reporting a Vulnerability + +Fuego relies on its community to ensure its security. Here is how to report a vulnerability: + +1. **Send a Pull Request (PR):** If possible, immediately send a PR addressing the vulnerability and tag the maintainers for a quick review. +2. **Dependency Issues:** For supply chain or dependency-related vulnerabilities, update the all modules with `make check-all-modules` and submit a PR. +3. **Direct Contact:** If you cannot send a PR or the issue requires further discussion, please contact the maintainers directly by email. + +### Important Notes + +- Please do not publicly disclose the vulnerability until it has been addressed and patched. +- We are committed to transparency and will publicly acknowledge reporters in the release notes unless requested otherwise. + +Your cooperation helps ensure Fuego remains a secure and reliable framework for everyone. From d056980d4af14c122fdcdbe30805c7df7ba2b23f Mon Sep 17 00:00:00 2001 From: EwenQuim Date: Fri, 13 Dec 2024 20:10:01 +0100 Subject: [PATCH 058/138] Trying to fix flaky test on CI by changing listening port --- serve_test.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/serve_test.go b/serve_test.go index c719fab7..8f11a599 100644 --- a/serve_test.go +++ b/serve_test.go @@ -486,7 +486,10 @@ func TestServer_RunTLS(t *testing.T) { } for _, tc := range tt { t.Run(tc.name, func(t *testing.T) { - s := NewServer(WithoutLogger()) + s := NewServer( + WithoutLogger(), + WithAddr("localhost:3005"), + ) if tc.tlsConfig != nil { s.Server.TLSConfig = tc.tlsConfig @@ -497,7 +500,10 @@ func TestServer_RunTLS(t *testing.T) { }) go func() { // start our test server async - _ = s.RunTLS(tc.certFile, tc.keyFile) + err := s.RunTLS(tc.certFile, tc.keyFile) + if err != nil { + t.Log(err) + } }() defer func() { // stop our test server when we are done ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) From f3d7823d4b2d23f0b5edc3a2dc4933890f67b4bb Mon Sep 17 00:00:00 2001 From: EwenQuim Date: Fri, 13 Dec 2024 21:19:11 +0100 Subject: [PATCH 059/138] Removes unused Param method from Route struct --- mux.go | 4 ++-- openapi_operations.go | 23 ----------------------- 2 files changed, 2 insertions(+), 25 deletions(-) diff --git a/mux.go b/mux.go index 3a13e7be..d88be2d0 100644 --- a/mux.go +++ b/mux.go @@ -237,8 +237,8 @@ func FuncName(f interface{}) string { // // The output can be further modified with a list of optional // string manipulation funcs (i.e func(string) string) -func (r Route[T, B]) NameFromNamespace(opts ...func(string) string) string { - ss := strings.Split(r.FullName, ".") +func (route Route[T, B]) NameFromNamespace(opts ...func(string) string) string { + ss := strings.Split(route.FullName, ".") name := ss[len(ss)-1] for _, o := range opts { name = o(name) diff --git a/openapi_operations.go b/openapi_operations.go index aace4fb1..e35380d6 100644 --- a/openapi_operations.go +++ b/openapi_operations.go @@ -38,29 +38,6 @@ type OpenAPIParamOption struct { StatusCodes []int } -// Param registers a parameter for the route. -// The paramType can be "query", "header" or "cookie" as defined in [ParamType]. -// [Cookie], [Header], [QueryParam] are shortcuts for Param. -func (r Route[ResponseBody, RequestBody]) Param(paramType ParamType, name, description string, params ...OpenAPIParamOption) Route[ResponseBody, RequestBody] { - openapiParam := openapi3.NewHeaderParameter(name) - openapiParam.Description = description - openapiParam.Schema = openapi3.NewStringSchema().NewRef() - openapiParam.In = string(paramType) - - for _, param := range params { - if param.Required { - openapiParam.Required = param.Required - } - if param.Example != "" { - openapiParam.Example = param.Example - } - } - - r.Operation.AddParameter(openapiParam) - - return r -} - // Registers a response for the route, only if error for this code is not already set. func addResponseIfNotSet(openapi *OpenAPI, operation *openapi3.Operation, code int, description string, errorType ...any) { var responseSchema SchemaTag From 359fde09479b3a850af076665432a0c797810e93 Mon Sep 17 00:00:00 2001 From: Ewen Quimerc'h <46993939+EwenQuim@users.noreply.github.com> Date: Fri, 13 Dec 2024 21:21:04 +0100 Subject: [PATCH 060/138] Adds a direct reference to the OpenAPI object in the BaseRoute object (#271) Instead of referencing the main router and only use OpenAPI field... --- mux.go | 24 ++++++++---------------- option.go | 8 ++++---- server.go | 5 ++--- 3 files changed, 14 insertions(+), 23 deletions(-) diff --git a/mux.go b/mux.go index d88be2d0..2cbc51b7 100644 --- a/mux.go +++ b/mux.go @@ -38,7 +38,6 @@ func Group(s *Server, path string, routeOptions ...func(*BaseRoute)) *Server { if autoTag := strings.TrimLeft(path, "/"); !s.disableAutoGroupTags && autoTag != "" { newServer.routeOptions = append(s.routeOptions, OptionTags(autoTag)) } - newServer.mainRouter = s newServer.routeOptions = append(newServer.routeOptions, routeOptions...) @@ -60,8 +59,7 @@ type BaseRoute struct { AcceptedContentTypes []string // Content types accepted for the request body. If nil, all content types (*/*) are accepted. Hidden bool // If true, the route will not be documented in the OpenAPI spec DefaultStatusCode int // Default status code for the response - - mainRouter *Server // ref to the main router, used to register the route in the OpenAPI spec + OpenAPI *OpenAPI // Ref to the whole OpenAPI spec } // Capture all methods (GET, POST, PUT, PATCH, DELETE) and register a controller. @@ -129,7 +127,6 @@ func Register[T, B any](s *Server, route Route[T, B], controller http.Handler, o if route.Operation.OperationID == "" { route.Operation.OperationID = route.Method + "_" + strings.ReplaceAll(strings.ReplaceAll(route.Path, "{", ":"), "}", "") } - route.mainRouter = s return &route } @@ -179,20 +176,14 @@ func PatchStd(s *Server, path string, controller func(http.ResponseWriter, *http func registerFuegoController[T, B any, Contexted ctx[B]](s *Server, method, path string, controller func(Contexted) (T, error), options ...func(*BaseRoute)) *Route[T, B] { route := BaseRoute{ - Method: method, - Path: path, - Params: make(map[string]OpenAPIParam), - FullName: FuncName(controller), - Operation: openapi3.NewOperation(), - mainRouter: s.mainRouter, - } - // Copy the params from the server/group, and add the route ones - if route.mainRouter == nil { - route.mainRouter = s + Method: method, + Path: path, + Params: make(map[string]OpenAPIParam), + FullName: FuncName(controller), + Operation: openapi3.NewOperation(), + OpenAPI: s.OpenAPI, } - route.AcceptedContentTypes = route.mainRouter.acceptedContentTypes - acceptHeaderParameter := openapi3.NewHeaderParameter("Accept") acceptHeaderParameter.Schema = openapi3.NewStringSchema().NewRef() route.Operation.AddParameter(acceptHeaderParameter) @@ -210,6 +201,7 @@ func registerStdController(s *Server, method, path string, controller func(http. Path: path, FullName: FuncName(controller), Operation: openapi3.NewOperation(), + OpenAPI: s.OpenAPI, } for _, o := range append(s.routeOptions, options...) { diff --git a/option.go b/option.go index 8ea40cfa..1c4c47e7 100644 --- a/option.go +++ b/option.go @@ -302,9 +302,9 @@ func OptionAddError(code int, description string, errorType ...any) func(*BaseRo } if len(errorType) > 0 { - responseSchema = SchemaTagFromType(r.mainRouter.OpenAPI, errorType[0]) + responseSchema = SchemaTagFromType(r.OpenAPI, errorType[0]) } else { - responseSchema = SchemaTagFromType(r.mainRouter.OpenAPI, HTTPError{}) + responseSchema = SchemaTagFromType(r.OpenAPI, HTTPError{}) } content := openapi3.NewContentWithSchemaRef(&responseSchema.SchemaRef, []string{"application/json"}) @@ -374,14 +374,14 @@ func OptionDefaultStatusCode(defaultStatusCode int) func(*BaseRoute) { // }) func OptionSecurity(securityRequirements ...openapi3.SecurityRequirement) func(*BaseRoute) { return func(r *BaseRoute) { - if r.mainRouter.OpenAPI.Description().Components == nil { + if r.OpenAPI.Description().Components == nil { panic("zero security schemes have been registered with the server") } // Validate the security scheme exists in components for _, req := range securityRequirements { for schemeName := range req { - if _, exists := r.mainRouter.OpenAPI.Description().Components.SecuritySchemes[schemeName]; !exists { + if _, exists := r.OpenAPI.Description().Components.SecuritySchemes[schemeName]; !exists { panic(fmt.Sprintf("security scheme '%s' not defined in components", schemeName)) } } diff --git a/server.go b/server.go index 8d2cf99b..12b60fab 100644 --- a/server.go +++ b/server.go @@ -56,10 +56,9 @@ type Server struct { disableStartupMessages bool disableAutoGroupTags bool - mainRouter *Server // Ref to the main router (used for groups) - basePath string // Base path of the group + basePath string // Base path of the group - // OpenAPI handles the OpenAPI spec generation. + // Points to the server OpenAPI struct. OpenAPI *OpenAPI Security Security From 8964e3f435d392654470b00b0eebcf1db1ab722c Mon Sep 17 00:00:00 2001 From: EwenQuim Date: Fri, 13 Dec 2024 21:42:08 +0100 Subject: [PATCH 061/138] Exports the default OpenAPI HTML template as a function so it can be customized to any framework-specific handler --- mux.go | 10 +++++----- openapi_handler.go | 10 +++++++--- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/mux.go b/mux.go index 2cbc51b7..d9287041 100644 --- a/mux.go +++ b/mux.go @@ -145,7 +145,7 @@ func Handle(s *Server, path string, controller http.Handler, options ...func(*Ba return Register(s, Route[any, any]{ BaseRoute: BaseRoute{ Path: path, - FullName: FuncName(controller), + FullName: funcName(controller), }, }, controller) } @@ -179,7 +179,7 @@ func registerFuegoController[T, B any, Contexted ctx[B]](s *Server, method, path Method: method, Path: path, Params: make(map[string]OpenAPIParam), - FullName: FuncName(controller), + FullName: funcName(controller), Operation: openapi3.NewOperation(), OpenAPI: s.OpenAPI, } @@ -199,7 +199,7 @@ func registerStdController(s *Server, method, path string, controller func(http. route := BaseRoute{ Method: method, Path: path, - FullName: FuncName(controller), + FullName: funcName(controller), Operation: openapi3.NewOperation(), OpenAPI: s.OpenAPI, } @@ -218,8 +218,8 @@ func withMiddlewares(controller http.Handler, middlewares ...func(http.Handler) return controller } -// FuncName returns the name of a function and the name with package path -func FuncName(f interface{}) string { +// funcName returns the name of a function and the name with package path +func funcName(f interface{}) string { return strings.TrimSuffix(runtime.FuncForPC(reflect.ValueOf(f).Pointer()).Name(), "-fm") } diff --git a/openapi_handler.go b/openapi_handler.go index 015b257c..4e973a32 100644 --- a/openapi_handler.go +++ b/openapi_handler.go @@ -7,7 +7,12 @@ import ( func DefaultOpenAPIHandler(specURL string) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "text/html; charset=utf-8") - _, _ = w.Write([]byte(` + _, _ = w.Write([]byte(DefaultOpenAPIHTML(specURL))) + }) +} + +func DefaultOpenAPIHTML(specURL string) string { + return ` @@ -27,6 +32,5 @@ func DefaultOpenAPIHandler(specURL string) http.Handler { tryItCredentialsPolicy="same-origin" /> -`)) - }) +` } From 5a337b24c48987bb513ef96f9ff51ee7116c5cf1 Mon Sep 17 00:00:00 2001 From: EwenQuim Date: Fri, 13 Dec 2024 21:49:23 +0100 Subject: [PATCH 062/138] Re-exports FuncName as public function --- mux.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/mux.go b/mux.go index d9287041..2cbc51b7 100644 --- a/mux.go +++ b/mux.go @@ -145,7 +145,7 @@ func Handle(s *Server, path string, controller http.Handler, options ...func(*Ba return Register(s, Route[any, any]{ BaseRoute: BaseRoute{ Path: path, - FullName: funcName(controller), + FullName: FuncName(controller), }, }, controller) } @@ -179,7 +179,7 @@ func registerFuegoController[T, B any, Contexted ctx[B]](s *Server, method, path Method: method, Path: path, Params: make(map[string]OpenAPIParam), - FullName: funcName(controller), + FullName: FuncName(controller), Operation: openapi3.NewOperation(), OpenAPI: s.OpenAPI, } @@ -199,7 +199,7 @@ func registerStdController(s *Server, method, path string, controller func(http. route := BaseRoute{ Method: method, Path: path, - FullName: funcName(controller), + FullName: FuncName(controller), Operation: openapi3.NewOperation(), OpenAPI: s.OpenAPI, } @@ -218,8 +218,8 @@ func withMiddlewares(controller http.Handler, middlewares ...func(http.Handler) return controller } -// funcName returns the name of a function and the name with package path -func funcName(f interface{}) string { +// FuncName returns the name of a function and the name with package path +func FuncName(f interface{}) string { return strings.TrimSuffix(runtime.FuncForPC(reflect.ValueOf(f).Pointer()).Name(), "-fm") } From d5577509bd42b48ed5c06666f75c6c62f6f8d721 Mon Sep 17 00:00:00 2001 From: dylanhitt Date: Fri, 13 Dec 2024 14:42:27 -0500 Subject: [PATCH 063/138] refactor: set openapi server url as close to startup as possible --- openapi.go | 5 +++++ server.go | 5 ----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/openapi.go b/openapi.go index e08ae26e..6db8e9e9 100644 --- a/openapi.go +++ b/openapi.go @@ -95,6 +95,11 @@ func declareAllTagsFromOperations(s *Server) { // Also serves a Swagger UI. // To modify its behavior, use the [WithOpenAPIConfig] option. func (s *Server) OutputOpenAPISpec() openapi3.T { + s.OpenAPI.Description().Servers = append(s.OpenAPI.Description().Servers, &openapi3.Server{ + URL: s.proto() + "//" + s.Addr, + Description: "local server", + }) + declareAllTagsFromOperations(s) // Validate diff --git a/server.go b/server.go index 12b60fab..be12884d 100644 --- a/server.go +++ b/server.go @@ -135,11 +135,6 @@ func NewServer(options ...func(*Server)) *Server { option(s) } - s.OpenAPI.Description().Servers = append(s.OpenAPI.Description().Servers, &openapi3.Server{ - URL: "http://" + s.Addr, - Description: "local server", - }) - s.startTime = time.Now() if s.autoAuth.Enabled { From 42919296c61d1d222a611cc7907e34e15a142fa7 Mon Sep 17 00:00:00 2001 From: dylanhitt Date: Fri, 13 Dec 2024 15:57:04 -0500 Subject: [PATCH 064/138] chore: add back missing colon when creating URL --- openapi.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openapi.go b/openapi.go index 6db8e9e9..e9a90ac7 100644 --- a/openapi.go +++ b/openapi.go @@ -96,7 +96,7 @@ func declareAllTagsFromOperations(s *Server) { // To modify its behavior, use the [WithOpenAPIConfig] option. func (s *Server) OutputOpenAPISpec() openapi3.T { s.OpenAPI.Description().Servers = append(s.OpenAPI.Description().Servers, &openapi3.Server{ - URL: s.proto() + "//" + s.Addr, + URL: s.proto() + "://" + s.Addr, Description: "local server", }) From c35b5a0adbd8011e27964526f3ce2d849b3f0dd6 Mon Sep 17 00:00:00 2001 From: dylanhitt Date: Fri, 13 Dec 2024 17:35:07 -0500 Subject: [PATCH 065/138] refactor: add helper func for generation Server url --- openapi.go | 6 +++--- serve.go | 6 +++++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/openapi.go b/openapi.go index e9a90ac7..83cbd280 100644 --- a/openapi.go +++ b/openapi.go @@ -96,7 +96,7 @@ func declareAllTagsFromOperations(s *Server) { // To modify its behavior, use the [WithOpenAPIConfig] option. func (s *Server) OutputOpenAPISpec() openapi3.T { s.OpenAPI.Description().Servers = append(s.OpenAPI.Description().Servers, &openapi3.Server{ - URL: s.proto() + "://" + s.Addr, + URL: s.url(), Description: "local server", }) @@ -164,7 +164,7 @@ func (s *Server) registerOpenAPIRoutes(jsonSpec []byte) { w.Header().Set("Content-Type", "application/json") _, _ = w.Write(jsonSpec) }) - s.printOpenAPIMessage(fmt.Sprintf("JSON spec: %s://%s%s", s.proto(), s.Server.Addr, s.OpenAPIConfig.JsonUrl)) + s.printOpenAPIMessage(fmt.Sprintf("JSON spec: %s%s", s.url(), s.OpenAPIConfig.JsonUrl)) if !s.OpenAPIConfig.DisableSwaggerUI { Register(s, Route[any, any]{ @@ -173,7 +173,7 @@ func (s *Server) registerOpenAPIRoutes(jsonSpec []byte) { Path: s.OpenAPIConfig.SwaggerUrl + "/", }, }, s.OpenAPIConfig.UIHandler(s.OpenAPIConfig.JsonUrl)) - s.printOpenAPIMessage(fmt.Sprintf("OpenAPI UI: %s://%s%s/index.html", s.proto(), s.Server.Addr, s.OpenAPIConfig.SwaggerUrl)) + s.printOpenAPIMessage(fmt.Sprintf("OpenAPI UI: %s%s/index.html", s.url(), s.OpenAPIConfig.SwaggerUrl)) } } diff --git a/serve.go b/serve.go index b410b284..4354ddfe 100644 --- a/serve.go +++ b/serve.go @@ -43,7 +43,7 @@ func (s *Server) printStartupMessage() { if !s.disableStartupMessages { elapsed := time.Since(s.startTime) slog.Debug("Server started in "+elapsed.String(), "info", "time between since server creation (fuego.NewServer) and server startup (fuego.Run). Depending on your implementation, there might be things that do not depend on fuego slowing start time") - slog.Info("Server running ✅ on "+s.proto()+"://"+s.Server.Addr, "started in", elapsed.String()) + slog.Info("Server running ✅ on "+s.url(), "started in", elapsed.String()) } } @@ -54,6 +54,10 @@ func (s *Server) proto() string { return "http" } +func (s *Server) url() string { + return s.proto() + "://" + s.Server.Addr +} + // initializes any Context type with the base ContextNoBody context. // // var ctx ContextWithBody[any] // does not work because it will create a ContextWithBody[any] with a nil value From 72d6a0bdeccf7d11385b1770c3d1a7251e5c017a Mon Sep 17 00:00:00 2001 From: dylanhitt Date: Fri, 13 Dec 2024 16:52:41 -0500 Subject: [PATCH 066/138] feat: AddResponse to allow for setting or overriding of any routes status code --- option.go | 37 ++++++++++++++++++++++++++ option/option.go | 6 +++++ option_test.go | 69 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 112 insertions(+) diff --git a/option.go b/option.go index 1c4c47e7..1d8b94f5 100644 --- a/option.go +++ b/option.go @@ -319,6 +319,43 @@ func OptionAddError(code int, description string, errorType ...any) func(*BaseRo } } +// Response represents a fuego.Response that can be used +// when setting custom response types on routes +type Response struct { + // content-type of the response i.e application/json + ContentTypes []string + // user provided type + Type any +} + +// AddResponse adds a response to a route by status code +// It replaces any existing response set by any status code, this will override 200. +// Required: Response.Type must be set +// Optional: Response.ContentTypes will default to `application/json`, `application/xml` if no set +func OptionAddResponse(code int, description string, response Response) func(*BaseRoute) { + var responseSchema SchemaTag + return func(r *BaseRoute) { + if response.Type == nil { + panic("Type in Response cannot be nil") + } + + responseSchema = SchemaTagFromType(r.OpenAPI, response.Type) + if len(response.ContentTypes) == 0 { + response.ContentTypes = []string{"application/json", "application/xml"} + } + + content := openapi3.NewContentWithSchemaRef(&responseSchema.SchemaRef, response.ContentTypes) + response := openapi3.NewResponse(). + WithDescription(description). + WithContent(content) + + if r.Operation.Responses == nil { + r.Operation.Responses = openapi3.NewResponses() + } + r.Operation.Responses.Set(strconv.Itoa(code), &openapi3.ResponseRef{Value: response}) + } +} + // RequestContentType sets the accepted content types for the route. // By default, the accepted content types is */*. // This will override any options set at the server level. diff --git a/option/option.go b/option/option.go index 050bcb06..c9db4d02 100644 --- a/option/option.go +++ b/option/option.go @@ -148,6 +148,12 @@ var Deprecated = fuego.OptionDeprecated // AddError adds an error to the route. var AddError = fuego.OptionAddError +// AddResponse adds a response to a route by status code +// It replaces any existing response set by any status code, this will override 200. +// Required: fuego.Response.Type must be set +// Optional: fuego.Response.ContentTypes will default to `application/json`, `application/xml` if no set +var AddResponse = fuego.OptionAddResponse + // RequestContentType sets the accepted content types for the route. // By default, the accepted content types is */*. // This will override any options set at the server level. diff --git a/option_test.go b/option_test.go index 61196994..6f93670f 100644 --- a/option_test.go +++ b/option_test.go @@ -412,6 +412,75 @@ func TestAddError(t *testing.T) { }) } +func TestAddResponse(t *testing.T) { + t.Run("base", func(t *testing.T) { + s := fuego.NewServer() + route := fuego.Get(s, "/test", helloWorld, fuego.OptionAddResponse( + 409, + "Conflict: Pet with the same name already exists", + fuego.Response{ + ContentTypes: []string{"application/json"}, + Type: fuego.HTTPError{}, + }, + )) + require.Equal(t, 5, route.Operation.Responses.Len()) // 200, 400, 409, 500, default + resp := route.Operation.Responses.Value("409") + require.NotNil(t, resp) + require.NotNil(t, resp.Value.Content.Get("application/json")) + require.Nil(t, resp.Value.Content.Get("application/xml")) + require.Equal(t, "Conflict: Pet with the same name already exists", *route.Operation.Responses.Value("409").Value.Description) + }) + + t.Run("no content types provided", func(t *testing.T) { + s := fuego.NewServer() + route := fuego.Get(s, "/test", helloWorld, fuego.OptionAddResponse( + 409, + "Conflict: Pet with the same name already exists", + fuego.Response{ + Type: fuego.HTTPError{}, + }, + )) + require.Equal(t, 5, route.Operation.Responses.Len()) // 200, 400, 409, 500, default + resp := route.Operation.Responses.Value("409") + require.NotNil(t, resp) + require.NotNil(t, resp.Value.Content.Get("application/json")) + require.NotNil(t, resp.Value.Content.Get("application/xml")) + require.Equal(t, "Conflict: Pet with the same name already exists", *route.Operation.Responses.Value("409").Value.Description) + }) + + t.Run("should override 200", func(t *testing.T) { + s := fuego.NewServer() + route := fuego.Get(s, "/test", helloWorld, fuego.OptionAddResponse( + 200, + "set 200", + fuego.Response{ + Type: fuego.HTTPError{}, + ContentTypes: []string{"application/x-yaml"}, + }, + )) + require.Equal(t, 4, route.Operation.Responses.Len()) // 200, 400, 500, default + resp := route.Operation.Responses.Value("200") + require.NotNil(t, resp) + require.Nil(t, resp.Value.Content.Get("application/json")) + require.Nil(t, resp.Value.Content.Get("application/xml")) + require.NotNil(t, resp.Value.Content.Get("application/x-yaml")) + require.Equal(t, "#/components/schemas/HTTPError", resp.Value.Content.Get("application/x-yaml").Schema.Ref) + require.Equal(t, "set 200", *route.Operation.Responses.Value("200").Value.Description) + }) + + t.Run("should be fatal", func(t *testing.T) { + s := fuego.NewServer() + + require.Panics(t, func() { + fuego.Get(s, "/test", helloWorld, fuego.OptionAddResponse( + 409, + "Conflict: Pet with the same name already exists", + fuego.Response{}, + )) + }) + }) +} + func TestHide(t *testing.T) { s := fuego.NewServer() From 7b30c69dba62542c2075ce448b9e2861fa1c64df Mon Sep 17 00:00:00 2001 From: dylanhitt Date: Fri, 13 Dec 2024 16:59:14 -0500 Subject: [PATCH 067/138] deprecate: deprecate AddError in favor of AddResponse --- option.go | 1 + option/option.go | 1 + 2 files changed, 2 insertions(+) diff --git a/option.go b/option.go index 1d8b94f5..0acaec64 100644 --- a/option.go +++ b/option.go @@ -294,6 +294,7 @@ func OptionDeprecated() func(*BaseRoute) { // AddError adds an error to the route. // It replaces any existing error previously set with the same code. // Required: should only supply one type to `errorType` +// Deprecated: Use `OptionAddResponse` instead func OptionAddError(code int, description string, errorType ...any) func(*BaseRoute) { var responseSchema SchemaTag return func(r *BaseRoute) { diff --git a/option/option.go b/option/option.go index c9db4d02..17dd30f0 100644 --- a/option/option.go +++ b/option/option.go @@ -146,6 +146,7 @@ var OperationID = fuego.OptionOperationID var Deprecated = fuego.OptionDeprecated // AddError adds an error to the route. +// Deprecated: Use `AddResponse` instead. var AddError = fuego.OptionAddError // AddResponse adds a response to a route by status code From c93a2de4e6c3f9b4b83db54052d7cc84314cf759 Mon Sep 17 00:00:00 2001 From: dylanhitt Date: Fri, 13 Dec 2024 17:15:14 -0500 Subject: [PATCH 068/138] chore: add golden example fo AddResponse --- examples/petstore/controllers/pets.go | 26 ++++++- examples/petstore/controllers/pets_test.go | 13 ++++ .../lib/testdata/doc/openapi.golden.json | 67 +++++++++++++++++++ 3 files changed, 105 insertions(+), 1 deletion(-) diff --git a/examples/petstore/controllers/pets.go b/examples/petstore/controllers/pets.go index e3bfecab..72a2d0d2 100644 --- a/examples/petstore/controllers/pets.go +++ b/examples/petstore/controllers/pets.go @@ -1,7 +1,9 @@ package controller import ( + "encoding/json" "log/slog" + "net/http" "github.com/go-fuego/fuego" "github.com/go-fuego/fuego/examples/petstore/models" @@ -48,7 +50,7 @@ func (rs PetsResources) Routes(s *fuego.Server) { fuego.Get(petsGroup, "/by-age", rs.getAllPetsByAge, option.Description("Returns an array of pets grouped by age")) fuego.Post(petsGroup, "/", rs.postPets, option.DefaultStatusCode(201), - option.AddError(409, "Conflict: Pet with the same name already exists", PetsError{}), + option.AddResponse(409, "Conflict: Pet with the same name already exists", fuego.Response{Type: PetsError{}}), ) fuego.Get(petsGroup, "/{id}", rs.getPets, @@ -61,6 +63,28 @@ func (rs PetsResources) Routes(s *fuego.Server) { option.RequestContentType("application/json"), ) fuego.Delete(petsGroup, "/{id}", rs.deletePets) + + stdPetsGroup := fuego.Group(petsGroup, "/std") + + fuego.GetStd(stdPetsGroup, "/all", func(w http.ResponseWriter, r *http.Request) { + pets, err := rs.PetsService.GetAllPets() + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + if err := json.NewEncoder(w).Encode(pets); err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + } + + }, option.AddResponse(http.StatusOK, "all the pets", + fuego.Response{ + Type: []models.Pets{}, + ContentTypes: []string{"application/json"}, + }, + )) + } func (rs PetsResources) getAllPets(c fuego.ContextNoBody) ([]models.Pets, error) { diff --git a/examples/petstore/controllers/pets_test.go b/examples/petstore/controllers/pets_test.go index d70478d3..9ce05db6 100644 --- a/examples/petstore/controllers/pets_test.go +++ b/examples/petstore/controllers/pets_test.go @@ -24,6 +24,19 @@ func TestGetAllPets(t *testing.T) { }) } +func TestGetAllPetsStd(t *testing.T) { + t.Run("can get all pets std", func(t *testing.T) { + s := lib.NewPetStoreServer() + + w := httptest.NewRecorder() + r := httptest.NewRequest("GET", "/pets/std/all", nil) + + s.Mux.ServeHTTP(w, r) + + require.Equal(t, http.StatusOK, w.Code) + }) +} + func TestFilterPets(t *testing.T) { t.Run("can filter pets", func(t *testing.T) { s := lib.NewPetStoreServer() diff --git a/examples/petstore/lib/testdata/doc/openapi.golden.json b/examples/petstore/lib/testdata/doc/openapi.golden.json index 16eaede4..beb1b056 100644 --- a/examples/petstore/lib/testdata/doc/openapi.golden.json +++ b/examples/petstore/lib/testdata/doc/openapi.golden.json @@ -364,6 +364,11 @@ "schema": { "$ref": "#/components/schemas/PetsError" } + }, + "application/xml": { + "schema": { + "$ref": "#/components/schemas/PetsError" + } } }, "description": "Conflict: Pet with the same name already exists" @@ -673,6 +678,65 @@ ] } }, + "/pets/std/all": { + "get": { + "description": "controller: `github.com/go-fuego/fuego/examples/petstore/controllers.PetsResources.Routes.func1`\n\n---\n\n", + "operationId": "GET_/pets/std/all", + "parameters": [ + { + "description": "header description", + "in": "header", + "name": "X-Header", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/Pets" + }, + "type": "array" + } + } + }, + "description": "all the pets" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPError" + } + } + }, + "description": "Bad Request _(validation or deserialization error)_" + }, + "500": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPError" + } + } + }, + "description": "Internal Server Error _(panics)_" + }, + "default": { + "description": "" + } + }, + "summary": "func1", + "tags": [ + "pets", + "std" + ] + } + }, "/pets/{id}": { "delete": { "description": "controller: `github.com/go-fuego/fuego/examples/petstore/controllers.PetsResources.deletePets`\n\n---\n\n", @@ -1008,6 +1072,9 @@ { "name": "pets" }, + { + "name": "std" + }, { "name": "my-tag" } From a55173e887de45bc473800db2af4518fa3ef393f Mon Sep 17 00:00:00 2001 From: dylanhitt Date: Fri, 13 Dec 2024 17:42:31 -0500 Subject: [PATCH 069/138] chore: update vaccum check pathing --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 1c245d57..492ee8f3 100644 --- a/Makefile +++ b/Makefile @@ -45,7 +45,7 @@ golden-update: # Check OpenAPI spec generated for the Petstore example. Uses https://github.com/daveshanley/vacuum openapi-check: - vacuum lint -d examples/petstore/testdata/doc/openapi.json + vacuum lint -d examples/petstore/lib/testdata/doc/openapi.json # Examples example: From 6ba326600729cdb5bfae8ea618deba57b8838243 Mon Sep 17 00:00:00 2001 From: dylanhitt Date: Fri, 13 Dec 2024 18:20:18 -0500 Subject: [PATCH 070/138] typo --- option.go | 2 +- option/option.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/option.go b/option.go index 0acaec64..e7e647a3 100644 --- a/option.go +++ b/option.go @@ -332,7 +332,7 @@ type Response struct { // AddResponse adds a response to a route by status code // It replaces any existing response set by any status code, this will override 200. // Required: Response.Type must be set -// Optional: Response.ContentTypes will default to `application/json`, `application/xml` if no set +// Optional: Response.ContentTypes will default to `application/json` and `application/xml` if not set func OptionAddResponse(code int, description string, response Response) func(*BaseRoute) { var responseSchema SchemaTag return func(r *BaseRoute) { diff --git a/option/option.go b/option/option.go index 17dd30f0..53199ddc 100644 --- a/option/option.go +++ b/option/option.go @@ -152,7 +152,7 @@ var AddError = fuego.OptionAddError // AddResponse adds a response to a route by status code // It replaces any existing response set by any status code, this will override 200. // Required: fuego.Response.Type must be set -// Optional: fuego.Response.ContentTypes will default to `application/json`, `application/xml` if no set +// Optional: fuego.Response.ContentTypes will default to `application/json` and `application/xml` if not set var AddResponse = fuego.OptionAddResponse // RequestContentType sets the accepted content types for the route. From b1d96464218d8c1def493bbeebf412dcbbd70c7d Mon Sep 17 00:00:00 2001 From: EwenQuim Date: Sat, 14 Dec 2024 01:52:08 +0100 Subject: [PATCH 071/138] Updated docusaurus dependencies --- documentation/package-lock.json | 13792 +++++++++++++++++------------- documentation/package.json | 18 +- 2 files changed, 8034 insertions(+), 5776 deletions(-) diff --git a/documentation/package-lock.json b/documentation/package-lock.json index b065d723..efd0dcdf 100644 --- a/documentation/package-lock.json +++ b/documentation/package-lock.json @@ -9,18 +9,18 @@ "version": "0.0.0", "dependencies": { "@docusaurus/core": "^3.1.1", - "@docusaurus/preset-classic": "^3.1.1", - "@docusaurus/theme-mermaid": "^3.1.1", - "@mdx-js/react": "^3.0.0", - "clsx": "^2.0.0", - "docusaurus-lunr-search": "^3.3.2", - "prism-react-renderer": "^2.3.0", - "react": "^18.0.0", - "react-dom": "^18.0.0" + "@docusaurus/preset-classic": "^3.6.3", + "@docusaurus/theme-mermaid": "^3.6.3", + "@mdx-js/react": "^3.1.0", + "clsx": "^2.1.1", + "docusaurus-lunr-search": "^3.5.0", + "prism-react-renderer": "^2.4.1", + "react": "^18.3.1", + "react-dom": "^18.3.1" }, "devDependencies": { "@docusaurus/module-type-aliases": "^3.1.1", - "@docusaurus/tsconfig": "^3.1.1", + "@docusaurus/tsconfig": "^3.6.3", "@docusaurus/types": "^3.1.1", "typescript": "~5.2.2" }, @@ -29,31 +29,31 @@ } }, "node_modules/@algolia/autocomplete-core": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.9.3.tgz", - "integrity": "sha512-009HdfugtGCdC4JdXUbVJClA0q0zh24yyePn+KUGk3rP7j8FEe/m5Yo/z65gn6nP/cM39PxpzqKrL7A6fP6PPw==", + "version": "1.17.7", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.17.7.tgz", + "integrity": "sha512-BjiPOW6ks90UKl7TwMv7oNQMnzU+t/wk9mgIDi6b1tXpUek7MW0lbNOUHpvam9pe3lVCf4xPFT+lK7s+e+fs7Q==", "dependencies": { - "@algolia/autocomplete-plugin-algolia-insights": "1.9.3", - "@algolia/autocomplete-shared": "1.9.3" + "@algolia/autocomplete-plugin-algolia-insights": "1.17.7", + "@algolia/autocomplete-shared": "1.17.7" } }, "node_modules/@algolia/autocomplete-plugin-algolia-insights": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.9.3.tgz", - "integrity": "sha512-a/yTUkcO/Vyy+JffmAnTWbr4/90cLzw+CC3bRbhnULr/EM0fGNvM13oQQ14f2moLMcVDyAx/leczLlAOovhSZg==", + "version": "1.17.7", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.17.7.tgz", + "integrity": "sha512-Jca5Ude6yUOuyzjnz57og7Et3aXjbwCSDf/8onLHSQgw1qW3ALl9mrMWaXb5FmPVkV3EtkD2F/+NkT6VHyPu9A==", "dependencies": { - "@algolia/autocomplete-shared": "1.9.3" + "@algolia/autocomplete-shared": "1.17.7" }, "peerDependencies": { "search-insights": ">= 1 < 3" } }, "node_modules/@algolia/autocomplete-preset-algolia": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.9.3.tgz", - "integrity": "sha512-d4qlt6YmrLMYy95n5TB52wtNDr6EgAIPH81dvvvW8UmuWRgxEtY0NJiPwl/h95JtG2vmRM804M0DSwMCNZlzRA==", + "version": "1.17.7", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.17.7.tgz", + "integrity": "sha512-ggOQ950+nwbWROq2MOCIL71RE0DdQZsceqrg32UqnhDz8FlO9rL8ONHNsI2R1MH0tkgVIDKI/D0sMiUchsFdWA==", "dependencies": { - "@algolia/autocomplete-shared": "1.9.3" + "@algolia/autocomplete-shared": "1.17.7" }, "peerDependencies": { "@algolia/client-search": ">= 4.9.1 < 6", @@ -61,83 +61,175 @@ } }, "node_modules/@algolia/autocomplete-shared": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.9.3.tgz", - "integrity": "sha512-Wnm9E4Ye6Rl6sTTqjoymD+l8DjSTHsHboVRYrKgEt8Q7UHm9nYbqhN/i0fhUYA3OAEH7WA8x3jfpnmJm3rKvaQ==", + "version": "1.17.7", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.17.7.tgz", + "integrity": "sha512-o/1Vurr42U/qskRSuhBH+VKxMvkkUVTLU6WZQr+L5lGZZLYWyhdzWjW0iGXY7EkwRTjBqvN2EsR81yCTGV/kmg==", "peerDependencies": { "@algolia/client-search": ">= 4.9.1 < 6", "algoliasearch": ">= 4.9.1 < 6" } }, "node_modules/@algolia/cache-browser-local-storage": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.22.1.tgz", - "integrity": "sha512-Sw6IAmOCvvP6QNgY9j+Hv09mvkvEIDKjYW8ow0UDDAxSXy664RBNQk3i/0nt7gvceOJ6jGmOTimaZoY1THmU7g==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.24.0.tgz", + "integrity": "sha512-t63W9BnoXVrGy9iYHBgObNXqYXM3tYXCjDSHeNwnsc324r4o5UiVKUiAB4THQ5z9U5hTj6qUvwg/Ez43ZD85ww==", "dependencies": { - "@algolia/cache-common": "4.22.1" + "@algolia/cache-common": "4.24.0" } }, "node_modules/@algolia/cache-common": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/@algolia/cache-common/-/cache-common-4.22.1.tgz", - "integrity": "sha512-TJMBKqZNKYB9TptRRjSUtevJeQVXRmg6rk9qgFKWvOy8jhCPdyNZV1nB3SKGufzvTVbomAukFR8guu/8NRKBTA==" + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/cache-common/-/cache-common-4.24.0.tgz", + "integrity": "sha512-emi+v+DmVLpMGhp0V9q9h5CdkURsNmFC+cOS6uK9ndeJm9J4TiqSvPYVu+THUP8P/S08rxf5x2P+p3CfID0Y4g==" }, "node_modules/@algolia/cache-in-memory": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/@algolia/cache-in-memory/-/cache-in-memory-4.22.1.tgz", - "integrity": "sha512-ve+6Ac2LhwpufuWavM/aHjLoNz/Z/sYSgNIXsinGofWOysPilQZPUetqLj8vbvi+DHZZaYSEP9H5SRVXnpsNNw==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/cache-in-memory/-/cache-in-memory-4.24.0.tgz", + "integrity": "sha512-gDrt2so19jW26jY3/MkFg5mEypFIPbPoXsQGQWAi6TrCPsNOSEYepBMPlucqWigsmEy/prp5ug2jy/N3PVG/8w==", + "dependencies": { + "@algolia/cache-common": "4.24.0" + } + }, + "node_modules/@algolia/client-abtesting": { + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/@algolia/client-abtesting/-/client-abtesting-5.17.1.tgz", + "integrity": "sha512-Os/xkQbDp5A5RdGYq1yS3fF69GoBJH5FIfrkVh+fXxCSe714i1Xdl9XoXhS4xG76DGKm6EFMlUqP024qjps8cg==", "dependencies": { - "@algolia/cache-common": "4.22.1" + "@algolia/client-common": "5.17.1", + "@algolia/requester-browser-xhr": "5.17.1", + "@algolia/requester-fetch": "5.17.1", + "@algolia/requester-node-http": "5.17.1" + }, + "engines": { + "node": ">= 14.0.0" } }, "node_modules/@algolia/client-account": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/@algolia/client-account/-/client-account-4.22.1.tgz", - "integrity": "sha512-k8m+oegM2zlns/TwZyi4YgCtyToackkOpE+xCaKCYfBfDtdGOaVZCM5YvGPtK+HGaJMIN/DoTL8asbM3NzHonw==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-account/-/client-account-4.24.0.tgz", + "integrity": "sha512-adcvyJ3KjPZFDybxlqnf+5KgxJtBjwTPTeyG2aOyoJvx0Y8dUQAEOEVOJ/GBxX0WWNbmaSrhDURMhc+QeevDsA==", + "dependencies": { + "@algolia/client-common": "4.24.0", + "@algolia/client-search": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/@algolia/client-account/node_modules/@algolia/client-common": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.24.0.tgz", + "integrity": "sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA==", + "dependencies": { + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/@algolia/client-account/node_modules/@algolia/client-search": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.24.0.tgz", + "integrity": "sha512-uRW6EpNapmLAD0mW47OXqTP8eiIx5F6qN9/x/7HHO6owL3N1IXqydGwW5nhDFBrV+ldouro2W1VX3XlcUXEFCA==", "dependencies": { - "@algolia/client-common": "4.22.1", - "@algolia/client-search": "4.22.1", - "@algolia/transporter": "4.22.1" + "@algolia/client-common": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" } }, "node_modules/@algolia/client-analytics": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-4.22.1.tgz", - "integrity": "sha512-1ssi9pyxyQNN4a7Ji9R50nSdISIumMFDwKNuwZipB6TkauJ8J7ha/uO60sPJFqQyqvvI+px7RSNRQT3Zrvzieg==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-4.24.0.tgz", + "integrity": "sha512-y8jOZt1OjwWU4N2qr8G4AxXAzaa8DBvyHTWlHzX/7Me1LX8OayfgHexqrsL4vSBcoMmVw2XnVW9MhL+Y2ZDJXg==", + "dependencies": { + "@algolia/client-common": "4.24.0", + "@algolia/client-search": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/@algolia/client-analytics/node_modules/@algolia/client-common": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.24.0.tgz", + "integrity": "sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA==", "dependencies": { - "@algolia/client-common": "4.22.1", - "@algolia/client-search": "4.22.1", - "@algolia/requester-common": "4.22.1", - "@algolia/transporter": "4.22.1" + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/@algolia/client-analytics/node_modules/@algolia/client-search": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.24.0.tgz", + "integrity": "sha512-uRW6EpNapmLAD0mW47OXqTP8eiIx5F6qN9/x/7HHO6owL3N1IXqydGwW5nhDFBrV+ldouro2W1VX3XlcUXEFCA==", + "dependencies": { + "@algolia/client-common": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" } }, "node_modules/@algolia/client-common": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.22.1.tgz", - "integrity": "sha512-IvaL5v9mZtm4k4QHbBGDmU3wa/mKokmqNBqPj0K7lcR8ZDKzUorhcGp/u8PkPC/e0zoHSTvRh7TRkGX3Lm7iOQ==", + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.17.1.tgz", + "integrity": "sha512-5rb5+yPIie6912riAypTSyzbE23a7UM1UpESvD8GEPI4CcWQvA9DBlkRNx9qbq/nJ5pvv8VjZjUxJj7rFkzEAA==", + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-insights": { + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/@algolia/client-insights/-/client-insights-5.17.1.tgz", + "integrity": "sha512-nb/tfwBMn209TzFv1DDTprBKt/wl5btHVKoAww9fdEVdoKK02R2KAqxe5tuXLdEzAsS+LevRyOM/YjXuLmPtjQ==", "dependencies": { - "@algolia/requester-common": "4.22.1", - "@algolia/transporter": "4.22.1" + "@algolia/client-common": "5.17.1", + "@algolia/requester-browser-xhr": "5.17.1", + "@algolia/requester-fetch": "5.17.1", + "@algolia/requester-node-http": "5.17.1" + }, + "engines": { + "node": ">= 14.0.0" } }, "node_modules/@algolia/client-personalization": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-4.22.1.tgz", - "integrity": "sha512-sl+/klQJ93+4yaqZ7ezOttMQ/nczly/3GmgZXJ1xmoewP5jmdP/X/nV5U7EHHH3hCUEHeN7X1nsIhGPVt9E1cQ==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-4.24.0.tgz", + "integrity": "sha512-l5FRFm/yngztweU0HdUzz1rC4yoWCFo3IF+dVIVTfEPg906eZg5BOd1k0K6rZx5JzyyoP4LdmOikfkfGsKVE9w==", + "dependencies": { + "@algolia/client-common": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/@algolia/client-personalization/node_modules/@algolia/client-common": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.24.0.tgz", + "integrity": "sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA==", + "dependencies": { + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/@algolia/client-query-suggestions": { + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/@algolia/client-query-suggestions/-/client-query-suggestions-5.17.1.tgz", + "integrity": "sha512-RBIFIv1QE3IlAikJKWTOpd6pwE4d2dY6t02iXH7r/SLXWn0HzJtsAPPeFg/OKkFvWAXt0H7In2/Mp7a1/Dy2pw==", "dependencies": { - "@algolia/client-common": "4.22.1", - "@algolia/requester-common": "4.22.1", - "@algolia/transporter": "4.22.1" + "@algolia/client-common": "5.17.1", + "@algolia/requester-browser-xhr": "5.17.1", + "@algolia/requester-fetch": "5.17.1", + "@algolia/requester-node-http": "5.17.1" + }, + "engines": { + "node": ">= 14.0.0" } }, "node_modules/@algolia/client-search": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.22.1.tgz", - "integrity": "sha512-yb05NA4tNaOgx3+rOxAmFztgMTtGBi97X7PC3jyNeGiwkAjOZc2QrdZBYyIdcDLoI09N0gjtpClcackoTN0gPA==", + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.17.1.tgz", + "integrity": "sha512-bd5JBUOP71kPsxwDcvOxqtqXXVo/706NFifZ/O5Rx5GB8ZNVAhg4l7aGoT6jBvEfgmrp2fqPbkdIZ6JnuOpGcw==", "dependencies": { - "@algolia/client-common": "4.22.1", - "@algolia/requester-common": "4.22.1", - "@algolia/transporter": "4.22.1" + "@algolia/client-common": "5.17.1", + "@algolia/requester-browser-xhr": "5.17.1", + "@algolia/requester-fetch": "5.17.1", + "@algolia/requester-node-http": "5.17.1" + }, + "engines": { + "node": ">= 14.0.0" } }, "node_modules/@algolia/events": { @@ -145,161 +237,216 @@ "resolved": "https://registry.npmjs.org/@algolia/events/-/events-4.0.1.tgz", "integrity": "sha512-FQzvOCgoFXAbf5Y6mYozw2aj5KCJoA3m4heImceldzPSMbdyS4atVjJzXKMsfX3wnZTFYwkkt8/z8UesLHlSBQ==" }, + "node_modules/@algolia/ingestion": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/@algolia/ingestion/-/ingestion-1.17.1.tgz", + "integrity": "sha512-T18tvePi1rjRYcIKhd82oRukrPWHxG/Iy1qFGaxCplgRm9Im5z96qnYOq75MSKGOUHkFxaBKJOLmtn8xDR+Mcw==", + "dependencies": { + "@algolia/client-common": "5.17.1", + "@algolia/requester-browser-xhr": "5.17.1", + "@algolia/requester-fetch": "5.17.1", + "@algolia/requester-node-http": "5.17.1" + }, + "engines": { + "node": ">= 14.0.0" + } + }, "node_modules/@algolia/logger-common": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/@algolia/logger-common/-/logger-common-4.22.1.tgz", - "integrity": "sha512-OnTFymd2odHSO39r4DSWRFETkBufnY2iGUZNrMXpIhF5cmFE8pGoINNPzwg02QLBlGSaLqdKy0bM8S0GyqPLBg==" + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/logger-common/-/logger-common-4.24.0.tgz", + "integrity": "sha512-LLUNjkahj9KtKYrQhFKCzMx0BY3RnNP4FEtO+sBybCjJ73E8jNdaKJ/Dd8A/VA4imVHP5tADZ8pn5B8Ga/wTMA==" }, "node_modules/@algolia/logger-console": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/@algolia/logger-console/-/logger-console-4.22.1.tgz", - "integrity": "sha512-O99rcqpVPKN1RlpgD6H3khUWylU24OXlzkavUAMy6QZd1776QAcauE3oP8CmD43nbaTjBexZj2nGsBH9Tc0FVA==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/logger-console/-/logger-console-4.24.0.tgz", + "integrity": "sha512-X4C8IoHgHfiUROfoRCV+lzSy+LHMgkoEEU1BbKcsfnV0i0S20zyy0NLww9dwVHUWNfPPxdMU+/wKmLGYf96yTg==", "dependencies": { - "@algolia/logger-common": "4.22.1" + "@algolia/logger-common": "4.24.0" } }, - "node_modules/@algolia/requester-browser-xhr": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.22.1.tgz", - "integrity": "sha512-dtQGYIg6MteqT1Uay3J/0NDqD+UciHy3QgRbk7bNddOJu+p3hzjTRYESqEnoX/DpEkaNYdRHUKNylsqMpgwaEw==", + "node_modules/@algolia/monitoring": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/@algolia/monitoring/-/monitoring-1.17.1.tgz", + "integrity": "sha512-gDtow+AUywTehRP8S1tWKx2IvhcJOxldAoqBxzN3asuQobF7er5n72auBeL++HY4ImEuzMi7PDOA/Iuwxs2IcA==", "dependencies": { - "@algolia/requester-common": "4.22.1" + "@algolia/client-common": "5.17.1", + "@algolia/requester-browser-xhr": "5.17.1", + "@algolia/requester-fetch": "5.17.1", + "@algolia/requester-node-http": "5.17.1" + }, + "engines": { + "node": ">= 14.0.0" } }, - "node_modules/@algolia/requester-common": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/@algolia/requester-common/-/requester-common-4.22.1.tgz", - "integrity": "sha512-dgvhSAtg2MJnR+BxrIFqlLtkLlVVhas9HgYKMk2Uxiy5m6/8HZBL40JVAMb2LovoPFs9I/EWIoFVjOrFwzn5Qg==" + "node_modules/@algolia/recommend": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-4.24.0.tgz", + "integrity": "sha512-P9kcgerfVBpfYHDfVZDvvdJv0lEoCvzNlOy2nykyt5bK8TyieYyiD0lguIJdRZZYGre03WIAFf14pgE+V+IBlw==", + "dependencies": { + "@algolia/cache-browser-local-storage": "4.24.0", + "@algolia/cache-common": "4.24.0", + "@algolia/cache-in-memory": "4.24.0", + "@algolia/client-common": "4.24.0", + "@algolia/client-search": "4.24.0", + "@algolia/logger-common": "4.24.0", + "@algolia/logger-console": "4.24.0", + "@algolia/requester-browser-xhr": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/requester-node-http": "4.24.0", + "@algolia/transporter": "4.24.0" + } }, - "node_modules/@algolia/requester-node-http": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-4.22.1.tgz", - "integrity": "sha512-JfmZ3MVFQkAU+zug8H3s8rZ6h0ahHZL/SpMaSasTCGYR5EEJsCc8SI5UZ6raPN2tjxa5bxS13BRpGSBUens7EA==", + "node_modules/@algolia/recommend/node_modules/@algolia/client-common": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.24.0.tgz", + "integrity": "sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA==", "dependencies": { - "@algolia/requester-common": "4.22.1" + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" } }, - "node_modules/@algolia/transporter": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/@algolia/transporter/-/transporter-4.22.1.tgz", - "integrity": "sha512-kzWgc2c9IdxMa3YqA6TN0NW5VrKYYW/BELIn7vnLyn+U/RFdZ4lxxt9/8yq3DKV5snvoDzzO4ClyejZRdV3lMQ==", + "node_modules/@algolia/recommend/node_modules/@algolia/client-search": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.24.0.tgz", + "integrity": "sha512-uRW6EpNapmLAD0mW47OXqTP8eiIx5F6qN9/x/7HHO6owL3N1IXqydGwW5nhDFBrV+ldouro2W1VX3XlcUXEFCA==", "dependencies": { - "@algolia/cache-common": "4.22.1", - "@algolia/logger-common": "4.22.1", - "@algolia/requester-common": "4.22.1" + "@algolia/client-common": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" } }, - "node_modules/@ampproject/remapping": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", - "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", + "node_modules/@algolia/recommend/node_modules/@algolia/requester-browser-xhr": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.24.0.tgz", + "integrity": "sha512-Z2NxZMb6+nVXSjF13YpjYTdvV3032YTBSGm2vnYvYPA6mMxzM3v5rsCiSspndn9rzIW4Qp1lPHBvuoKJV6jnAA==", "dependencies": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" + "@algolia/requester-common": "4.24.0" } }, - "node_modules/@babel/code-frame": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", - "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", + "node_modules/@algolia/recommend/node_modules/@algolia/requester-node-http": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-4.24.0.tgz", + "integrity": "sha512-JF18yTjNOVYvU/L3UosRcvbPMGT9B+/GQWNWnenIImglzNVGpyzChkXLnrSf6uxwVNO6ESGu6oN8MqcGQcjQJw==", + "dependencies": { + "@algolia/requester-common": "4.24.0" + } + }, + "node_modules/@algolia/requester-browser-xhr": { + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.17.1.tgz", + "integrity": "sha512-XpKgBfyczVesKgr7DOShNyPPu5kqlboimRRPjdqAw5grSyHhCmb8yoTIKy0TCqBABZeXRPMYT13SMruUVRXvHA==", "dependencies": { - "@babel/highlight": "^7.23.4", - "chalk": "^2.4.2" + "@algolia/client-common": "5.17.1" }, "engines": { - "node": ">=6.9.0" + "node": ">= 14.0.0" } }, - "node_modules/@babel/code-frame/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "node_modules/@algolia/requester-common": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-common/-/requester-common-4.24.0.tgz", + "integrity": "sha512-k3CXJ2OVnvgE3HMwcojpvY6d9kgKMPRxs/kVohrwF5WMr2fnqojnycZkxPoEg+bXm8fi5BBfFmOqgYztRtHsQA==" + }, + "node_modules/@algolia/requester-fetch": { + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/@algolia/requester-fetch/-/requester-fetch-5.17.1.tgz", + "integrity": "sha512-EhUomH+DZP5vb6DnEjT0GvXaXBSwzZnuU6hPGNU1EYKRXDouRjII/bIWpVjt7ycMgL2D2oQruqDh6rAWUhQwRw==", "dependencies": { - "color-convert": "^1.9.0" + "@algolia/client-common": "5.17.1" }, "engines": { - "node": ">=4" + "node": ">= 14.0.0" } }, - "node_modules/@babel/code-frame/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "node_modules/@algolia/requester-node-http": { + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.17.1.tgz", + "integrity": "sha512-PSnENJtl4/wBWXlGyOODbLYm6lSiFqrtww7UpQRCJdsHXlJKF8XAP6AME8NxvbE0Qo/RJUxK0mvyEh9sQcx6bg==", "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "@algolia/client-common": "5.17.1" }, "engines": { - "node": ">=4" + "node": ">= 14.0.0" } }, - "node_modules/@babel/code-frame/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "node_modules/@algolia/transporter": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/transporter/-/transporter-4.24.0.tgz", + "integrity": "sha512-86nI7w6NzWxd1Zp9q3413dRshDqAzSbsQjhcDhPIatEFiZrL1/TjnHL8S7jVKFePlIMzDsZWXAXwXzcok9c5oA==", "dependencies": { - "color-name": "1.1.3" + "@algolia/cache-common": "4.24.0", + "@algolia/logger-common": "4.24.0", + "@algolia/requester-common": "4.24.0" } }, - "node_modules/@babel/code-frame/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" - }, - "node_modules/@babel/code-frame/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, "engines": { - "node": ">=0.8.0" + "node": ">=6.0.0" } }, - "node_modules/@babel/code-frame/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "engines": { - "node": ">=4" + "node_modules/@antfu/install-pkg": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@antfu/install-pkg/-/install-pkg-0.4.1.tgz", + "integrity": "sha512-T7yB5QNG29afhWVkVq7XeIMBa5U/vs9mX69YqayXypPRmYzUmzwnYltplHmPtZ4HPCn+sQKeXW8I47wCbuBOjw==", + "dependencies": { + "package-manager-detector": "^0.2.0", + "tinyexec": "^0.3.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@antfu/utils": { + "version": "0.7.10", + "resolved": "https://registry.npmjs.org/@antfu/utils/-/utils-0.7.10.tgz", + "integrity": "sha512-+562v9k4aI80m1+VuMHehNJWLOFjBnXn3tdOitzD0il5b7smkSBal4+a3oKiQTbrwMmN/TBUMDvbdoWDehgOww==", + "funding": { + "url": "https://github.com/sponsors/antfu" } }, - "node_modules/@babel/code-frame/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "node_modules/@babel/code-frame": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", "dependencies": { - "has-flag": "^3.0.0" + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" }, "engines": { - "node": ">=4" + "node": ">=6.9.0" } }, "node_modules/@babel/compat-data": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz", - "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==", + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.3.tgz", + "integrity": "sha512-nHIxvKPniQXpmQLb0vhY3VaFb3S0YrTAwpOWJZh1wn3oJPjJk9Asva204PsBdmAE8vpzfHudT8DB0scYvy9q0g==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.23.7", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.7.tgz", - "integrity": "sha512-+UpDgowcmqe36d4NwqvKsyPMlOLNGMsfMmQ5WGCu+siCe3t3dfe9njrzGfdN4qq+bcNUt0+Vw6haRxBOycs4dw==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.0.tgz", + "integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==", "dependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.6", - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helpers": "^7.23.7", - "@babel/parser": "^7.23.6", - "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.7", - "@babel/types": "^7.23.6", + "@babel/code-frame": "^7.26.0", + "@babel/generator": "^7.26.0", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helpers": "^7.26.0", + "@babel/parser": "^7.26.0", + "@babel/template": "^7.25.9", + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.26.0", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -323,49 +470,39 @@ } }, "node_modules/@babel/generator": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", - "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.3.tgz", + "integrity": "sha512-6FF/urZvD0sTeO7k6/B15pMLC4CHUv1426lzr3N01aHJTl046uCAh9LXW/fzeXXjPNCJ6iABW5XaWOsIZB93aQ==", "dependencies": { - "@babel/types": "^7.23.6", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", - "jsesc": "^2.5.1" + "@babel/parser": "^7.26.3", + "@babel/types": "^7.26.3", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^3.0.2" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", - "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.15.tgz", - "integrity": "sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz", + "integrity": "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==", "dependencies": { - "@babel/types": "^7.22.15" + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", - "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz", + "integrity": "sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==", "dependencies": { - "@babel/compat-data": "^7.23.5", - "@babel/helper-validator-option": "^7.23.5", - "browserslist": "^4.22.2", + "@babel/compat-data": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" }, @@ -382,18 +519,16 @@ } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.23.7", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.23.7.tgz", - "integrity": "sha512-xCoqR/8+BoNnXOY7RVSgv6X+o7pmT5q1d+gGcRlXYkI+9B31glE4jeejhKVpA04O1AtzOt7OSQ6VYKP5FcRl9g==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-member-expression-to-functions": "^7.23.0", - "@babel/helper-optimise-call-expression": "^7.22.5", - "@babel/helper-replace-supers": "^7.22.20", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.9.tgz", + "integrity": "sha512-UTZQMvt0d/rSz6KI+qdu7GQze5TIajwTS++GUozlw8VBJDEOAqSXwm1WvmYEZwqdqSGQshRocPDqrt4HBZB3fQ==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-member-expression-to-functions": "^7.25.9", + "@babel/helper-optimise-call-expression": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", + "@babel/traverse": "^7.25.9", "semver": "^6.3.1" }, "engines": { @@ -412,12 +547,12 @@ } }, "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.15.tgz", - "integrity": "sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==", + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.26.3.tgz", + "integrity": "sha512-G7ZRb40uUgdKOQqPLjfD12ZmGA54PzqDFUv2BKImnC9QIfGhIHKvVML0oN8IUiDq4iRqpq74ABpvOaerfWdong==", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "regexpu-core": "^5.3.1", + "@babel/helper-annotate-as-pure": "^7.25.9", + "regexpu-core": "^6.2.0", "semver": "^6.3.1" }, "engines": { @@ -436,9 +571,9 @@ } }, "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.5.0.tgz", - "integrity": "sha512-NovQquuQLAQ5HuyjCz7WQP9MjRj7dx++yspwiyUiGl9ZyadHRSql1HZh5ogRd8W8w6YM6EQ/NTB8rgjLt5W65Q==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.3.tgz", + "integrity": "sha512-HK7Bi+Hj6H+VTHA3ZvBis7V/6hu9QuTrnMXNybfUf2iiuU/N97I8VjB+KbhFF8Rld/Lx5MzoCwPCpPjfK+n8Cg==", "dependencies": { "@babel/helper-compilation-targets": "^7.22.6", "@babel/helper-plugin-utils": "^7.22.5", @@ -450,69 +585,38 @@ "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", - "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", - "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", - "dependencies": { - "@babel/template": "^7.22.15", - "@babel/types": "^7.23.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", - "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.23.0.tgz", - "integrity": "sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.25.9.tgz", + "integrity": "sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ==", "dependencies": { - "@babel/types": "^7.23.0" + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", - "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", + "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", "dependencies": { - "@babel/types": "^7.22.15" + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", - "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", + "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-module-imports": "^7.22.15", - "@babel/helper-simple-access": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/helper-validator-identifier": "^7.22.20" + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -522,32 +626,32 @@ } }, "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz", - "integrity": "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.25.9.tgz", + "integrity": "sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ==", "dependencies": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", - "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.9.tgz", + "integrity": "sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.20.tgz", - "integrity": "sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.9.tgz", + "integrity": "sha512-IZtukuUeBbhgOcaW2s06OXTzVNJR0ybm4W5xC1opWFFJMZbwRj5LCk+ByYH7WdZPZTt8KnFwA8pvjN2yqcPlgw==", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-wrap-function": "^7.22.20" + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-wrap-function": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -557,13 +661,13 @@ } }, "node_modules/@babel/helper-replace-supers": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.20.tgz", - "integrity": "sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.25.9.tgz", + "integrity": "sha512-IiDqTOTBQy0sWyeXyGSC5TBJpGFXBkRynjBeXsvbhQFKj2viwJC76Epz35YLU1fpe/Am6Vppb7W7zM4fPQzLsQ==", "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-member-expression-to-functions": "^7.22.15", - "@babel/helper-optimise-call-expression": "^7.22.5" + "@babel/helper-member-expression-to-functions": "^7.25.9", + "@babel/helper-optimise-call-expression": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -572,183 +676,116 @@ "@babel/core": "^7.0.0" } }, - "node_modules/@babel/helper-simple-access": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", - "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz", - "integrity": "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==", - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", - "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.25.9.tgz", + "integrity": "sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA==", "dependencies": { - "@babel/types": "^7.22.5" + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", - "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", - "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", + "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-wrap-function": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.20.tgz", - "integrity": "sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.25.9.tgz", + "integrity": "sha512-ETzz9UTjQSTmw39GboatdymDq4XIQbR8ySgVrylRhPOFpsd+JrKHIuF0de7GCWmem+T4uC5z7EZguod7Wj4A4g==", "dependencies": { - "@babel/helper-function-name": "^7.22.5", - "@babel/template": "^7.22.15", - "@babel/types": "^7.22.19" + "@babel/template": "^7.25.9", + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.23.8", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.8.tgz", - "integrity": "sha512-KDqYz4PiOWvDFrdHLPhKtCThtIcKVy6avWD2oG4GEvyQ+XDZwHD4YQd+H2vNMnq2rkdxsDkU82T+Vk8U/WXHRQ==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.0.tgz", + "integrity": "sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==", "dependencies": { - "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.7", - "@babel/types": "^7.23.6" + "@babel/template": "^7.25.9", + "@babel/types": "^7.26.0" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/highlight": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", - "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", + "node_modules/@babel/parser": { + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.3.tgz", + "integrity": "sha512-WJ/CvmY8Mea8iDXo6a7RK2wbmJITT5fN3BEkRuFlxVyNx8jOKIIhmC4fSkTcPcf8JyavbBwIe6OpiCOBXt/IcA==", "dependencies": { - "@babel/helper-validator-identifier": "^7.22.20", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0" + "@babel/types": "^7.26.3" }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dependencies": { - "color-convert": "^1.9.0" + "bin": { + "parser": "bin/babel-parser.js" }, "engines": { - "node": ">=4" + "node": ">=6.0.0" } }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.9.tgz", + "integrity": "sha512-ZkRyVkThtxQ/J6nv3JFYv1RYY+JT5BvU0y3k5bWrmuG4woXypRa4PXmm9RhOwodRkYFWqC0C0cqcJ4OqR7kW+g==", "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" - }, - "node_modules/@babel/highlight/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "engines": { - "node": ">=4" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.9.tgz", + "integrity": "sha512-MrGRLZxLD/Zjj0gdU15dfs+HH/OXvnw/U4jJD8vpcP2CJQapPEv1IWwjc/qMg7ItBlPwSv1hRBbb7LeuANdcnw==", "dependencies": { - "has-flag": "^3.0.0" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/parser": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz", - "integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==", - "bin": { - "parser": "bin/babel-parser.js" + "node": ">=6.9.0" }, - "engines": { - "node": ">=6.0.0" + "peerDependencies": { + "@babel/core": "^7.0.0" } }, "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.23.3.tgz", - "integrity": "sha512-iRkKcCqb7iGnq9+3G6rZ+Ciz5VywC4XNRHe57lKM+jOeYAoR0lVqdeeDRfh0tQcTfw/+vBhHn926FmQhLtlFLQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.9.tgz", + "integrity": "sha512-2qUwwfAFpJLZqxd02YW9btUCZHl+RFvdDkNfZwaIJrvB8Tesjsk8pEQkTvGwZXLqXUx/2oyY3ySRhm6HOXuCug==", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -758,13 +795,13 @@ } }, "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.23.3.tgz", - "integrity": "sha512-WwlxbfMNdVEpQjZmK5mhm7oSwD3dS6eU+Iwsi4Knl9wAletWem7kaRsGOG+8UEbRyqxY4SS5zvtfXwX+jMxUwQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.25.9.tgz", + "integrity": "sha512-6xWgLZTJXwilVjlnV7ospI3xi+sl8lN8rXXbBD6vYn3UYDlGsag8wrZkKcSI8G6KgqKP7vNFaDgeDnfAABq61g==", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/plugin-transform-optional-chaining": "^7.23.3" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", + "@babel/plugin-transform-optional-chaining": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -774,12 +811,12 @@ } }, "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { - "version": "7.23.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.23.7.tgz", - "integrity": "sha512-LlRT7HgaifEpQA1ZgLVOIJZZFVPWN5iReq/7/JixwBtwcoeVGDBD53ZV28rrsLYOZs1Y/EHhA8N/Z6aazHR8cw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.9.tgz", + "integrity": "sha512-aLnMXYPnzwwqhYSCyXfKkIkYgJ8zv9RK+roo9DkTXz38ynIhd9XCbN08s3MGvqL2MYGVUGdRQLL/JqBIeJhJBg==", "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -799,10 +836,10 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "node_modules/@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -810,23 +847,26 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.26.0.tgz", + "integrity": "sha512-QCWT5Hh830hK5EQa7XzuqIkQU9tT/whqbDz7kuaZMHFl1inRRg7JnuAEOQ0Ur0QUl0NufCk1msK2BeY79Aj/eg==", "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-class-static-block": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", - "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.26.0.tgz", + "integrity": "sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==", "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -835,48 +875,55 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-dynamic-import": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", - "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.25.9.tgz", + "integrity": "sha512-ld6oezHQMZsZfp6pWtbjaNDF2tiiCYYDqQszHt5VV437lewP9aSi2Of99CK0D0XB21k7FLgnLcmQKyKzynfeAA==", "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-export-namespace-from": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", - "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.9.tgz", + "integrity": "sha512-hjMgRy5hb8uJJjUcdWunWVcoi9bGpJp8p5Ol1229PoN6aytsLwNMgmdftO23wnCLMfVmTwZDWMPNq/D1SY60JQ==", "dependencies": { - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-import-assertions": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.23.3.tgz", - "integrity": "sha512-lPgDSU+SJLK3xmFDTV2ZRQAiM7UuUjGidwBywFavObCiZc1BeAAcMtHJKUya92hPHO+at63JJPLygilZard8jw==", + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.0.0" } }, - "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.23.3.tgz", - "integrity": "sha512-pawnE0P9g10xgoP7yKr6CK63K2FMsTE+FZidZO/1PwRdzmAPVs+HS1mAURUsgaoxammTJvULUdIkEK0gOcU2tA==", + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.25.9.tgz", + "integrity": "sha512-6jmooXYIwn9ca5/RylZADJ+EnSxVUS5sjeJ9UPk6RWRzXCmOJCy6dqItPJFpw2cuCangPK4OYr5uhGKcmrm5Qg==", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -885,34 +932,44 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.9.tgz", + "integrity": "sha512-RXV6QAzTBbhDMO9fWwOmwwTuYaiPbggWQ9INdZqAYeSHyG7FzQ+nOZaUUjNwKv9pV3aE4WFqFm1Hnbci5tBCAw==", "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-remap-async-to-generator": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.25.9.tgz", + "integrity": "sha512-NT7Ejn7Z/LjUH0Gv5KsBCxh7BH3fbLTV0ptHvpeMvrt3cPThHfJfst9Wrb7S8EvJ7vRTFI7z+VAvFVEQn/m5zQ==", "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-remap-async-to-generator": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.23.3.tgz", - "integrity": "sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==", + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.25.9.tgz", + "integrity": "sha512-toHc9fzab0ZfenFpsyYinOX0J/5dgJVA2fm64xPewu7CoYHWEivIWKxkK2rMi4r3yQqLnVmheMXRdG+k239CgA==", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -921,248 +978,76 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.9.tgz", + "integrity": "sha512-1F05O7AYjymAtqbsFETboN1NvBdcnzMerO+zlMyJBEz6WkMdejvGWw9p05iTSjC85RLlBseHHQpYaM4gzJkBGg==", "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.9.tgz", + "integrity": "sha512-bbMAII8GRSkcd0h0b4X+36GksxuheLFjP65ul9w6C3KgAamI3JqErNgSrosX6ZPj+Mpim5VvEbawXxJCyEUV3Q==", "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.26.0.tgz", + "integrity": "sha512-6J2APTs7BDDm+UMqP1useWqhcRAXo0WIoVj26N7kPFB6S73Lgvyka4KTZYIxtgYXiN5HTyRObA72N2iu628iTQ==", "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.12.0" } }, - "node_modules/@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" + "node_modules/@babel/plugin-transform-classes": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.9.tgz", + "integrity": "sha512-mD8APIXmseE7oZvZgGABDyM34GUmK45Um2TXiBUt7PnuAxrgoSVf123qUzPxEr/+/BHrRn5NMZCdE2m/1F8DGg==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9", + "@babel/traverse": "^7.25.9", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.25.9.tgz", + "integrity": "sha512-HnBegGqXZR12xbcTHlJ9HGxw1OniltT26J5YpfruGqtUHlz/xKf/G2ak9e+t0rVqrjXa9WOhvYPz1ERfMj23AA==", "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-private-property-in-object": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", - "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.23.3.tgz", - "integrity": "sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-unicode-sets-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", - "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-transform-arrow-functions": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.23.3.tgz", - "integrity": "sha512-NzQcQrzaQPkaEwoTm4Mhyl8jI1huEL/WWIEvudjTCMJ9aBZNpsJbMASx7EQECtQQPS/DcnFpo0FIh3LvEO9cxQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-async-generator-functions": { - "version": "7.23.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.23.7.tgz", - "integrity": "sha512-PdxEpL71bJp1byMG0va5gwQcXHxuEYC/BgI/e88mGTtohbZN28O5Yit0Plkkm/dBzCF/BxmbNcses1RH1T+urA==", - "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-remap-async-to-generator": "^7.22.20", - "@babel/plugin-syntax-async-generators": "^7.8.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.23.3.tgz", - "integrity": "sha512-A7LFsKi4U4fomjqXJlZg/u0ft/n8/7n7lpffUP/ZULx/DtV9SGlNKZolHH6PE8Xl1ngCc0M11OaeZptXVkfKSw==", - "dependencies": { - "@babel/helper-module-imports": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-remap-async-to-generator": "^7.22.20" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-block-scoped-functions": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.23.3.tgz", - "integrity": "sha512-vI+0sIaPIO6CNuM9Kk5VmXcMVRiOpDh7w2zZt9GXzmE/9KD70CUEVhvPR/etAeNK/FAEkhxQtXOzVF3EuRL41A==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.23.4.tgz", - "integrity": "sha512-0QqbP6B6HOh7/8iNR4CQU2Th/bbRtBp4KS9vcaZd1fZ0wSh5Fyssg0UCIHwxh+ka+pNDREbVLQnHCMHKZfPwfw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-class-properties": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.23.3.tgz", - "integrity": "sha512-uM+AN8yCIjDPccsKGlw271xjJtGii+xQIF/uMPS8H15L12jZTsLfF4o5vNO7d/oUguOyfdikHGc/yi9ge4SGIg==", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-class-static-block": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.23.4.tgz", - "integrity": "sha512-nsWu/1M+ggti1SOALj3hfx5FXzAY06fwPJsUZD4/A5e1bWi46VUIWtD+kOX6/IdhXGsXBWllLFDSnqSCdUNydQ==", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-class-static-block": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.12.0" - } - }, - "node_modules/@babel/plugin-transform-classes": { - "version": "7.23.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.23.8.tgz", - "integrity": "sha512-yAYslGsY1bX6Knmg46RjiCiNSwJKv2IUC8qOdYKqMMr0491SXFhcHqOdRDeCRohOOIzwN/90C6mQ9qAKgrP7dg==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-replace-supers": "^7.22.20", - "@babel/helper-split-export-declaration": "^7.22.6", - "globals": "^11.1.0" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/template": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1171,13 +1056,12 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.23.3.tgz", - "integrity": "sha512-dTj83UVTLw/+nbiHqQSFdwO9CbTtwq1DsDqm3CUEtDrZNET5rT5E6bIdTlOftDTDLMYxvxHNEYO4B9SLl8SLZw==", + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.25.9.tgz", + "integrity": "sha512-WkCGb/3ZxXepmMiX101nnGiU+1CAdut8oHyEOHxkKuS1qKpU2SMXE2uSvfz8PBuLd49V6LEsbtyPhWC7fnkgvQ==", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/template": "^7.22.15" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1186,12 +1070,13 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.23.3.tgz", - "integrity": "sha512-n225npDqjDIr967cMScVKHXJs7rout1q+tt50inyBCPkyZ8KxeI6d+GIbSBTT/w/9WdlWDOej3V9HE5Lgk57gw==", + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.25.9.tgz", + "integrity": "sha512-t7ZQ7g5trIgSRYhI9pIJtRl64KHotutUJsh4Eze5l7olJv+mRSg4/MmbZ0tv1eeqRbdvo/+trvJD/Oc5DmW2cA==", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1200,13 +1085,12 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-dotall-regex": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.23.3.tgz", - "integrity": "sha512-vgnFYDHAKzFaTVp+mneDsIEbnJ2Np/9ng9iviHw3P/KVcgONxpNULEW/51Z/BaFojG2GI2GwwXck5uV1+1NOYQ==", + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.25.9.tgz", + "integrity": "sha512-LZxhJ6dvBb/f3x8xwWIuyiAHy56nrRG3PeYTpBkkzkYRRQ6tJLu68lEF5VIqMUZiAV7a8+Tb78nEoMCMcqjXBw==", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1215,27 +1099,27 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-duplicate-keys": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.23.3.tgz", - "integrity": "sha512-RrqQ+BQmU3Oyav3J+7/myfvRCq7Tbz+kKLLshUmMwNlDHExbGL7ARhajvoBJEvc+fCguPPu887N+3RRXBVKZUA==", + "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.9.tgz", + "integrity": "sha512-0UfuJS0EsXbRvKnwcLjFtJy/Sxc5J5jhLHnFhy7u4zih97Hz6tJkLU+O+FMMrNZrosUPxDi6sYxJ/EA8jDiAog==", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.0.0" } }, "node_modules/@babel/plugin-transform-dynamic-import": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.23.4.tgz", - "integrity": "sha512-V6jIbLhdJK86MaLh4Jpghi8ho5fGzt3imHOBu/x0jlBaPYqDoWz4RDXjmMOfnh+JWNaQleEAByZLV0QzBT4YQQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.25.9.tgz", + "integrity": "sha512-GCggjexbmSLaFhqsojeugBpeaRIgWNTcgKVq/0qIteFEqY2A+b9QidYadrWlnbWQUrW5fn+mCvf3tr7OeBFTyg==", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-dynamic-import": "^7.8.3" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1245,12 +1129,11 @@ } }, "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.23.3.tgz", - "integrity": "sha512-5fhCsl1odX96u7ILKHBj4/Y8vipoqwsJMh4csSA8qFfxrZDEA4Ssku2DyNvMJSmZNOEBT750LfFPbtrnTP90BQ==", + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.26.3.tgz", + "integrity": "sha512-7CAHcQ58z2chuXPWblnn1K6rLDnDWieghSOEmqQsrBenH0P9InCUtOJYD89pvngljmZlJcz3fcmgYsXFNGa1ZQ==", "dependencies": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1260,12 +1143,11 @@ } }, "node_modules/@babel/plugin-transform-export-namespace-from": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.23.4.tgz", - "integrity": "sha512-GzuSBcKkx62dGzZI1WVgTWvkkz84FZO5TC5T8dl/Tht/rAla6Dg/Mz9Yhypg+ezVACf/rgDuQt3kbWEv7LdUDQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.25.9.tgz", + "integrity": "sha512-2NsEz+CxzJIVOPx2o9UsW1rXLqtChtLoVnwYHHiB04wS5sgn7mrV45fWMBX0Kk+ub9uXytVYfNP2HjbVbCB3Ww==", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1275,12 +1157,12 @@ } }, "node_modules/@babel/plugin-transform-for-of": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.23.6.tgz", - "integrity": "sha512-aYH4ytZ0qSuBbpfhuofbg/e96oQ7U2w1Aw/UQmKT+1l39uEhUPoFS3fHevDc1G0OvewyDudfMKY1OulczHzWIw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.25.9.tgz", + "integrity": "sha512-LqHxduHoaGELJl2uhImHwRQudhCM50pT46rIBNvtT/Oql3nqiS3wOwP+5ten7NpYSXrrVLgtZU3DZmPtWZo16A==", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1290,13 +1172,13 @@ } }, "node_modules/@babel/plugin-transform-function-name": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.23.3.tgz", - "integrity": "sha512-I1QXp1LxIvt8yLaib49dRW5Okt7Q4oaxao6tFVKS/anCdEOMtYwWVKoiOA1p34GOWIZjUK0E+zCp7+l1pfQyiw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.9.tgz", + "integrity": "sha512-8lP+Yxjv14Vc5MuWBpJsoUCd3hD6V9DgBon2FVYL4jJgbnVQ9fTgYmonchzZJOVNgzEgbxp4OwAf6xz6M/14XA==", "dependencies": { - "@babel/helper-compilation-targets": "^7.22.15", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1306,12 +1188,11 @@ } }, "node_modules/@babel/plugin-transform-json-strings": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.23.4.tgz", - "integrity": "sha512-81nTOqM1dMwZ/aRXQ59zVubN9wHGqk6UtqRK+/q+ciXmRy8fSolhGVvG09HHRGo4l6fr/c4ZhXUQH0uFW7PZbg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.25.9.tgz", + "integrity": "sha512-xoTMk0WXceiiIvsaquQQUaLLXSW1KJ159KP87VilruQm0LNNGxWzahxSS6T6i4Zg3ezp4vA4zuwiNUR53qmQAw==", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-json-strings": "^7.8.3" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1321,11 +1202,11 @@ } }, "node_modules/@babel/plugin-transform-literals": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.23.3.tgz", - "integrity": "sha512-wZ0PIXRxnwZvl9AYpqNUxpZ5BiTGrYt7kueGQ+N5FiQ7RCOD4cm8iShd6S6ggfVIWaJf2EMk8eRzAh52RfP4rQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.9.tgz", + "integrity": "sha512-9N7+2lFziW8W9pBl2TzaNht3+pgMIRP74zizeCSrtnSKVdUl8mAjjOP2OOVQAfZ881P2cNjDj1uAMEdeD50nuQ==", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1335,12 +1216,11 @@ } }, "node_modules/@babel/plugin-transform-logical-assignment-operators": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.23.4.tgz", - "integrity": "sha512-Mc/ALf1rmZTP4JKKEhUwiORU+vcfarFVLfcFiolKUo6sewoxSEgl36ak5t+4WamRsNr6nzjZXQjM35WsU+9vbg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.25.9.tgz", + "integrity": "sha512-wI4wRAzGko551Y8eVf6iOY9EouIDTtPb0ByZx+ktDGHwv6bHFimrgJM/2T021txPZ2s4c7bqvHbd+vXG6K948Q==", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1350,11 +1230,11 @@ } }, "node_modules/@babel/plugin-transform-member-expression-literals": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.23.3.tgz", - "integrity": "sha512-sC3LdDBDi5x96LA+Ytekz2ZPk8i/Ck+DEuDbRAll5rknJ5XRTSaPKEYwomLcs1AA8wg9b3KjIQRsnApj+q51Ag==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.25.9.tgz", + "integrity": "sha512-PYazBVfofCQkkMzh2P6IdIUaCEWni3iYEerAsRWuVd8+jlM1S9S9cz1dF9hIzyoZ8IA3+OwVYIp9v9e+GbgZhA==", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1364,12 +1244,12 @@ } }, "node_modules/@babel/plugin-transform-modules-amd": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.23.3.tgz", - "integrity": "sha512-vJYQGxeKM4t8hYCKVBlZX/gtIY2I7mRGFNcm85sgXGMTBcoV3QdVtdpbcWEbzbfUIUZKwvgFT82mRvaQIebZzw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.25.9.tgz", + "integrity": "sha512-g5T11tnI36jVClQlMlt4qKDLlWnG5pP9CSM4GhdRciTNMRgkfpo5cR6b4rGIOYPgRRuFAvwjPQ/Yk+ql4dyhbw==", "dependencies": { - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1379,13 +1259,12 @@ } }, "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.3.tgz", - "integrity": "sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA==", + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.26.3.tgz", + "integrity": "sha512-MgR55l4q9KddUDITEzEFYn5ZsGDXMSsU9E+kh7fjRXTIC3RHqfCo8RPRbyReYJh44HQ/yomFkqbOFohXvDCiIQ==", "dependencies": { - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-simple-access": "^7.22.5" + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1395,14 +1274,14 @@ } }, "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.23.3.tgz", - "integrity": "sha512-ZxyKGTkF9xT9YJuKQRo19ewf3pXpopuYQd8cDXqNzc3mUNbOME0RKMoZxviQk74hwzfQsEe66dE92MaZbdHKNQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.9.tgz", + "integrity": "sha512-hyss7iIlH/zLHaehT+xwiymtPOpsiwIIRlCAOwBB04ta5Tt+lNItADdlXw3jAWZ96VJ2jlhl/c+PNIQPKNfvcA==", "dependencies": { - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.20" + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1412,12 +1291,12 @@ } }, "node_modules/@babel/plugin-transform-modules-umd": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.23.3.tgz", - "integrity": "sha512-zHsy9iXX2nIsCBFPud3jKn1IRPWg3Ing1qOZgeKV39m1ZgIdpJqvlWVeiHBZC6ITRG0MfskhYe9cLgntfSFPIg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.25.9.tgz", + "integrity": "sha512-bS9MVObUgE7ww36HEfwe6g9WakQ0KF07mQF74uuXdkoziUPfKyu/nIm663kz//e5O1nPInPFx36z7WJmJ4yNEw==", "dependencies": { - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1427,12 +1306,12 @@ } }, "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz", - "integrity": "sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.25.9.tgz", + "integrity": "sha512-oqB6WHdKTGl3q/ItQhpLSnWWOpjUJLsOCLVyeFgeTktkBSCiurvPOsyt93gibI9CmuKvTUEtWmG5VhZD+5T/KA==", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1442,11 +1321,11 @@ } }, "node_modules/@babel/plugin-transform-new-target": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.23.3.tgz", - "integrity": "sha512-YJ3xKqtJMAT5/TIZnpAR3I+K+WaDowYbN3xyxI8zxx/Gsypwf9B9h0VB+1Nh6ACAAPRS5NSRje0uVv5i79HYGQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.25.9.tgz", + "integrity": "sha512-U/3p8X1yCSoKyUj2eOBIx3FOn6pElFOKvAAGf8HTtItuPyB+ZeOqfn+mvTtg9ZlOAjsPdK3ayQEjqHjU/yLeVQ==", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1456,12 +1335,11 @@ } }, "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.23.4.tgz", - "integrity": "sha512-jHE9EVVqHKAQx+VePv5LLGHjmHSJR76vawFPTdlxR/LVJPfOEGxREQwQfjuZEOPTwG92X3LINSh3M40Rv4zpVA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.25.9.tgz", + "integrity": "sha512-ENfftpLZw5EItALAD4WsY/KUWvhUlZndm5GC7G3evUsVeSJB6p0pBeLQUnRnBCBx7zV0RKQjR9kCuwrsIrjWog==", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1471,12 +1349,11 @@ } }, "node_modules/@babel/plugin-transform-numeric-separator": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.23.4.tgz", - "integrity": "sha512-mps6auzgwjRrwKEZA05cOwuDc9FAzoyFS4ZsG/8F43bTLf/TgkJg7QXOrPO1JO599iA3qgK9MXdMGOEC8O1h6Q==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.25.9.tgz", + "integrity": "sha512-TlprrJ1GBZ3r6s96Yq8gEQv82s8/5HnCVHtEJScUj90thHQbwe+E5MLhi2bbNHBEJuzrvltXSru+BUxHDoog7Q==", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1486,15 +1363,13 @@ } }, "node_modules/@babel/plugin-transform-object-rest-spread": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.23.4.tgz", - "integrity": "sha512-9x9K1YyeQVw0iOXJlIzwm8ltobIIv7j2iLyP2jIhEbqPRQ7ScNgwQufU2I0Gq11VjyG4gI4yMXt2VFags+1N3g==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.25.9.tgz", + "integrity": "sha512-fSaXafEE9CVHPweLYw4J0emp1t8zYTXyzN3UuG+lylqkvYd7RMrsOQ8TYx5RF231be0vqtFC6jnx3UmpJmKBYg==", "dependencies": { - "@babel/compat-data": "^7.23.3", - "@babel/helper-compilation-targets": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.23.3" + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/plugin-transform-parameters": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1504,12 +1379,12 @@ } }, "node_modules/@babel/plugin-transform-object-super": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.23.3.tgz", - "integrity": "sha512-BwQ8q0x2JG+3lxCVFohg+KbQM7plfpBwThdW9A6TMtWwLsbDA01Ek2Zb/AgDN39BiZsExm4qrXxjk+P1/fzGrA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.25.9.tgz", + "integrity": "sha512-Kj/Gh+Rw2RNLbCK1VAWj2U48yxxqL2x0k10nPtSdRa0O2xnHXalD0s+o1A6a0W43gJ00ANo38jxkQreckOzv5A==", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-replace-supers": "^7.22.20" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1519,12 +1394,11 @@ } }, "node_modules/@babel/plugin-transform-optional-catch-binding": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.23.4.tgz", - "integrity": "sha512-XIq8t0rJPHf6Wvmbn9nFxU6ao4c7WhghTR5WyV8SrJfUFzyxhCm4nhC+iAp3HFhbAKLfYpgzhJ6t4XCtVwqO5A==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.25.9.tgz", + "integrity": "sha512-qM/6m6hQZzDcZF3onzIhZeDHDO43bkNNlOX0i8n3lR6zLbu0GN2d8qfM/IERJZYauhAHSLHy39NF0Ctdvcid7g==", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1534,13 +1408,12 @@ } }, "node_modules/@babel/plugin-transform-optional-chaining": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.23.4.tgz", - "integrity": "sha512-ZU8y5zWOfjM5vZ+asjgAPwDaBjJzgufjES89Rs4Lpq63O300R/kOz30WCLo6BxxX6QVEilwSlpClnG5cZaikTA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.25.9.tgz", + "integrity": "sha512-6AvV0FsLULbpnXeBjrY4dmWF8F7gf8QnvTEoO/wX/5xm/xE1Xo8oPuD3MPS+KS9f9XBEAWN7X1aWr4z9HdOr7A==", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1550,11 +1423,11 @@ } }, "node_modules/@babel/plugin-transform-parameters": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.23.3.tgz", - "integrity": "sha512-09lMt6UsUb3/34BbECKVbVwrT9bO6lILWln237z7sLaWnMsTi7Yc9fhX5DLpkJzAGfaReXI22wP41SZmnAA3Vw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.25.9.tgz", + "integrity": "sha512-wzz6MKwpnshBAiRmn4jR8LYz/g8Ksg0o80XmwZDlordjwEk9SxBzTWC7F5ef1jhbrbOW2DJ5J6ayRukrJmnr0g==", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1564,12 +1437,12 @@ } }, "node_modules/@babel/plugin-transform-private-methods": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.23.3.tgz", - "integrity": "sha512-UzqRcRtWsDMTLrRWFvUBDwmw06tCQH9Rl1uAjfh6ijMSmGYQ+fpdB+cnqRC8EMh5tuuxSv0/TejGL+7vyj+50g==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.9.tgz", + "integrity": "sha512-D/JUozNpQLAPUVusvqMxyvjzllRaF8/nSrP1s2YGQT/W4LHK4xxsMcHjhOGTS01mp9Hda8nswb+FblLdJornQw==", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1579,14 +1452,13 @@ } }, "node_modules/@babel/plugin-transform-private-property-in-object": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.23.4.tgz", - "integrity": "sha512-9G3K1YqTq3F4Vt88Djx1UZ79PDyj+yKRnUy7cZGSMe+a7jkwD259uKKuUzQlPkGam7R+8RJwh5z4xO27fA1o2A==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.25.9.tgz", + "integrity": "sha512-Evf3kcMqzXA3xfYJmZ9Pg1OvKdtqsDMSWBDzZOPLvHiTt36E75jLDQo5w1gtRU95Q4E5PDttrTf25Fw8d/uWLw==", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-create-class-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1596,11 +1468,11 @@ } }, "node_modules/@babel/plugin-transform-property-literals": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.23.3.tgz", - "integrity": "sha512-jR3Jn3y7cZp4oEWPFAlRsSWjxKe4PZILGBSd4nis1TsC5qeSpb+nrtihJuDhNI7QHiVbUaiXa0X2RZY3/TI6Nw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.25.9.tgz", + "integrity": "sha512-IvIUeV5KrS/VPavfSM/Iu+RE6llrHrYIKY1yfCzyO/lMXHQ+p7uGhonmGVisv6tSBSVgWzMBohTcvkC9vQcQFA==", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1610,11 +1482,11 @@ } }, "node_modules/@babel/plugin-transform-react-constant-elements": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.23.3.tgz", - "integrity": "sha512-zP0QKq/p6O42OL94udMgSfKXyse4RyJ0JqbQ34zDAONWjyrEsghYEyTSK5FIpmXmCpB55SHokL1cRRKHv8L2Qw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.25.9.tgz", + "integrity": "sha512-Ncw2JFsJVuvfRsa2lSHiC55kETQVLSnsYGQ1JDDwkUeWGTL/8Tom8aLTnlqgoeuopWrbbGndrc9AlLYrIosrow==", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1624,11 +1496,11 @@ } }, "node_modules/@babel/plugin-transform-react-display-name": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.23.3.tgz", - "integrity": "sha512-GnvhtVfA2OAtzdX58FJxU19rhoGeQzyVndw3GgtdECQvQFXPEZIOVULHVZGAYmOgmqjXpVpfocAbSjh99V/Fqw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.25.9.tgz", + "integrity": "sha512-KJfMlYIUxQB1CJfO3e0+h0ZHWOTLCPP115Awhaz8U0Zpq36Gl/cXlpoyMRnUWlhNUBAzldnCiAZNvCDj7CrKxQ==", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1638,15 +1510,15 @@ } }, "node_modules/@babel/plugin-transform-react-jsx": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.23.4.tgz", - "integrity": "sha512-5xOpoPguCZCRbo/JeHlloSkTA8Bld1J/E1/kLfD1nsuiW1m8tduTA1ERCgIZokDflX/IBzKcqR3l7VlRgiIfHA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.25.9.tgz", + "integrity": "sha512-s5XwpQYCqGerXl+Pu6VDL3x0j2d82eiV77UJ8a2mDHAW7j9SWRqQ2y1fNo1Z74CdcYipl5Z41zvjj4Nfzq36rw==", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-module-imports": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-jsx": "^7.23.3", - "@babel/types": "^7.23.4" + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/plugin-syntax-jsx": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1656,11 +1528,11 @@ } }, "node_modules/@babel/plugin-transform-react-jsx-development": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.22.5.tgz", - "integrity": "sha512-bDhuzwWMuInwCYeDeMzyi7TaBgRQei6DqxhbyniL7/VG4RSS7HtSL2QbY4eESy1KJqlWt8g3xeEBGPuo+XqC8A==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.25.9.tgz", + "integrity": "sha512-9mj6rm7XVYs4mdLIpbZnHOYdpW42uoiBCTVowg7sP1thUOiANgMb4UtpRivR0pp5iL+ocvUv7X4mZgFRpJEzGw==", "dependencies": { - "@babel/plugin-transform-react-jsx": "^7.22.5" + "@babel/plugin-transform-react-jsx": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1670,12 +1542,12 @@ } }, "node_modules/@babel/plugin-transform-react-pure-annotations": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.23.3.tgz", - "integrity": "sha512-qMFdSS+TUhB7Q/3HVPnEdYJDQIk57jkntAwSuz9xfSE4n+3I+vHYCli3HoHawN1Z3RfCz/y1zXA/JXjG6cVImQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.25.9.tgz", + "integrity": "sha512-KQ/Takk3T8Qzj5TppkS1be588lkbTp5uj7w6a0LeQaTMSckU/wK0oJ/pih+T690tkgI5jfmg2TqDJvd41Sj1Cg==", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1685,11 +1557,11 @@ } }, "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.23.3.tgz", - "integrity": "sha512-KP+75h0KghBMcVpuKisx3XTu9Ncut8Q8TuvGO4IhY+9D5DFEckQefOuIsB/gQ2tG71lCke4NMrtIPS8pOj18BQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.25.9.tgz", + "integrity": "sha512-vwDcDNsgMPDGP0nMqzahDWE5/MLcX8sv96+wfX7as7LoF/kr97Bo/7fI00lXY4wUXYfVmwIIyG80fGZ1uvt2qg==", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-plugin-utils": "^7.25.9", "regenerator-transform": "^0.15.2" }, "engines": { @@ -1699,12 +1571,27 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-transform-regexp-modifiers": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.26.0.tgz", + "integrity": "sha512-vN6saax7lrA2yA/Pak3sCxuD6F5InBjn9IcrIKQPjpsLvuHYLVroTxjdlVRHjjBWxKOqIwpTXDkOssYT4BFdRw==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, "node_modules/@babel/plugin-transform-reserved-words": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.23.3.tgz", - "integrity": "sha512-QnNTazY54YqgGxwIexMZva9gqbPa15t/x9VS+0fsEFWplwVpXYZivtgl43Z1vMpc1bdPP2PP8siFeVcnFvA3Cg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.25.9.tgz", + "integrity": "sha512-7DL7DKYjn5Su++4RXu8puKZm2XBPHyjWLUidaPEkCUBbE7IPcsrkRHggAOOKydH1dASWdcUBxrkOGNxUv5P3Jg==", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1714,15 +1601,15 @@ } }, "node_modules/@babel/plugin-transform-runtime": { - "version": "7.23.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.23.7.tgz", - "integrity": "sha512-fa0hnfmiXc9fq/weK34MUV0drz2pOL/vfKWvN7Qw127hiUPabFCUMgAbYWcchRzMJit4o5ARsK/s+5h0249pLw==", - "dependencies": { - "@babel/helper-module-imports": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", - "babel-plugin-polyfill-corejs2": "^0.4.7", - "babel-plugin-polyfill-corejs3": "^0.8.7", - "babel-plugin-polyfill-regenerator": "^0.5.4", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.25.9.tgz", + "integrity": "sha512-nZp7GlEl+yULJrClz0SwHPqir3lc0zsPrDHQUcxGspSL7AKrexNSEfTbfqnDNJUO13bgKyfuOLMF8Xqtu8j3YQ==", + "dependencies": { + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.10.6", + "babel-plugin-polyfill-regenerator": "^0.6.1", "semver": "^6.3.1" }, "engines": { @@ -1741,11 +1628,11 @@ } }, "node_modules/@babel/plugin-transform-shorthand-properties": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.23.3.tgz", - "integrity": "sha512-ED2fgqZLmexWiN+YNFX26fx4gh5qHDhn1O2gvEhreLW2iI63Sqm4llRLCXALKrCnbN4Jy0VcMQZl/SAzqug/jg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.25.9.tgz", + "integrity": "sha512-MUv6t0FhO5qHnS/W8XCbHmiRWOphNufpE1IVxhK5kuN3Td9FT1x4rx4K42s3RYdMXCXpfWkGSbCSd0Z64xA7Ng==", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1755,12 +1642,12 @@ } }, "node_modules/@babel/plugin-transform-spread": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.23.3.tgz", - "integrity": "sha512-VvfVYlrlBVu+77xVTOAoxQ6mZbnIq5FM0aGBSFEcIh03qHf+zNqA4DC/3XMUozTg7bZV3e3mZQ0i13VB6v5yUg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.25.9.tgz", + "integrity": "sha512-oNknIB0TbURU5pqJFVbOOFspVlrpVwo2H1+HUIsVDvp5VauGGDP1ZEvO8Nn5xyMEs3dakajOxlmkNW7kNgSm6A==", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1770,11 +1657,11 @@ } }, "node_modules/@babel/plugin-transform-sticky-regex": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.23.3.tgz", - "integrity": "sha512-HZOyN9g+rtvnOU3Yh7kSxXrKbzgrm5X4GncPY1QOquu7epga5MxKHVpYu2hvQnry/H+JjckSYRb93iNfsioAGg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.25.9.tgz", + "integrity": "sha512-WqBUSgeVwucYDP9U/xNRQam7xV8W5Zf+6Eo7T2SRVUFlhRiMNFdFz58u0KZmCVVqs2i7SHgpRnAhzRNmKfi2uA==", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1784,11 +1671,11 @@ } }, "node_modules/@babel/plugin-transform-template-literals": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.23.3.tgz", - "integrity": "sha512-Flok06AYNp7GV2oJPZZcP9vZdszev6vPBkHLwxwSpaIqx75wn6mUd3UFWsSsA0l8nXAKkyCmL/sR02m8RYGeHg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.25.9.tgz", + "integrity": "sha512-o97AE4syN71M/lxrCtQByzphAdlYluKPDBzDVzMmfCobUjjhAryZV0AIpRPrxN0eAkxXO6ZLEScmt+PNhj2OTw==", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1798,11 +1685,11 @@ } }, "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.23.3.tgz", - "integrity": "sha512-4t15ViVnaFdrPC74be1gXBSMzXk3B4Us9lP7uLRQHTFpV5Dvt33pn+2MyyNxmN3VTTm3oTrZVMUmuw3oBnQ2oQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.25.9.tgz", + "integrity": "sha512-v61XqUMiueJROUv66BVIOi0Fv/CUuZuZMl5NkRoCVxLAnMexZ0A3kMe7vvZ0nulxMuMp0Mk6S5hNh48yki08ZA==", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1812,14 +1699,15 @@ } }, "node_modules/@babel/plugin-transform-typescript": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.23.6.tgz", - "integrity": "sha512-6cBG5mBvUu4VUD04OHKnYzbuHNP8huDsD3EDqqpIpsswTDoqHCjLoHb6+QgsV1WsT2nipRqCPgxD3LXnEO7XfA==", + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.26.3.tgz", + "integrity": "sha512-6+5hpdr6mETwSKjmJUdYw0EIkATiQhnELWlE3kJFBwSg/BGIVwVaVbX+gOXBCdc7Ln1RXZxyWGecIXhUfnl7oA==", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-create-class-features-plugin": "^7.23.6", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-typescript": "^7.23.3" + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", + "@babel/plugin-syntax-typescript": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1829,11 +1717,11 @@ } }, "node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.23.3.tgz", - "integrity": "sha512-OMCUx/bU6ChE3r4+ZdylEqAjaQgHAgipgW8nsCfu5pGqDcFytVd91AwRvUJSBZDz0exPGgnjoqhgRYLRjFZc9Q==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.25.9.tgz", + "integrity": "sha512-s5EDrE6bW97LtxOcGj1Khcx5AaXwiMmi4toFWRDP9/y0Woo6pXC+iyPu/KuhKtfSrNFd7jJB+/fkOtZy6aIC6Q==", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1843,12 +1731,12 @@ } }, "node_modules/@babel/plugin-transform-unicode-property-regex": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.23.3.tgz", - "integrity": "sha512-KcLIm+pDZkWZQAFJ9pdfmh89EwVfmNovFBcXko8szpBeF8z68kWIPeKlmSOkT9BXJxs2C0uk+5LxoxIv62MROA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.25.9.tgz", + "integrity": "sha512-Jt2d8Ga+QwRluxRQ307Vlxa6dMrYEMZCgGxoPR8V52rxPyldHu3hdlHspxaqYmE7oID5+kB+UKUB/eWS+DkkWg==", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1858,12 +1746,12 @@ } }, "node_modules/@babel/plugin-transform-unicode-regex": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.23.3.tgz", - "integrity": "sha512-wMHpNA4x2cIA32b/ci3AfwNgheiva2W0WUKWTK7vBHBhDKfPsc5cFGNWm69WBqpwd86u1qwZ9PWevKqm1A3yAw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.25.9.tgz", + "integrity": "sha512-yoxstj7Rg9dlNn9UQxzk4fcNivwv4nUYz7fYXBaKxvw/lnmPuOm/ikoELygbYq68Bls3D/D+NBPHiLwZdZZ4HA==", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1873,12 +1761,12 @@ } }, "node_modules/@babel/plugin-transform-unicode-sets-regex": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.23.3.tgz", - "integrity": "sha512-W7lliA/v9bNR83Qc3q1ip9CQMZ09CcHDbHfbLRDNuAhn1Mvkr1ZNF7hPmztMQvtTGVLJ9m8IZqWsTkXOml8dbw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.9.tgz", + "integrity": "sha512-8BYqO3GeVNHtx69fdPshN3fnzUNLrWdHhk/icSwigksJGczKSizZ+Z6SBCxTs723Fr5VSNorTIK7a+R2tISvwQ==", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1888,89 +1776,78 @@ } }, "node_modules/@babel/preset-env": { - "version": "7.23.8", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.23.8.tgz", - "integrity": "sha512-lFlpmkApLkEP6woIKprO6DO60RImpatTQKtz4sUcDjVcK8M8mQ4sZsuxaTMNOZf0sqAq/ReYW1ZBHnOQwKpLWA==", - "dependencies": { - "@babel/compat-data": "^7.23.5", - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-validator-option": "^7.23.5", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.23.3", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.23.3", - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.23.7", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.26.0.tgz", + "integrity": "sha512-H84Fxq0CQJNdPFT2DrfnylZ3cf5K43rGfWK4LJGPpjKHiZlk0/RzwEus3PDDZZg+/Er7lCA03MVacueUuXdzfw==", + "dependencies": { + "@babel/compat-data": "^7.26.0", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.25.9", + "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.25.9", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.25.9", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.25.9", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.25.9", "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-class-properties": "^7.12.13", - "@babel/plugin-syntax-class-static-block": "^7.14.5", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-import-assertions": "^7.23.3", - "@babel/plugin-syntax-import-attributes": "^7.23.3", - "@babel/plugin-syntax-import-meta": "^7.10.4", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5", - "@babel/plugin-syntax-top-level-await": "^7.14.5", + "@babel/plugin-syntax-import-assertions": "^7.26.0", + "@babel/plugin-syntax-import-attributes": "^7.26.0", "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", - "@babel/plugin-transform-arrow-functions": "^7.23.3", - "@babel/plugin-transform-async-generator-functions": "^7.23.7", - "@babel/plugin-transform-async-to-generator": "^7.23.3", - "@babel/plugin-transform-block-scoped-functions": "^7.23.3", - "@babel/plugin-transform-block-scoping": "^7.23.4", - "@babel/plugin-transform-class-properties": "^7.23.3", - "@babel/plugin-transform-class-static-block": "^7.23.4", - "@babel/plugin-transform-classes": "^7.23.8", - "@babel/plugin-transform-computed-properties": "^7.23.3", - "@babel/plugin-transform-destructuring": "^7.23.3", - "@babel/plugin-transform-dotall-regex": "^7.23.3", - "@babel/plugin-transform-duplicate-keys": "^7.23.3", - "@babel/plugin-transform-dynamic-import": "^7.23.4", - "@babel/plugin-transform-exponentiation-operator": "^7.23.3", - "@babel/plugin-transform-export-namespace-from": "^7.23.4", - "@babel/plugin-transform-for-of": "^7.23.6", - "@babel/plugin-transform-function-name": "^7.23.3", - "@babel/plugin-transform-json-strings": "^7.23.4", - "@babel/plugin-transform-literals": "^7.23.3", - "@babel/plugin-transform-logical-assignment-operators": "^7.23.4", - "@babel/plugin-transform-member-expression-literals": "^7.23.3", - "@babel/plugin-transform-modules-amd": "^7.23.3", - "@babel/plugin-transform-modules-commonjs": "^7.23.3", - "@babel/plugin-transform-modules-systemjs": "^7.23.3", - "@babel/plugin-transform-modules-umd": "^7.23.3", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5", - "@babel/plugin-transform-new-target": "^7.23.3", - "@babel/plugin-transform-nullish-coalescing-operator": "^7.23.4", - "@babel/plugin-transform-numeric-separator": "^7.23.4", - "@babel/plugin-transform-object-rest-spread": "^7.23.4", - "@babel/plugin-transform-object-super": "^7.23.3", - "@babel/plugin-transform-optional-catch-binding": "^7.23.4", - "@babel/plugin-transform-optional-chaining": "^7.23.4", - "@babel/plugin-transform-parameters": "^7.23.3", - "@babel/plugin-transform-private-methods": "^7.23.3", - "@babel/plugin-transform-private-property-in-object": "^7.23.4", - "@babel/plugin-transform-property-literals": "^7.23.3", - "@babel/plugin-transform-regenerator": "^7.23.3", - "@babel/plugin-transform-reserved-words": "^7.23.3", - "@babel/plugin-transform-shorthand-properties": "^7.23.3", - "@babel/plugin-transform-spread": "^7.23.3", - "@babel/plugin-transform-sticky-regex": "^7.23.3", - "@babel/plugin-transform-template-literals": "^7.23.3", - "@babel/plugin-transform-typeof-symbol": "^7.23.3", - "@babel/plugin-transform-unicode-escapes": "^7.23.3", - "@babel/plugin-transform-unicode-property-regex": "^7.23.3", - "@babel/plugin-transform-unicode-regex": "^7.23.3", - "@babel/plugin-transform-unicode-sets-regex": "^7.23.3", + "@babel/plugin-transform-arrow-functions": "^7.25.9", + "@babel/plugin-transform-async-generator-functions": "^7.25.9", + "@babel/plugin-transform-async-to-generator": "^7.25.9", + "@babel/plugin-transform-block-scoped-functions": "^7.25.9", + "@babel/plugin-transform-block-scoping": "^7.25.9", + "@babel/plugin-transform-class-properties": "^7.25.9", + "@babel/plugin-transform-class-static-block": "^7.26.0", + "@babel/plugin-transform-classes": "^7.25.9", + "@babel/plugin-transform-computed-properties": "^7.25.9", + "@babel/plugin-transform-destructuring": "^7.25.9", + "@babel/plugin-transform-dotall-regex": "^7.25.9", + "@babel/plugin-transform-duplicate-keys": "^7.25.9", + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.25.9", + "@babel/plugin-transform-dynamic-import": "^7.25.9", + "@babel/plugin-transform-exponentiation-operator": "^7.25.9", + "@babel/plugin-transform-export-namespace-from": "^7.25.9", + "@babel/plugin-transform-for-of": "^7.25.9", + "@babel/plugin-transform-function-name": "^7.25.9", + "@babel/plugin-transform-json-strings": "^7.25.9", + "@babel/plugin-transform-literals": "^7.25.9", + "@babel/plugin-transform-logical-assignment-operators": "^7.25.9", + "@babel/plugin-transform-member-expression-literals": "^7.25.9", + "@babel/plugin-transform-modules-amd": "^7.25.9", + "@babel/plugin-transform-modules-commonjs": "^7.25.9", + "@babel/plugin-transform-modules-systemjs": "^7.25.9", + "@babel/plugin-transform-modules-umd": "^7.25.9", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.25.9", + "@babel/plugin-transform-new-target": "^7.25.9", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.25.9", + "@babel/plugin-transform-numeric-separator": "^7.25.9", + "@babel/plugin-transform-object-rest-spread": "^7.25.9", + "@babel/plugin-transform-object-super": "^7.25.9", + "@babel/plugin-transform-optional-catch-binding": "^7.25.9", + "@babel/plugin-transform-optional-chaining": "^7.25.9", + "@babel/plugin-transform-parameters": "^7.25.9", + "@babel/plugin-transform-private-methods": "^7.25.9", + "@babel/plugin-transform-private-property-in-object": "^7.25.9", + "@babel/plugin-transform-property-literals": "^7.25.9", + "@babel/plugin-transform-regenerator": "^7.25.9", + "@babel/plugin-transform-regexp-modifiers": "^7.26.0", + "@babel/plugin-transform-reserved-words": "^7.25.9", + "@babel/plugin-transform-shorthand-properties": "^7.25.9", + "@babel/plugin-transform-spread": "^7.25.9", + "@babel/plugin-transform-sticky-regex": "^7.25.9", + "@babel/plugin-transform-template-literals": "^7.25.9", + "@babel/plugin-transform-typeof-symbol": "^7.25.9", + "@babel/plugin-transform-unicode-escapes": "^7.25.9", + "@babel/plugin-transform-unicode-property-regex": "^7.25.9", + "@babel/plugin-transform-unicode-regex": "^7.25.9", + "@babel/plugin-transform-unicode-sets-regex": "^7.25.9", "@babel/preset-modules": "0.1.6-no-external-plugins", - "babel-plugin-polyfill-corejs2": "^0.4.7", - "babel-plugin-polyfill-corejs3": "^0.8.7", - "babel-plugin-polyfill-regenerator": "^0.5.4", - "core-js-compat": "^3.31.0", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.10.6", + "babel-plugin-polyfill-regenerator": "^0.6.1", + "core-js-compat": "^3.38.1", "semver": "^6.3.1" }, "engines": { @@ -2002,16 +1879,16 @@ } }, "node_modules/@babel/preset-react": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.23.3.tgz", - "integrity": "sha512-tbkHOS9axH6Ysf2OUEqoSZ6T3Fa2SrNH6WTWSPBboxKzdxNc9qOICeLXkNG0ZEwbQ1HY8liwOce4aN/Ceyuq6w==", + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.26.3.tgz", + "integrity": "sha512-Nl03d6T9ky516DGK2YMxrTqvnpUW63TnJMOMonj+Zae0JiPC5BC9xPMSL6L8fiSpA5vP88qfygavVQvnLp+6Cw==", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-validator-option": "^7.22.15", - "@babel/plugin-transform-react-display-name": "^7.23.3", - "@babel/plugin-transform-react-jsx": "^7.22.15", - "@babel/plugin-transform-react-jsx-development": "^7.22.5", - "@babel/plugin-transform-react-pure-annotations": "^7.23.3" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "@babel/plugin-transform-react-display-name": "^7.25.9", + "@babel/plugin-transform-react-jsx": "^7.25.9", + "@babel/plugin-transform-react-jsx-development": "^7.25.9", + "@babel/plugin-transform-react-pure-annotations": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -2021,15 +1898,15 @@ } }, "node_modules/@babel/preset-typescript": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.23.3.tgz", - "integrity": "sha512-17oIGVlqz6CchO9RFYn5U6ZpWRZIngayYCtrPRSgANSwC2V1Jb+iP74nVxzzXJte8b8BYxrL1yY96xfhTBrNNQ==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.26.0.tgz", + "integrity": "sha512-NMk1IGZ5I/oHhoXEElcm+xUnL/szL6xflkFZmoEU9xj1qSJXpiS7rsspYo92B4DRCDvZn2erT5LdsCeXAKNCkg==", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-validator-option": "^7.22.15", - "@babel/plugin-syntax-jsx": "^7.23.3", - "@babel/plugin-transform-modules-commonjs": "^7.23.3", - "@babel/plugin-transform-typescript": "^7.23.3" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "@babel/plugin-syntax-jsx": "^7.25.9", + "@babel/plugin-transform-modules-commonjs": "^7.25.9", + "@babel/plugin-transform-typescript": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -2038,15 +1915,10 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/regjsgen": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", - "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==" - }, "node_modules/@babel/runtime": { - "version": "7.23.8", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.8.tgz", - "integrity": "sha512-Y7KbAP984rn1VGMbGqKmBLio9V7y5Je9GvU4rQPCPinCyNfUcToxIXl06d59URp/F3LwinvODxab5N/G6qggkw==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz", + "integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -2055,9 +1927,9 @@ } }, "node_modules/@babel/runtime-corejs3": { - "version": "7.23.8", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.23.8.tgz", - "integrity": "sha512-2ZzmcDugdm0/YQKFVYsXiwUN7USPX8PM7cytpb4PFl87fM+qYPSvTZX//8tyeJB1j0YDmafBJEbl5f8NfLyuKw==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.26.0.tgz", + "integrity": "sha512-YXHu5lN8kJCb1LOb9PgV6pvak43X2h4HvRApcN5SdWeaItQOzfn1hgP6jasD6KWQyJDBxrVmA9o9OivlnNJK/w==", "dependencies": { "core-js-pure": "^3.30.2", "regenerator-runtime": "^0.14.0" @@ -2067,31 +1939,28 @@ } }, "node_modules/@babel/template": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", - "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz", + "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==", "dependencies": { - "@babel/code-frame": "^7.22.13", - "@babel/parser": "^7.22.15", - "@babel/types": "^7.22.15" + "@babel/code-frame": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.23.7", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.7.tgz", - "integrity": "sha512-tY3mM8rH9jM0YHFGyfC0/xf+SB5eKUu7HPj7/k3fpi9dAlsMc5YbQvDi0Sh2QTPXqMhyaAtzAr807TIyfQrmyg==", - "dependencies": { - "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.6", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.23.6", - "@babel/types": "^7.23.6", + "version": "7.26.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.4.tgz", + "integrity": "sha512-fH+b7Y4p3yqvApJALCPJcwb0/XaOSgtK4pzV6WVjPR5GLFQBRI7pfoX2V2iM48NXvX07NUxxm1Vw98YjqTcU5w==", + "dependencies": { + "@babel/code-frame": "^7.26.2", + "@babel/generator": "^7.26.3", + "@babel/parser": "^7.26.3", + "@babel/template": "^7.25.9", + "@babel/types": "^7.26.3", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -2100,22 +1969,55 @@ } }, "node_modules/@babel/types": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.6.tgz", - "integrity": "sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==", + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.3.tgz", + "integrity": "sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA==", "dependencies": { - "@babel/helper-string-parser": "^7.23.4", - "@babel/helper-validator-identifier": "^7.22.20", - "to-fast-properties": "^2.0.0" + "@babel/helper-string-parser": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@braintree/sanitize-url": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-6.0.4.tgz", - "integrity": "sha512-s3jaWicZd0pkP0jf5ysyHUI/RE7MHos6qlToFcGWXVp+ykHOy77OUMrfbgJ9it2C5bow7OIQwYYaHjk9XlBQ2A==" + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-7.1.0.tgz", + "integrity": "sha512-o+UlMLt49RvtCASlOMW0AkHnabN9wR9rwCCherxO0yG4Npy34GkvrAqdXQvrhNs+jh+gkK8gB8Lf05qL/O7KWg==" + }, + "node_modules/@chevrotain/cst-dts-gen": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@chevrotain/cst-dts-gen/-/cst-dts-gen-11.0.3.tgz", + "integrity": "sha512-BvIKpRLeS/8UbfxXxgC33xOumsacaeCKAjAeLyOn7Pcp95HiRbrpl14S+9vaZLolnbssPIUuiUd8IvgkRyt6NQ==", + "dependencies": { + "@chevrotain/gast": "11.0.3", + "@chevrotain/types": "11.0.3", + "lodash-es": "4.17.21" + } + }, + "node_modules/@chevrotain/gast": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@chevrotain/gast/-/gast-11.0.3.tgz", + "integrity": "sha512-+qNfcoNk70PyS/uxmj3li5NiECO+2YKZZQMbmjTqRI3Qchu8Hig/Q9vgkHpI3alNjr7M+a2St5pw5w5F6NL5/Q==", + "dependencies": { + "@chevrotain/types": "11.0.3", + "lodash-es": "4.17.21" + } + }, + "node_modules/@chevrotain/regexp-to-ast": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@chevrotain/regexp-to-ast/-/regexp-to-ast-11.0.3.tgz", + "integrity": "sha512-1fMHaBZxLFvWI067AVbGJav1eRY7N8DDvYCTwGBiE/ytKBgP8azTdgyrKyWZ9Mfh09eHWb5PgTSO8wi7U824RA==" + }, + "node_modules/@chevrotain/types": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@chevrotain/types/-/types-11.0.3.tgz", + "integrity": "sha512-gsiM3G8b58kZC2HaWR50gu6Y1440cHiJ+i3JUvcp/35JchYejb2+5MVeJK0iKThYpAa/P2PYFV4hoi44HD+aHQ==" + }, + "node_modules/@chevrotain/utils": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@chevrotain/utils/-/utils-11.0.3.tgz", + "integrity": "sha512-YslZMgtJUyuMbZ+aKvfF3x1f5liK4mWNxghFRv7jqRR9C3R3fAOGTTKvxXDa2Y1s9zSbcpuO0cAxDYsc9SrXoQ==" }, "node_modules/@colors/colors": { "version": "1.5.0", @@ -2126,1574 +2028,2978 @@ "node": ">=0.1.90" } }, - "node_modules/@discoveryjs/json-ext": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", - "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", + "node_modules/@csstools/cascade-layer-name-parser": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@csstools/cascade-layer-name-parser/-/cascade-layer-name-parser-2.0.4.tgz", + "integrity": "sha512-7DFHlPuIxviKYZrOiwVU/PiHLm3lLUR23OMuEEtfEOQTOp9hzQ2JjdY6X5H18RVuUPJqSCI+qNnD5iOLMVE0bA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/@docsearch/css": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.5.2.tgz", - "integrity": "sha512-SPiDHaWKQZpwR2siD0KQUwlStvIAnEyK6tAE2h2Wuoq8ue9skzhlyVQ1ddzOxX6khULnAALDiR/isSF3bnuciA==" - }, - "node_modules/@docsearch/react": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.5.2.tgz", - "integrity": "sha512-9Ahcrs5z2jq/DcAvYtvlqEBHImbm4YJI8M9y0x6Tqg598P40HTEkX7hsMcIuThI+hTFxRGZ9hll0Wygm2yEjng==", - "dependencies": { - "@algolia/autocomplete-core": "1.9.3", - "@algolia/autocomplete-preset-algolia": "1.9.3", - "@docsearch/css": "3.5.2", - "algoliasearch": "^4.19.1" + "node": ">=18" }, "peerDependencies": { - "@types/react": ">= 16.8.0 < 19.0.0", - "react": ">= 16.8.0 < 19.0.0", - "react-dom": ">= 16.8.0 < 19.0.0", - "search-insights": ">= 1 < 3" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "react": { - "optional": true + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3" + } + }, + "node_modules/@csstools/color-helpers": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.0.1.tgz", + "integrity": "sha512-MKtmkA0BX87PKaO1NFRTFH+UnkgnmySQOvNxJubsadusqPEC2aJ9MOQiMceZJJ6oitUl/i0L6u0M1IrmAOmgBA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" }, - "react-dom": { - "optional": true + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@csstools/css-calc": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.0.tgz", + "integrity": "sha512-X69PmFOrjTZfN5ijxtI8hZ9kRADFSLrmmQ6hgDJ272Il049WGKpDY64KhrFm/7rbWve0z81QepawzjkKlqkNGw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" }, - "search-insights": { - "optional": true + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" } + ], + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3" } }, - "node_modules/@docusaurus/core": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@docusaurus/core/-/core-3.1.1.tgz", - "integrity": "sha512-2nQfKFcf+MLEM7JXsXwQxPOmQAR6ytKMZVSx7tVi9HEm9WtfwBH1fp6bn8Gj4zLUhjWKCLoysQ9/Wm+EZCQ4yQ==", - "dependencies": { - "@babel/core": "^7.23.3", - "@babel/generator": "^7.23.3", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-transform-runtime": "^7.22.9", - "@babel/preset-env": "^7.22.9", - "@babel/preset-react": "^7.22.5", - "@babel/preset-typescript": "^7.22.5", - "@babel/runtime": "^7.22.6", - "@babel/runtime-corejs3": "^7.22.6", - "@babel/traverse": "^7.22.8", - "@docusaurus/cssnano-preset": "3.1.1", - "@docusaurus/logger": "3.1.1", - "@docusaurus/mdx-loader": "3.1.1", - "@docusaurus/react-loadable": "5.5.2", - "@docusaurus/utils": "3.1.1", - "@docusaurus/utils-common": "3.1.1", - "@docusaurus/utils-validation": "3.1.1", - "@slorber/static-site-generator-webpack-plugin": "^4.0.7", - "@svgr/webpack": "^6.5.1", - "autoprefixer": "^10.4.14", - "babel-loader": "^9.1.3", - "babel-plugin-dynamic-import-node": "^2.3.3", - "boxen": "^6.2.1", - "chalk": "^4.1.2", - "chokidar": "^3.5.3", - "clean-css": "^5.3.2", - "cli-table3": "^0.6.3", - "combine-promises": "^1.1.0", - "commander": "^5.1.0", - "copy-webpack-plugin": "^11.0.0", - "core-js": "^3.31.1", - "css-loader": "^6.8.1", - "css-minimizer-webpack-plugin": "^4.2.2", - "cssnano": "^5.1.15", - "del": "^6.1.1", - "detect-port": "^1.5.1", - "escape-html": "^1.0.3", - "eta": "^2.2.0", - "file-loader": "^6.2.0", - "fs-extra": "^11.1.1", - "html-minifier-terser": "^7.2.0", - "html-tags": "^3.3.1", - "html-webpack-plugin": "^5.5.3", - "leven": "^3.1.0", - "lodash": "^4.17.21", - "mini-css-extract-plugin": "^2.7.6", - "postcss": "^8.4.26", - "postcss-loader": "^7.3.3", - "prompts": "^2.4.2", - "react-dev-utils": "^12.0.1", - "react-helmet-async": "^1.3.0", - "react-loadable": "npm:@docusaurus/react-loadable@5.5.2", - "react-loadable-ssr-addon-v5-slorber": "^1.0.1", - "react-router": "^5.3.4", - "react-router-config": "^5.1.1", - "react-router-dom": "^5.3.4", - "rtl-detect": "^1.0.4", - "semver": "^7.5.4", - "serve-handler": "^6.1.5", - "shelljs": "^0.8.5", - "terser-webpack-plugin": "^5.3.9", - "tslib": "^2.6.0", - "update-notifier": "^6.0.2", - "url-loader": "^4.1.1", - "webpack": "^5.88.1", - "webpack-bundle-analyzer": "^4.9.0", - "webpack-dev-server": "^4.15.1", - "webpack-merge": "^5.9.0", - "webpackbar": "^5.0.2" - }, - "bin": { - "docusaurus": "bin/docusaurus.mjs" + "node_modules/@csstools/css-color-parser": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.0.6.tgz", + "integrity": "sha512-S/IjXqTHdpI4EtzGoNCHfqraXF37x12ZZHA1Lk7zoT5pm2lMjFuqhX/89L7dqX4CcMacKK+6ZCs5TmEGb/+wKw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "@csstools/color-helpers": "^5.0.1", + "@csstools/css-calc": "^2.1.0" }, "engines": { - "node": ">=18.0" + "node": ">=18" }, "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3" } }, - "node_modules/@docusaurus/cssnano-preset": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@docusaurus/cssnano-preset/-/cssnano-preset-3.1.1.tgz", - "integrity": "sha512-LnoIDjJWbirdbVZDMq+4hwmrTl2yHDnBf9MLG9qyExeAE3ac35s4yUhJI8yyTCdixzNfKit4cbXblzzqMu4+8g==", - "dependencies": { - "cssnano-preset-advanced": "^5.3.10", - "postcss": "^8.4.26", - "postcss-sort-media-queries": "^4.4.1", - "tslib": "^2.6.0" - }, + "node_modules/@csstools/css-parser-algorithms": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.4.tgz", + "integrity": "sha512-Up7rBoV77rv29d3uKHUIVubz1BTcgyUK72IvCQAbfbMv584xHcGKCKbWh7i8hPrRJ7qU4Y8IO3IY9m+iTB7P3A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "engines": { - "node": ">=18.0" + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-tokenizer": "^3.0.3" } }, - "node_modules/@docusaurus/logger": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@docusaurus/logger/-/logger-3.1.1.tgz", - "integrity": "sha512-BjkNDpQzewcTnST8trx4idSoAla6zZ3w22NqM/UMcFtvYJgmoE4layuTzlfql3VFPNuivvj7BOExa/+21y4X2Q==", - "dependencies": { - "chalk": "^4.1.2", - "tslib": "^2.6.0" - }, + "node_modules/@csstools/css-tokenizer": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.3.tgz", + "integrity": "sha512-UJnjoFsmxfKUdNYdWgOB0mWUypuLvAfQPH1+pyvRJs6euowbFkFC6P13w1l8mJyi3vxYMxc9kld5jZEGRQs6bw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "engines": { - "node": ">=18.0" + "node": ">=18" } }, - "node_modules/@docusaurus/mdx-loader": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@docusaurus/mdx-loader/-/mdx-loader-3.1.1.tgz", - "integrity": "sha512-xN2IccH9+sv7TmxwsDJNS97BHdmlqWwho+kIVY4tcCXkp+k4QuzvWBeunIMzeayY4Fu13A6sAjHGv5qm72KyGA==", - "dependencies": { - "@babel/parser": "^7.22.7", - "@babel/traverse": "^7.22.8", - "@docusaurus/logger": "3.1.1", - "@docusaurus/utils": "3.1.1", - "@docusaurus/utils-validation": "3.1.1", - "@mdx-js/mdx": "^3.0.0", - "@slorber/remark-comment": "^1.0.0", - "escape-html": "^1.0.3", - "estree-util-value-to-estree": "^3.0.1", - "file-loader": "^6.2.0", - "fs-extra": "^11.1.1", - "image-size": "^1.0.2", - "mdast-util-mdx": "^3.0.0", - "mdast-util-to-string": "^4.0.0", - "rehype-raw": "^7.0.0", - "remark-directive": "^3.0.0", - "remark-emoji": "^4.0.0", - "remark-frontmatter": "^5.0.0", - "remark-gfm": "^4.0.0", - "stringify-object": "^3.3.0", - "tslib": "^2.6.0", - "unified": "^11.0.3", - "unist-util-visit": "^5.0.0", - "url-loader": "^4.1.1", - "vfile": "^6.0.1", - "webpack": "^5.88.1" - }, + "node_modules/@csstools/media-query-list-parser": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-4.0.2.tgz", + "integrity": "sha512-EUos465uvVvMJehckATTlNqGj4UJWkTmdWuDMjqvSUkjGpmOyFZBVwb4knxCm/k2GMTXY+c/5RkdndzFYWeX5A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "engines": { - "node": ">=18.0" + "node": ">=18" }, "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3" } }, - "node_modules/@docusaurus/module-type-aliases": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@docusaurus/module-type-aliases/-/module-type-aliases-3.1.1.tgz", - "integrity": "sha512-xBJyx0TMfAfVZ9ZeIOb1awdXgR4YJMocIEzTps91rq+hJDFJgJaylDtmoRhUxkwuYmNK1GJpW95b7DLztSBJ3A==", + "node_modules/@csstools/postcss-cascade-layers": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-cascade-layers/-/postcss-cascade-layers-5.0.1.tgz", + "integrity": "sha512-XOfhI7GShVcKiKwmPAnWSqd2tBR0uxt+runAxttbSp/LY2U16yAVPmAf7e9q4JJ0d+xMNmpwNDLBXnmRCl3HMQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "dependencies": { - "@docusaurus/react-loadable": "5.5.2", - "@docusaurus/types": "3.1.1", - "@types/history": "^4.7.11", - "@types/react": "*", - "@types/react-router-config": "*", - "@types/react-router-dom": "*", - "react-helmet-async": "*", - "react-loadable": "npm:@docusaurus/react-loadable@5.5.2" - }, - "peerDependencies": { - "react": "*", - "react-dom": "*" - } - }, - "node_modules/@docusaurus/plugin-content-blog": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-blog/-/plugin-content-blog-3.1.1.tgz", - "integrity": "sha512-ew/3VtVoG3emoAKmoZl7oKe1zdFOsI0NbcHS26kIxt2Z8vcXKCUgK9jJJrz0TbOipyETPhqwq4nbitrY3baibg==", - "dependencies": { - "@docusaurus/core": "3.1.1", - "@docusaurus/logger": "3.1.1", - "@docusaurus/mdx-loader": "3.1.1", - "@docusaurus/types": "3.1.1", - "@docusaurus/utils": "3.1.1", - "@docusaurus/utils-common": "3.1.1", - "@docusaurus/utils-validation": "3.1.1", - "cheerio": "^1.0.0-rc.12", - "feed": "^4.2.2", - "fs-extra": "^11.1.1", - "lodash": "^4.17.21", - "reading-time": "^1.5.0", - "srcset": "^4.0.0", - "tslib": "^2.6.0", - "unist-util-visit": "^5.0.0", - "utility-types": "^3.10.0", - "webpack": "^5.88.1" + "@csstools/selector-specificity": "^5.0.0", + "postcss-selector-parser": "^7.0.0" }, "engines": { - "node": ">=18.0" + "node": ">=18" }, "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" + "postcss": "^8.4" } }, - "node_modules/@docusaurus/plugin-content-docs": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-docs/-/plugin-content-docs-3.1.1.tgz", - "integrity": "sha512-lhFq4E874zw0UOH7ujzxnCayOyAt0f9YPVYSb9ohxrdCM8B4szxitUw9rIX4V9JLLHVoqIJb6k+lJJ1jrcGJ0A==", - "dependencies": { - "@docusaurus/core": "3.1.1", - "@docusaurus/logger": "3.1.1", - "@docusaurus/mdx-loader": "3.1.1", - "@docusaurus/module-type-aliases": "3.1.1", - "@docusaurus/types": "3.1.1", - "@docusaurus/utils": "3.1.1", - "@docusaurus/utils-validation": "3.1.1", - "@types/react-router-config": "^5.0.7", - "combine-promises": "^1.1.0", - "fs-extra": "^11.1.1", - "js-yaml": "^4.1.0", - "lodash": "^4.17.21", - "tslib": "^2.6.0", - "utility-types": "^3.10.0", - "webpack": "^5.88.1" - }, + "node_modules/@csstools/postcss-cascade-layers/node_modules/@csstools/selector-specificity": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-5.0.0.tgz", + "integrity": "sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "engines": { - "node": ">=18.0" + "node": ">=18" }, "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" + "postcss-selector-parser": "^7.0.0" } }, - "node_modules/@docusaurus/plugin-content-pages": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-pages/-/plugin-content-pages-3.1.1.tgz", - "integrity": "sha512-NQHncNRAJbyLtgTim9GlEnNYsFhuCxaCNkMwikuxLTiGIPH7r/jpb7O3f3jUMYMebZZZrDq5S7om9a6rvB/YCA==", - "dependencies": { - "@docusaurus/core": "3.1.1", - "@docusaurus/mdx-loader": "3.1.1", - "@docusaurus/types": "3.1.1", - "@docusaurus/utils": "3.1.1", - "@docusaurus/utils-validation": "3.1.1", - "fs-extra": "^11.1.1", - "tslib": "^2.6.0", - "webpack": "^5.88.1" + "node_modules/@csstools/postcss-cascade-layers/node_modules/postcss-selector-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz", + "integrity": "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" }, "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" + "node": ">=4" } }, - "node_modules/@docusaurus/plugin-debug": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-debug/-/plugin-debug-3.1.1.tgz", - "integrity": "sha512-xWeMkueM9wE/8LVvl4+Qf1WqwXmreMjI5Kgr7GYCDoJ8zu4kD+KaMhrh7py7MNM38IFvU1RfrGKacCEe2DRRfQ==", + "node_modules/@csstools/postcss-color-function": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@csstools/postcss-color-function/-/postcss-color-function-4.0.6.tgz", + "integrity": "sha512-EcvXfC60cTIumzpsxWuvVjb7rsJEHPvqn3jeMEBUaE3JSc4FRuP7mEQ+1eicxWmIrs3FtzMH9gR3sgA5TH+ebQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "dependencies": { - "@docusaurus/core": "3.1.1", - "@docusaurus/types": "3.1.1", - "@docusaurus/utils": "3.1.1", - "fs-extra": "^11.1.1", - "react-json-view-lite": "^1.2.0", - "tslib": "^2.6.0" + "@csstools/css-color-parser": "^3.0.6", + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3", + "@csstools/postcss-progressive-custom-properties": "^4.0.0", + "@csstools/utilities": "^2.0.0" }, "engines": { - "node": ">=18.0" + "node": ">=18" }, "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" + "postcss": "^8.4" } }, - "node_modules/@docusaurus/plugin-google-analytics": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-analytics/-/plugin-google-analytics-3.1.1.tgz", - "integrity": "sha512-+q2UpWTqVi8GdlLoSlD5bS/YpxW+QMoBwrPrUH/NpvpuOi0Of7MTotsQf9JWd3hymZxl2uu1o3PIrbpxfeDFDQ==", + "node_modules/@csstools/postcss-color-mix-function": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@csstools/postcss-color-mix-function/-/postcss-color-mix-function-3.0.6.tgz", + "integrity": "sha512-jVKdJn4+JkASYGhyPO+Wa5WXSx1+oUgaXb3JsjJn/BlrtFh5zjocCY7pwWi0nuP24V1fY7glQsxEYcYNy0dMFg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "dependencies": { - "@docusaurus/core": "3.1.1", - "@docusaurus/types": "3.1.1", - "@docusaurus/utils-validation": "3.1.1", - "tslib": "^2.6.0" + "@csstools/css-color-parser": "^3.0.6", + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3", + "@csstools/postcss-progressive-custom-properties": "^4.0.0", + "@csstools/utilities": "^2.0.0" }, "engines": { - "node": ">=18.0" + "node": ">=18" }, "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" + "postcss": "^8.4" } }, - "node_modules/@docusaurus/plugin-google-gtag": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-gtag/-/plugin-google-gtag-3.1.1.tgz", - "integrity": "sha512-0mMPiBBlQ5LFHTtjxuvt/6yzh8v7OxLi3CbeEsxXZpUzcKO/GC7UA1VOWUoBeQzQL508J12HTAlR3IBU9OofSw==", + "node_modules/@csstools/postcss-content-alt-text": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@csstools/postcss-content-alt-text/-/postcss-content-alt-text-2.0.4.tgz", + "integrity": "sha512-YItlZUOuZJCBlRaCf8Aucc1lgN41qYGALMly0qQllrxYJhiyzlI6RxOTMUvtWk+KhS8GphMDsDhKQ7KTPfEMSw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "dependencies": { - "@docusaurus/core": "3.1.1", - "@docusaurus/types": "3.1.1", - "@docusaurus/utils-validation": "3.1.1", - "@types/gtag.js": "^0.0.12", - "tslib": "^2.6.0" + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3", + "@csstools/postcss-progressive-custom-properties": "^4.0.0", + "@csstools/utilities": "^2.0.0" }, "engines": { - "node": ">=18.0" + "node": ">=18" }, "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" + "postcss": "^8.4" } }, - "node_modules/@docusaurus/plugin-google-tag-manager": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-tag-manager/-/plugin-google-tag-manager-3.1.1.tgz", - "integrity": "sha512-d07bsrMLdDIryDtY17DgqYUbjkswZQr8cLWl4tzXrt5OR/T/zxC1SYKajzB3fd87zTu5W5klV5GmUwcNSMXQXA==", - "dependencies": { - "@docusaurus/core": "3.1.1", - "@docusaurus/types": "3.1.1", - "@docusaurus/utils-validation": "3.1.1", - "tslib": "^2.6.0" + "node_modules/@csstools/postcss-exponential-functions": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@csstools/postcss-exponential-functions/-/postcss-exponential-functions-2.0.5.tgz", + "integrity": "sha512-mi8R6dVfA2nDoKM3wcEi64I8vOYEgQVtVKCfmLHXupeLpACfGAided5ddMt5f+CnEodNu4DifuVwb0I6fQDGGQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "@csstools/css-calc": "^2.1.0", + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3" }, "engines": { - "node": ">=18.0" + "node": ">=18" }, "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" + "postcss": "^8.4" } }, - "node_modules/@docusaurus/plugin-sitemap": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-sitemap/-/plugin-sitemap-3.1.1.tgz", - "integrity": "sha512-iJ4hCaMmDaUqRv131XJdt/C/jJQx8UreDWTRqZKtNydvZVh/o4yXGRRFOplea1D9b/zpwL1Y+ZDwX7xMhIOTmg==", - "dependencies": { - "@docusaurus/core": "3.1.1", - "@docusaurus/logger": "3.1.1", - "@docusaurus/types": "3.1.1", - "@docusaurus/utils": "3.1.1", - "@docusaurus/utils-common": "3.1.1", - "@docusaurus/utils-validation": "3.1.1", - "fs-extra": "^11.1.1", - "sitemap": "^7.1.1", - "tslib": "^2.6.0" + "node_modules/@csstools/postcss-font-format-keywords": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-font-format-keywords/-/postcss-font-format-keywords-4.0.0.tgz", + "integrity": "sha512-usBzw9aCRDvchpok6C+4TXC57btc4bJtmKQWOHQxOVKen1ZfVqBUuCZ/wuqdX5GHsD0NRSr9XTP+5ID1ZZQBXw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "@csstools/utilities": "^2.0.0", + "postcss-value-parser": "^4.2.0" }, "engines": { - "node": ">=18.0" + "node": ">=18" }, "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" + "postcss": "^8.4" } }, - "node_modules/@docusaurus/preset-classic": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@docusaurus/preset-classic/-/preset-classic-3.1.1.tgz", - "integrity": "sha512-jG4ys/hWYf69iaN/xOmF+3kjs4Nnz1Ay3CjFLDtYa8KdxbmUhArA9HmP26ru5N0wbVWhY+6kmpYhTJpez5wTyg==", - "dependencies": { - "@docusaurus/core": "3.1.1", - "@docusaurus/plugin-content-blog": "3.1.1", - "@docusaurus/plugin-content-docs": "3.1.1", - "@docusaurus/plugin-content-pages": "3.1.1", - "@docusaurus/plugin-debug": "3.1.1", - "@docusaurus/plugin-google-analytics": "3.1.1", - "@docusaurus/plugin-google-gtag": "3.1.1", - "@docusaurus/plugin-google-tag-manager": "3.1.1", - "@docusaurus/plugin-sitemap": "3.1.1", - "@docusaurus/theme-classic": "3.1.1", - "@docusaurus/theme-common": "3.1.1", - "@docusaurus/theme-search-algolia": "3.1.1", - "@docusaurus/types": "3.1.1" + "node_modules/@csstools/postcss-gamut-mapping": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@csstools/postcss-gamut-mapping/-/postcss-gamut-mapping-2.0.6.tgz", + "integrity": "sha512-0ke7fmXfc8H+kysZz246yjirAH6JFhyX9GTlyRnM0exHO80XcA9zeJpy5pOp5zo/AZiC/q5Pf+Hw7Pd6/uAoYA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "@csstools/css-color-parser": "^3.0.6", + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3" }, "engines": { - "node": ">=18.0" + "node": ">=18" }, "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" + "postcss": "^8.4" } }, - "node_modules/@docusaurus/react-loadable": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/react-loadable/-/react-loadable-5.5.2.tgz", - "integrity": "sha512-A3dYjdBGuy0IGT+wyLIGIKLRE+sAk1iNk0f1HjNDysO7u8lhL4N3VEm+FAubmJbAztn94F7MxBTPmnixbiyFdQ==", + "node_modules/@csstools/postcss-gradients-interpolation-method": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/@csstools/postcss-gradients-interpolation-method/-/postcss-gradients-interpolation-method-5.0.6.tgz", + "integrity": "sha512-Itrbx6SLUzsZ6Mz3VuOlxhbfuyLTogG5DwEF1V8dAi24iMuvQPIHd7Ti+pNDp7j6WixndJGZaoNR0f9VSzwuTg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "dependencies": { - "@types/react": "*", - "prop-types": "^15.6.2" + "@csstools/css-color-parser": "^3.0.6", + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3", + "@csstools/postcss-progressive-custom-properties": "^4.0.0", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" }, "peerDependencies": { - "react": "*" + "postcss": "^8.4" } }, - "node_modules/@docusaurus/theme-classic": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-classic/-/theme-classic-3.1.1.tgz", - "integrity": "sha512-GiPE/jbWM8Qv1A14lk6s9fhc0LhPEQ00eIczRO4QL2nAQJZXkjPG6zaVx+1cZxPFWbAsqSjKe2lqkwF3fGkQ7Q==", - "dependencies": { - "@docusaurus/core": "3.1.1", - "@docusaurus/mdx-loader": "3.1.1", - "@docusaurus/module-type-aliases": "3.1.1", - "@docusaurus/plugin-content-blog": "3.1.1", - "@docusaurus/plugin-content-docs": "3.1.1", - "@docusaurus/plugin-content-pages": "3.1.1", - "@docusaurus/theme-common": "3.1.1", - "@docusaurus/theme-translations": "3.1.1", - "@docusaurus/types": "3.1.1", - "@docusaurus/utils": "3.1.1", - "@docusaurus/utils-common": "3.1.1", - "@docusaurus/utils-validation": "3.1.1", - "@mdx-js/react": "^3.0.0", - "clsx": "^2.0.0", - "copy-text-to-clipboard": "^3.2.0", - "infima": "0.2.0-alpha.43", - "lodash": "^4.17.21", - "nprogress": "^0.2.0", - "postcss": "^8.4.26", - "prism-react-renderer": "^2.3.0", - "prismjs": "^1.29.0", - "react-router-dom": "^5.3.4", - "rtlcss": "^4.1.0", - "tslib": "^2.6.0", - "utility-types": "^3.10.0" + "node_modules/@csstools/postcss-hwb-function": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@csstools/postcss-hwb-function/-/postcss-hwb-function-4.0.6.tgz", + "integrity": "sha512-927Pqy3a1uBP7U8sTfaNdZVB0mNXzIrJO/GZ8us9219q9n06gOqCdfZ0E6d1P66Fm0fYHvxfDbfcUuwAn5UwhQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "@csstools/css-color-parser": "^3.0.6", + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3", + "@csstools/postcss-progressive-custom-properties": "^4.0.0", + "@csstools/utilities": "^2.0.0" }, "engines": { - "node": ">=18.0" + "node": ">=18" }, "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" + "postcss": "^8.4" } }, - "node_modules/@docusaurus/theme-common": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-common/-/theme-common-3.1.1.tgz", - "integrity": "sha512-38urZfeMhN70YaXkwIGXmcUcv2CEYK/2l4b05GkJPrbEbgpsIZM3Xc+Js2ehBGGZmfZq8GjjQ5RNQYG+MYzCYg==", - "dependencies": { - "@docusaurus/mdx-loader": "3.1.1", - "@docusaurus/module-type-aliases": "3.1.1", - "@docusaurus/plugin-content-blog": "3.1.1", - "@docusaurus/plugin-content-docs": "3.1.1", - "@docusaurus/plugin-content-pages": "3.1.1", - "@docusaurus/utils": "3.1.1", - "@docusaurus/utils-common": "3.1.1", - "@types/history": "^4.7.11", - "@types/react": "*", - "@types/react-router-config": "*", - "clsx": "^2.0.0", - "parse-numeric-range": "^1.3.0", - "prism-react-renderer": "^2.3.0", - "tslib": "^2.6.0", - "utility-types": "^3.10.0" + "node_modules/@csstools/postcss-ic-unit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-ic-unit/-/postcss-ic-unit-4.0.0.tgz", + "integrity": "sha512-9QT5TDGgx7wD3EEMN3BSUG6ckb6Eh5gSPT5kZoVtUuAonfPmLDJyPhqR4ntPpMYhUKAMVKAg3I/AgzqHMSeLhA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "@csstools/postcss-progressive-custom-properties": "^4.0.0", + "@csstools/utilities": "^2.0.0", + "postcss-value-parser": "^4.2.0" }, "engines": { - "node": ">=18.0" + "node": ">=18" }, "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" + "postcss": "^8.4" } }, - "node_modules/@docusaurus/theme-mermaid": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-mermaid/-/theme-mermaid-3.1.1.tgz", - "integrity": "sha512-O6u9/7QX/ZapV4HJJSzNs0Jir1KA/LRLORWYeDvbGswqZNusj6q4iLELrKIClysJ3PB3zWUzyKtI/wjIKiV1vA==", - "dependencies": { - "@docusaurus/core": "3.1.1", - "@docusaurus/module-type-aliases": "3.1.1", - "@docusaurus/theme-common": "3.1.1", - "@docusaurus/types": "3.1.1", - "@docusaurus/utils-validation": "3.1.1", - "mermaid": "^10.4.0", - "tslib": "^2.6.0" - }, + "node_modules/@csstools/postcss-initial": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-initial/-/postcss-initial-2.0.0.tgz", + "integrity": "sha512-dv2lNUKR+JV+OOhZm9paWzYBXOCi+rJPqJ2cJuhh9xd8USVrd0cBEPczla81HNOyThMQWeCcdln3gZkQV2kYxA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "engines": { - "node": ">=18.0" + "node": ">=18" }, "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" + "postcss": "^8.4" } }, - "node_modules/@docusaurus/theme-search-algolia": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-search-algolia/-/theme-search-algolia-3.1.1.tgz", - "integrity": "sha512-tBH9VY5EpRctVdaAhT+b1BY8y5dyHVZGFXyCHgTrvcXQy5CV4q7serEX7U3SveNT9zksmchPyct6i1sFDC4Z5g==", + "node_modules/@csstools/postcss-is-pseudo-class": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-is-pseudo-class/-/postcss-is-pseudo-class-5.0.1.tgz", + "integrity": "sha512-JLp3POui4S1auhDR0n8wHd/zTOWmMsmK3nQd3hhL6FhWPaox5W7j1se6zXOG/aP07wV2ww0lxbKYGwbBszOtfQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "dependencies": { - "@docsearch/react": "^3.5.2", - "@docusaurus/core": "3.1.1", - "@docusaurus/logger": "3.1.1", - "@docusaurus/plugin-content-docs": "3.1.1", - "@docusaurus/theme-common": "3.1.1", - "@docusaurus/theme-translations": "3.1.1", - "@docusaurus/utils": "3.1.1", - "@docusaurus/utils-validation": "3.1.1", - "algoliasearch": "^4.18.0", - "algoliasearch-helper": "^3.13.3", - "clsx": "^2.0.0", - "eta": "^2.2.0", - "fs-extra": "^11.1.1", - "lodash": "^4.17.21", - "tslib": "^2.6.0", - "utility-types": "^3.10.0" + "@csstools/selector-specificity": "^5.0.0", + "postcss-selector-parser": "^7.0.0" }, "engines": { - "node": ">=18.0" + "node": ">=18" }, "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" + "postcss": "^8.4" } }, - "node_modules/@docusaurus/theme-translations": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-translations/-/theme-translations-3.1.1.tgz", - "integrity": "sha512-xvWQFwjxHphpJq5fgk37FXCDdAa2o+r7FX8IpMg+bGZBNXyWBu3MjZ+G4+eUVNpDhVinTc+j6ucL0Ain5KCGrg==", - "dependencies": { - "fs-extra": "^11.1.1", - "tslib": "^2.6.0" - }, + "node_modules/@csstools/postcss-is-pseudo-class/node_modules/@csstools/selector-specificity": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-5.0.0.tgz", + "integrity": "sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "engines": { - "node": ">=18.0" + "node": ">=18" + }, + "peerDependencies": { + "postcss-selector-parser": "^7.0.0" } }, - "node_modules/@docusaurus/tsconfig": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@docusaurus/tsconfig/-/tsconfig-3.1.1.tgz", - "integrity": "sha512-FTBuY3KvaHfMVBgvlPmDQ+KS9Q/bYtVftq2ugou3PgBDJoQmw2aUZ4Sg15HKqLGbfIkxoy9t6cqE4Yw1Ta8Q1A==", - "dev": true - }, - "node_modules/@docusaurus/types": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-3.1.1.tgz", - "integrity": "sha512-grBqOLnubUecgKFXN9q3uit2HFbCxTWX4Fam3ZFbMN0sWX9wOcDoA7lwdX/8AmeL20Oc4kQvWVgNrsT8bKRvzg==", + "node_modules/@csstools/postcss-is-pseudo-class/node_modules/postcss-selector-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz", + "integrity": "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==", "dependencies": { - "@mdx-js/mdx": "^3.0.0", - "@types/history": "^4.7.11", - "@types/react": "*", - "commander": "^5.1.0", - "joi": "^17.9.2", - "react-helmet-async": "^1.3.0", - "utility-types": "^3.10.0", - "webpack": "^5.88.1", - "webpack-merge": "^5.9.0" + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" + "engines": { + "node": ">=4" } }, - "node_modules/@docusaurus/utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@docusaurus/utils/-/utils-3.1.1.tgz", - "integrity": "sha512-ZJfJa5cJQtRYtqijsPEnAZoduW6sjAQ7ZCWSZavLcV10Fw0Z3gSaPKA/B4micvj2afRZ4gZxT7KfYqe5H8Cetg==", + "node_modules/@csstools/postcss-light-dark-function": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@csstools/postcss-light-dark-function/-/postcss-light-dark-function-2.0.7.tgz", + "integrity": "sha512-ZZ0rwlanYKOHekyIPaU+sVm3BEHCe+Ha0/px+bmHe62n0Uc1lL34vbwrLYn6ote8PHlsqzKeTQdIejQCJ05tfw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "dependencies": { - "@docusaurus/logger": "3.1.1", - "@svgr/webpack": "^6.5.1", - "escape-string-regexp": "^4.0.0", - "file-loader": "^6.2.0", - "fs-extra": "^11.1.1", - "github-slugger": "^1.5.0", - "globby": "^11.1.0", - "gray-matter": "^4.0.3", - "jiti": "^1.20.0", - "js-yaml": "^4.1.0", - "lodash": "^4.17.21", - "micromatch": "^4.0.5", - "resolve-pathname": "^3.0.0", - "shelljs": "^0.8.5", - "tslib": "^2.6.0", - "url-loader": "^4.1.1", - "webpack": "^5.88.1" + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3", + "@csstools/postcss-progressive-custom-properties": "^4.0.0", + "@csstools/utilities": "^2.0.0" }, "engines": { - "node": ">=18.0" + "node": ">=18" }, "peerDependencies": { - "@docusaurus/types": "*" - }, - "peerDependenciesMeta": { - "@docusaurus/types": { - "optional": true - } + "postcss": "^8.4" } }, - "node_modules/@docusaurus/utils-common": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@docusaurus/utils-common/-/utils-common-3.1.1.tgz", - "integrity": "sha512-eGne3olsIoNfPug5ixjepZAIxeYFzHHnor55Wb2P57jNbtVaFvij/T+MS8U0dtZRFi50QU+UPmRrXdVUM8uyMg==", - "dependencies": { - "tslib": "^2.6.0" - }, + "node_modules/@csstools/postcss-logical-float-and-clear": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-logical-float-and-clear/-/postcss-logical-float-and-clear-3.0.0.tgz", + "integrity": "sha512-SEmaHMszwakI2rqKRJgE+8rpotFfne1ZS6bZqBoQIicFyV+xT1UF42eORPxJkVJVrH9C0ctUgwMSn3BLOIZldQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "engines": { - "node": ">=18.0" + "node": ">=18" }, "peerDependencies": { - "@docusaurus/types": "*" - }, - "peerDependenciesMeta": { - "@docusaurus/types": { - "optional": true - } + "postcss": "^8.4" } }, - "node_modules/@docusaurus/utils-validation": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@docusaurus/utils-validation/-/utils-validation-3.1.1.tgz", - "integrity": "sha512-KlY4P9YVDnwL+nExvlIpu79abfEv6ZCHuOX4ZQ+gtip+Wxj0daccdReIWWtqxM/Fb5Cz1nQvUCc7VEtT8IBUAA==", - "dependencies": { - "@docusaurus/logger": "3.1.1", - "@docusaurus/utils": "3.1.1", - "joi": "^17.9.2", - "js-yaml": "^4.1.0", - "tslib": "^2.6.0" - }, + "node_modules/@csstools/postcss-logical-overflow": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-logical-overflow/-/postcss-logical-overflow-2.0.0.tgz", + "integrity": "sha512-spzR1MInxPuXKEX2csMamshR4LRaSZ3UXVaRGjeQxl70ySxOhMpP2252RAFsg8QyyBXBzuVOOdx1+bVO5bPIzA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "engines": { - "node": ">=18.0" + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" } }, - "node_modules/@hapi/hoek": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", - "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==" - }, - "node_modules/@hapi/topo": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", - "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", - "dependencies": { - "@hapi/hoek": "^9.0.0" + "node_modules/@csstools/postcss-logical-overscroll-behavior": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-logical-overscroll-behavior/-/postcss-logical-overscroll-behavior-2.0.0.tgz", + "integrity": "sha512-e/webMjoGOSYfqLunyzByZj5KKe5oyVg/YSbie99VEaSDE2kimFm0q1f6t/6Jo+VVCQ/jbe2Xy+uX+C4xzWs4w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" } }, - "node_modules/@jest/schemas": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", - "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "node_modules/@csstools/postcss-logical-resize": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-logical-resize/-/postcss-logical-resize-3.0.0.tgz", + "integrity": "sha512-DFbHQOFW/+I+MY4Ycd/QN6Dg4Hcbb50elIJCfnwkRTCX05G11SwViI5BbBlg9iHRl4ytB7pmY5ieAFk3ws7yyg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "dependencies": { - "@sinclair/typebox": "^0.27.8" + "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" } }, - "node_modules/@jest/types": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", - "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "node_modules/@csstools/postcss-logical-viewport-units": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@csstools/postcss-logical-viewport-units/-/postcss-logical-viewport-units-3.0.3.tgz", + "integrity": "sha512-OC1IlG/yoGJdi0Y+7duz/kU/beCwO+Gua01sD6GtOtLi7ByQUpcIqs7UE/xuRPay4cHgOMatWdnDdsIDjnWpPw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "dependencies": { - "@jest/schemas": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" + "@csstools/css-tokenizer": "^3.0.3", + "@csstools/utilities": "^2.0.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" } }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "node_modules/@csstools/postcss-media-minmax": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@csstools/postcss-media-minmax/-/postcss-media-minmax-2.0.5.tgz", + "integrity": "sha512-sdh5i5GToZOIAiwhdntRWv77QDtsxP2r2gXW/WbLSCoLr00KTq/yiF1qlQ5XX2+lmiFa8rATKMcbwl3oXDMNew==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "dependencies": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" + "@csstools/css-calc": "^2.1.0", + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3", + "@csstools/media-query-list-parser": "^4.0.2" }, "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", - "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", - "engines": { - "node": ">=6.0.0" + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" } }, - "node_modules/@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "node_modules/@csstools/postcss-media-queries-aspect-ratio-number-values": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@csstools/postcss-media-queries-aspect-ratio-number-values/-/postcss-media-queries-aspect-ratio-number-values-3.0.4.tgz", + "integrity": "sha512-AnGjVslHMm5xw9keusQYvjVWvuS7KWK+OJagaG0+m9QnIjZsrysD2kJP/tr/UJIyYtMCtu8OkUd+Rajb4DqtIQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3", + "@csstools/media-query-list-parser": "^4.0.2" + }, "engines": { - "node": ">=6.0.0" + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" } }, - "node_modules/@jridgewell/source-map": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", - "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", + "node_modules/@csstools/postcss-nested-calc": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-nested-calc/-/postcss-nested-calc-4.0.0.tgz", + "integrity": "sha512-jMYDdqrQQxE7k9+KjstC3NbsmC063n1FTPLCgCRS2/qHUbHM0mNy9pIn4QIiQGs9I/Bg98vMqw7mJXBxa0N88A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "dependencies": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" + "@csstools/utilities": "^2.0.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" } }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.21", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.21.tgz", - "integrity": "sha512-SRfKmRe1KvYnxjEMtxEr+J4HIeMX5YBg/qhRHpxEIGjhX1rshcHlnFUE9K0GazhVKWM7B+nARSkV8LuvJdJ5/g==", + "node_modules/@csstools/postcss-normalize-display-values": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.0.tgz", + "integrity": "sha512-HlEoG0IDRoHXzXnkV4in47dzsxdsjdz6+j7MLjaACABX2NfvjFS6XVAnpaDyGesz9gK2SC7MbNwdCHusObKJ9Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" } }, - "node_modules/@leichtgewicht/ip-codec": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", - "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==" - }, - "node_modules/@mdx-js/mdx": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-3.0.1.tgz", - "integrity": "sha512-eIQ4QTrOWyL3LWEe/bu6Taqzq2HQvHcyTMaOrI95P2/LmJE7AsfPfgJGuFLPVqBUE1BC1rik3VIhU+s9u72arA==", + "node_modules/@csstools/postcss-oklab-function": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@csstools/postcss-oklab-function/-/postcss-oklab-function-4.0.6.tgz", + "integrity": "sha512-Hptoa0uX+XsNacFBCIQKTUBrFKDiplHan42X73EklG6XmQLG7/aIvxoNhvZ7PvOWMt67Pw3bIlUY2nD6p5vL8A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "dependencies": { - "@types/estree": "^1.0.0", - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/mdx": "^2.0.0", - "collapse-white-space": "^2.0.0", - "devlop": "^1.0.0", - "estree-util-build-jsx": "^3.0.0", - "estree-util-is-identifier-name": "^3.0.0", - "estree-util-to-js": "^2.0.0", - "estree-walker": "^3.0.0", - "hast-util-to-estree": "^3.0.0", - "hast-util-to-jsx-runtime": "^2.0.0", - "markdown-extensions": "^2.0.0", - "periscopic": "^3.0.0", - "remark-mdx": "^3.0.0", - "remark-parse": "^11.0.0", - "remark-rehype": "^11.0.0", - "source-map": "^0.7.0", - "unified": "^11.0.0", - "unist-util-position-from-estree": "^2.0.0", - "unist-util-stringify-position": "^4.0.0", - "unist-util-visit": "^5.0.0", - "vfile": "^6.0.0" + "@csstools/css-color-parser": "^3.0.6", + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3", + "@csstools/postcss-progressive-custom-properties": "^4.0.0", + "@csstools/utilities": "^2.0.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" } }, - "node_modules/@mdx-js/react": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-3.0.0.tgz", - "integrity": "sha512-nDctevR9KyYFyV+m+/+S4cpzCWHqj+iHDHq3QrsWezcC+B17uZdIWgCguESUkwFhM3n/56KxWVE3V6EokrmONQ==", + "node_modules/@csstools/postcss-progressive-custom-properties": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-progressive-custom-properties/-/postcss-progressive-custom-properties-4.0.0.tgz", + "integrity": "sha512-XQPtROaQjomnvLUSy/bALTR5VCtTVUFwYs1SblvYgLSeTo2a/bMNwUwo2piXw5rTv/FEYiy5yPSXBqg9OKUx7Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "dependencies": { - "@types/mdx": "^2.0.0" + "postcss-value-parser": "^4.2.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "engines": { + "node": ">=18" }, "peerDependencies": { - "@types/react": ">=16", - "react": ">=16" + "postcss": "^8.4" } }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "node_modules/@csstools/postcss-random-function": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-random-function/-/postcss-random-function-1.0.1.tgz", + "integrity": "sha512-Ab/tF8/RXktQlFwVhiC70UNfpFQRhtE5fQQoP2pO+KCPGLsLdWFiOuHgSRtBOqEshCVAzR4H6o38nhvRZq8deA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" + "@csstools/css-calc": "^2.1.0", + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3" }, "engines": { - "node": ">= 8" + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" } }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "node_modules/@csstools/postcss-relative-color-syntax": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@csstools/postcss-relative-color-syntax/-/postcss-relative-color-syntax-3.0.6.tgz", + "integrity": "sha512-yxP618Xb+ji1I624jILaYM62uEmZcmbdmFoZHoaThw896sq0vU39kqTTF+ZNic9XyPtPMvq0vyvbgmHaszq8xg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "@csstools/css-color-parser": "^3.0.6", + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3", + "@csstools/postcss-progressive-custom-properties": "^4.0.0", + "@csstools/utilities": "^2.0.0" + }, "engines": { - "node": ">= 8" + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" } }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "node_modules/@csstools/postcss-scope-pseudo-class": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-scope-pseudo-class/-/postcss-scope-pseudo-class-4.0.1.tgz", + "integrity": "sha512-IMi9FwtH6LMNuLea1bjVMQAsUhFxJnyLSgOp/cpv5hrzWmrUYU5fm0EguNDIIOHUqzXode8F/1qkC/tEo/qN8Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" + "postcss-selector-parser": "^7.0.0" }, "engines": { - "node": ">= 8" - } - }, - "node_modules/@pnpm/config.env-replace": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz", - "integrity": "sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==", - "engines": { - "node": ">=12.22.0" + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" } }, - "node_modules/@pnpm/network.ca-file": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@pnpm/network.ca-file/-/network.ca-file-1.0.2.tgz", - "integrity": "sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==", + "node_modules/@csstools/postcss-scope-pseudo-class/node_modules/postcss-selector-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz", + "integrity": "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==", "dependencies": { - "graceful-fs": "4.2.10" + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" }, "engines": { - "node": ">=12.22.0" + "node": ">=4" } }, - "node_modules/@pnpm/network.ca-file/node_modules/graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" - }, - "node_modules/@pnpm/npm-conf": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/@pnpm/npm-conf/-/npm-conf-2.2.2.tgz", - "integrity": "sha512-UA91GwWPhFExt3IizW6bOeY/pQ0BkuNwKjk9iQW9KqxluGCrg4VenZ0/L+2Y0+ZOtme72EVvg6v0zo3AMQRCeA==", + "node_modules/@csstools/postcss-sign-functions": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-sign-functions/-/postcss-sign-functions-1.1.0.tgz", + "integrity": "sha512-SLcc20Nujx/kqbSwDmj6oaXgpy3UjFhBy1sfcqPgDkHfOIfUtUVH7OXO+j7BU4v/At5s61N5ZX6shvgPwluhsA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "dependencies": { - "@pnpm/config.env-replace": "^1.1.0", - "@pnpm/network.ca-file": "^1.0.1", - "config-chain": "^1.1.11" + "@csstools/css-calc": "^2.1.0", + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3" }, "engines": { - "node": ">=12" + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" } }, - "node_modules/@polka/url": { - "version": "1.0.0-next.24", - "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.24.tgz", - "integrity": "sha512-2LuNTFBIO0m7kKIQvvPHN6UE63VjpmL9rnEEaOOaiSPbZK+zUOYIzBAWcED+3XYzhYsd/0mD57VdxAEqqV52CQ==" - }, - "node_modules/@sideway/address": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz", - "integrity": "sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==", + "node_modules/@csstools/postcss-stepped-value-functions": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@csstools/postcss-stepped-value-functions/-/postcss-stepped-value-functions-4.0.5.tgz", + "integrity": "sha512-G6SJ6hZJkhxo6UZojVlLo14MohH4J5J7z8CRBrxxUYy9JuZiIqUo5TBYyDGcE0PLdzpg63a7mHSJz3VD+gMwqw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "dependencies": { - "@hapi/hoek": "^9.0.0" - } - }, - "node_modules/@sideway/formula": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz", - "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==" - }, - "node_modules/@sideway/pinpoint": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", - "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==" - }, - "node_modules/@sinclair/typebox": { - "version": "0.27.8", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", - "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==" - }, - "node_modules/@sindresorhus/is": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", - "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", + "@csstools/css-calc": "^2.1.0", + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3" + }, "engines": { - "node": ">=10" + "node": ">=18" }, - "funding": { - "url": "https://github.com/sindresorhus/is?sponsor=1" - } - }, - "node_modules/@slorber/remark-comment": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@slorber/remark-comment/-/remark-comment-1.0.0.tgz", - "integrity": "sha512-RCE24n7jsOj1M0UPvIQCHTe7fI0sFL4S2nwKVWwHyVr/wI/H8GosgsJGyhnsZoGFnD/P2hLf1mSbrrgSLN93NA==", - "dependencies": { - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.1.0", - "micromark-util-symbol": "^1.0.1" + "peerDependencies": { + "postcss": "^8.4" } }, - "node_modules/@slorber/static-site-generator-webpack-plugin": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/@slorber/static-site-generator-webpack-plugin/-/static-site-generator-webpack-plugin-4.0.7.tgz", - "integrity": "sha512-Ug7x6z5lwrz0WqdnNFOMYrDQNTPAprvHLSh6+/fmml3qUiz6l5eq+2MzLKWtn/q5K5NpSiFsZTP/fck/3vjSxA==", + "node_modules/@csstools/postcss-text-decoration-shorthand": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-text-decoration-shorthand/-/postcss-text-decoration-shorthand-4.0.1.tgz", + "integrity": "sha512-xPZIikbx6jyzWvhms27uugIc0I4ykH4keRvoa3rxX5K7lEhkbd54rjj/dv60qOCTisoS+3bmwJTeyV1VNBrXaw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "dependencies": { - "eval": "^0.1.8", - "p-map": "^4.0.0", - "webpack-sources": "^3.2.2" + "@csstools/color-helpers": "^5.0.1", + "postcss-value-parser": "^4.2.0" }, "engines": { - "node": ">=14" - } - }, - "node_modules/@svgr/babel-plugin-add-jsx-attribute": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-6.5.1.tgz", - "integrity": "sha512-9PYGcXrAxitycIjRmZB+Q0JaN07GZIWaTBIGQzfaZv+qr1n8X1XUEJ5rZ/vx6OVD9RRYlrNnXWExQXcmZeD/BQ==", - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" + "node": ">=18" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "postcss": "^8.4" } }, - "node_modules/@svgr/babel-plugin-remove-jsx-attribute": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-8.0.0.tgz", - "integrity": "sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA==", - "engines": { - "node": ">=14" + "node_modules/@csstools/postcss-trigonometric-functions": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@csstools/postcss-trigonometric-functions/-/postcss-trigonometric-functions-4.0.5.tgz", + "integrity": "sha512-/YQThYkt5MLvAmVu7zxjhceCYlKrYddK6LEmK5I4ojlS6BmO9u2yO4+xjXzu2+NPYmHSTtP4NFSamBCMmJ1NJA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "@csstools/css-calc": "^2.1.0", + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" + "engines": { + "node": ">=18" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "postcss": "^8.4" } }, - "node_modules/@svgr/babel-plugin-remove-jsx-empty-expression": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-8.0.0.tgz", - "integrity": "sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA==", + "node_modules/@csstools/postcss-unset-value": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-unset-value/-/postcss-unset-value-4.0.0.tgz", + "integrity": "sha512-cBz3tOCI5Fw6NIFEwU3RiwK6mn3nKegjpJuzCndoGq3BZPkUjnsq7uQmIeMNeMbMk7YD2MfKcgCpZwX5jyXqCA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" + "node": ">=18" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "postcss": "^8.4" } }, - "node_modules/@svgr/babel-plugin-replace-jsx-attribute-value": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-6.5.1.tgz", - "integrity": "sha512-8DPaVVE3fd5JKuIC29dqyMB54sA6mfgki2H2+swh+zNJoynC8pMPzOkidqHOSc6Wj032fhl8Z0TVn1GiPpAiJg==", + "node_modules/@csstools/utilities": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@csstools/utilities/-/utilities-2.0.0.tgz", + "integrity": "sha512-5VdOr0Z71u+Yp3ozOx8T11N703wIFGVRgOWbOZMKgglPJsWA54MRIoMNVMa7shUToIhx5J8vX4sOZgD2XiihiQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" + "node": ">=18" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "postcss": "^8.4" } }, - "node_modules/@svgr/babel-plugin-svg-dynamic-title": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-6.5.1.tgz", - "integrity": "sha512-FwOEi0Il72iAzlkaHrlemVurgSQRDFbk0OC8dSvD5fSBPHltNh7JtLsxmZUhjYBZo2PpcU/RJvvi6Q0l7O7ogw==", + "node_modules/@discoveryjs/json-ext": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", + "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=10.0.0" } }, - "node_modules/@svgr/babel-plugin-svg-em-dimensions": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-6.5.1.tgz", - "integrity": "sha512-gWGsiwjb4tw+ITOJ86ndY/DZZ6cuXMNE/SjcDRg+HLuCmwpcjOktwRF9WgAiycTqJD/QXqL2f8IzE2Rzh7aVXA==", - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" + "node_modules/@docsearch/css": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.8.0.tgz", + "integrity": "sha512-pieeipSOW4sQ0+bE5UFC51AOZp9NGxg89wAlZ1BAQFaiRAGK1IKUaPQ0UGZeNctJXyqZ1UvBtOQh2HH+U5GtmA==" + }, + "node_modules/@docsearch/react": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.8.0.tgz", + "integrity": "sha512-WnFK720+iwTVt94CxY3u+FgX6exb3BfN5kE9xUY6uuAH/9W/UFboBZFLlrw/zxFRHoHZCOXRtOylsXF+6LHI+Q==", + "dependencies": { + "@algolia/autocomplete-core": "1.17.7", + "@algolia/autocomplete-preset-algolia": "1.17.7", + "@docsearch/css": "3.8.0", + "algoliasearch": "^5.12.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@types/react": ">= 16.8.0 < 19.0.0", + "react": ">= 16.8.0 < 19.0.0", + "react-dom": ">= 16.8.0 < 19.0.0", + "search-insights": ">= 1 < 3" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + }, + "search-insights": { + "optional": true + } } }, - "node_modules/@svgr/babel-plugin-transform-react-native-svg": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-6.5.1.tgz", - "integrity": "sha512-2jT3nTayyYP7kI6aGutkyfJ7UMGtuguD72OjeGLwVNyfPRBD8zQthlvL+fAbAKk5n9ZNcvFkp/b1lZ7VsYqVJg==", - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" + "node_modules/@docsearch/react/node_modules/@algolia/client-analytics": { + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-5.17.1.tgz", + "integrity": "sha512-WKpGC+cUhmdm3wndIlTh8RJXoVabUH+4HrvZHC4hXtvCYojEXYeep8RZstatwSZ7Ocg6Y2u67bLw90NEINuYEw==", + "dependencies": { + "@algolia/client-common": "5.17.1", + "@algolia/requester-browser-xhr": "5.17.1", + "@algolia/requester-fetch": "5.17.1", + "@algolia/requester-node-http": "5.17.1" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "engines": { + "node": ">= 14.0.0" } }, - "node_modules/@svgr/babel-plugin-transform-svg-component": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-6.5.1.tgz", - "integrity": "sha512-a1p6LF5Jt33O3rZoVRBqdxL350oge54iZWHNI6LJB5tQ7EelvD/Mb1mfBiZNAan0dt4i3VArkFRjA4iObuNykQ==", + "node_modules/@docsearch/react/node_modules/@algolia/client-personalization": { + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-5.17.1.tgz", + "integrity": "sha512-JuNlZe1SdW9KbV0gcgdsiVkFfXt0mmPassdS3cBSGvZGbPB9JsHthD719k5Y6YOY4dGvw1JmC1i9CwCQHAS8hg==", + "dependencies": { + "@algolia/client-common": "5.17.1", + "@algolia/requester-browser-xhr": "5.17.1", + "@algolia/requester-fetch": "5.17.1", + "@algolia/requester-node-http": "5.17.1" + }, "engines": { - "node": ">=12" + "node": ">= 14.0.0" + } + }, + "node_modules/@docsearch/react/node_modules/@algolia/recommend": { + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-5.17.1.tgz", + "integrity": "sha512-2992tTHkRe18qmf5SP57N78kN1D3e5t4PO1rt10sJncWtXBZWiNOK6K/UcvWsFbNSGAogFcIcvIMAl5mNp6RWA==", + "dependencies": { + "@algolia/client-common": "5.17.1", + "@algolia/requester-browser-xhr": "5.17.1", + "@algolia/requester-fetch": "5.17.1", + "@algolia/requester-node-http": "5.17.1" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@docsearch/react/node_modules/algoliasearch": { + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-5.17.1.tgz", + "integrity": "sha512-3CcbT5yTWJDIcBe9ZHgsPi184SkT1kyZi3GWlQU5EFgvq1V73X2sqHRkPCQMe0RA/uvZbB+1sFeAk73eWygeLg==", + "dependencies": { + "@algolia/client-abtesting": "5.17.1", + "@algolia/client-analytics": "5.17.1", + "@algolia/client-common": "5.17.1", + "@algolia/client-insights": "5.17.1", + "@algolia/client-personalization": "5.17.1", + "@algolia/client-query-suggestions": "5.17.1", + "@algolia/client-search": "5.17.1", + "@algolia/ingestion": "1.17.1", + "@algolia/monitoring": "1.17.1", + "@algolia/recommend": "5.17.1", + "@algolia/requester-browser-xhr": "5.17.1", + "@algolia/requester-fetch": "5.17.1", + "@algolia/requester-node-http": "5.17.1" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@docusaurus/babel": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/@docusaurus/babel/-/babel-3.6.3.tgz", + "integrity": "sha512-7dW9Hat9EHYCVicFXYA4hjxBY38+hPuCURL8oRF9fySRm7vzNWuEOghA1TXcykuXZp0HLG2td4RhDxCvGG7tNw==", + "dependencies": { + "@babel/core": "^7.25.9", + "@babel/generator": "^7.25.9", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-transform-runtime": "^7.25.9", + "@babel/preset-env": "^7.25.9", + "@babel/preset-react": "^7.25.9", + "@babel/preset-typescript": "^7.25.9", + "@babel/runtime": "^7.25.9", + "@babel/runtime-corejs3": "^7.25.9", + "@babel/traverse": "^7.25.9", + "@docusaurus/logger": "3.6.3", + "@docusaurus/utils": "3.6.3", + "babel-plugin-dynamic-import-node": "^2.3.3", + "fs-extra": "^11.1.1", + "tslib": "^2.6.0" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "engines": { + "node": ">=18.0" } }, - "node_modules/@svgr/babel-preset": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-6.5.1.tgz", - "integrity": "sha512-6127fvO/FF2oi5EzSQOAjo1LE3OtNVh11R+/8FXa+mHx1ptAaS4cknIjnUA7e6j6fwGGJ17NzaTJFUwOV2zwCw==", + "node_modules/@docusaurus/bundler": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/@docusaurus/bundler/-/bundler-3.6.3.tgz", + "integrity": "sha512-47JLuc8D4wA+6VOvmMd5fUC9rFppBQpQOnxDYiVXffm/DeV/wmm3sbpNd5Y+O+G2+nevLTRnvCm/qyancv0Y3A==", "dependencies": { - "@svgr/babel-plugin-add-jsx-attribute": "^6.5.1", - "@svgr/babel-plugin-remove-jsx-attribute": "*", - "@svgr/babel-plugin-remove-jsx-empty-expression": "*", - "@svgr/babel-plugin-replace-jsx-attribute-value": "^6.5.1", - "@svgr/babel-plugin-svg-dynamic-title": "^6.5.1", - "@svgr/babel-plugin-svg-em-dimensions": "^6.5.1", - "@svgr/babel-plugin-transform-react-native-svg": "^6.5.1", - "@svgr/babel-plugin-transform-svg-component": "^6.5.1" + "@babel/core": "^7.25.9", + "@docusaurus/babel": "3.6.3", + "@docusaurus/cssnano-preset": "3.6.3", + "@docusaurus/logger": "3.6.3", + "@docusaurus/types": "3.6.3", + "@docusaurus/utils": "3.6.3", + "babel-loader": "^9.2.1", + "clean-css": "^5.3.2", + "copy-webpack-plugin": "^11.0.0", + "css-loader": "^6.8.1", + "css-minimizer-webpack-plugin": "^5.0.1", + "cssnano": "^6.1.2", + "file-loader": "^6.2.0", + "html-minifier-terser": "^7.2.0", + "mini-css-extract-plugin": "^2.9.1", + "null-loader": "^4.0.1", + "postcss": "^8.4.26", + "postcss-loader": "^7.3.3", + "postcss-preset-env": "^10.1.0", + "react-dev-utils": "^12.0.1", + "terser-webpack-plugin": "^5.3.9", + "tslib": "^2.6.0", + "url-loader": "^4.1.1", + "webpack": "^5.95.0", + "webpackbar": "^6.0.1" }, "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" + "node": ">=18.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@docusaurus/faster": "*" + }, + "peerDependenciesMeta": { + "@docusaurus/faster": { + "optional": true + } } }, - "node_modules/@svgr/core": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/core/-/core-6.5.1.tgz", - "integrity": "sha512-/xdLSWxK5QkqG524ONSjvg3V/FkNyCv538OIBdQqPNaAta3AsXj/Bd2FbvR87yMbXO2hFSWiAe/Q6IkVPDw+mw==", - "dependencies": { - "@babel/core": "^7.19.6", - "@svgr/babel-preset": "^6.5.1", - "@svgr/plugin-jsx": "^6.5.1", - "camelcase": "^6.2.0", - "cosmiconfig": "^7.0.1" + "node_modules/@docusaurus/core": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/@docusaurus/core/-/core-3.6.3.tgz", + "integrity": "sha512-xL7FRY9Jr5DWqB6pEnqgKqcMPJOX5V0pgWXi5lCiih11sUBmcFKM7c3+GyxcVeeWFxyYSDP3grLTWqJoP4P9Vw==", + "dependencies": { + "@docusaurus/babel": "3.6.3", + "@docusaurus/bundler": "3.6.3", + "@docusaurus/logger": "3.6.3", + "@docusaurus/mdx-loader": "3.6.3", + "@docusaurus/utils": "3.6.3", + "@docusaurus/utils-common": "3.6.3", + "@docusaurus/utils-validation": "3.6.3", + "boxen": "^6.2.1", + "chalk": "^4.1.2", + "chokidar": "^3.5.3", + "cli-table3": "^0.6.3", + "combine-promises": "^1.1.0", + "commander": "^5.1.0", + "core-js": "^3.31.1", + "del": "^6.1.1", + "detect-port": "^1.5.1", + "escape-html": "^1.0.3", + "eta": "^2.2.0", + "eval": "^0.1.8", + "fs-extra": "^11.1.1", + "html-tags": "^3.3.1", + "html-webpack-plugin": "^5.6.0", + "leven": "^3.1.0", + "lodash": "^4.17.21", + "p-map": "^4.0.0", + "prompts": "^2.4.2", + "react-dev-utils": "^12.0.1", + "react-helmet-async": "^1.3.0", + "react-loadable": "npm:@docusaurus/react-loadable@6.0.0", + "react-loadable-ssr-addon-v5-slorber": "^1.0.1", + "react-router": "^5.3.4", + "react-router-config": "^5.1.1", + "react-router-dom": "^5.3.4", + "rtl-detect": "^1.0.4", + "semver": "^7.5.4", + "serve-handler": "^6.1.6", + "shelljs": "^0.8.5", + "tslib": "^2.6.0", + "update-notifier": "^6.0.2", + "webpack": "^5.95.0", + "webpack-bundle-analyzer": "^4.10.2", + "webpack-dev-server": "^4.15.2", + "webpack-merge": "^6.0.1" + }, + "bin": { + "docusaurus": "bin/docusaurus.mjs" }, "engines": { - "node": ">=10" + "node": ">=18.0" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" + "peerDependencies": { + "@mdx-js/react": "^3.0.0", + "react": "^18.0.0", + "react-dom": "^18.0.0" } }, - "node_modules/@svgr/hast-util-to-babel-ast": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-6.5.1.tgz", - "integrity": "sha512-1hnUxxjd83EAxbL4a0JDJoD3Dao3hmjvyvyEV8PzWmLK3B9m9NPlW7GKjFyoWE8nM7HnXzPcmmSyOW8yOddSXw==", + "node_modules/@docusaurus/cssnano-preset": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/@docusaurus/cssnano-preset/-/cssnano-preset-3.6.3.tgz", + "integrity": "sha512-qP7SXrwZ+23GFJdPN4aIHQrZW+oH/7tzwEuc/RNL0+BdZdmIjYQqUxdXsjE4lFxLNZjj0eUrSNYIS6xwfij+5Q==", "dependencies": { - "@babel/types": "^7.20.0", - "entities": "^4.4.0" + "cssnano-preset-advanced": "^6.1.2", + "postcss": "^8.4.38", + "postcss-sort-media-queries": "^5.2.0", + "tslib": "^2.6.0" }, "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" + "node": ">=18.0" } }, - "node_modules/@svgr/plugin-jsx": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-6.5.1.tgz", - "integrity": "sha512-+UdQxI3jgtSjCykNSlEMuy1jSRQlGC7pqBCPvkG/2dATdWo082zHTTK3uhnAju2/6XpE6B5mZ3z4Z8Ns01S8Gw==", + "node_modules/@docusaurus/logger": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/@docusaurus/logger/-/logger-3.6.3.tgz", + "integrity": "sha512-xSubJixcNyMV9wMV4q0s47CBz3Rlc5jbcCCuij8pfQP8qn/DIpt0ks8W6hQWzHAedg/J/EwxxUOUrnEoKzJo8g==", "dependencies": { - "@babel/core": "^7.19.6", - "@svgr/babel-preset": "^6.5.1", - "@svgr/hast-util-to-babel-ast": "^6.5.1", - "svg-parser": "^2.0.4" + "chalk": "^4.1.2", + "tslib": "^2.6.0" }, "engines": { - "node": ">=10" + "node": ">=18.0" + } + }, + "node_modules/@docusaurus/mdx-loader": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/@docusaurus/mdx-loader/-/mdx-loader-3.6.3.tgz", + "integrity": "sha512-3iJdiDz9540ppBseeI93tWTDtUGVkxzh59nMq4ignylxMuXBLK8dFqVeaEor23v1vx6TrGKZ2FuLaTB+U7C0QQ==", + "dependencies": { + "@docusaurus/logger": "3.6.3", + "@docusaurus/utils": "3.6.3", + "@docusaurus/utils-validation": "3.6.3", + "@mdx-js/mdx": "^3.0.0", + "@slorber/remark-comment": "^1.0.0", + "escape-html": "^1.0.3", + "estree-util-value-to-estree": "^3.0.1", + "file-loader": "^6.2.0", + "fs-extra": "^11.1.1", + "image-size": "^1.0.2", + "mdast-util-mdx": "^3.0.0", + "mdast-util-to-string": "^4.0.0", + "rehype-raw": "^7.0.0", + "remark-directive": "^3.0.0", + "remark-emoji": "^4.0.0", + "remark-frontmatter": "^5.0.0", + "remark-gfm": "^4.0.0", + "stringify-object": "^3.3.0", + "tslib": "^2.6.0", + "unified": "^11.0.3", + "unist-util-visit": "^5.0.0", + "url-loader": "^4.1.1", + "vfile": "^6.0.1", + "webpack": "^5.88.1" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" + "engines": { + "node": ">=18.0" }, "peerDependencies": { - "@svgr/core": "^6.0.0" + "react": "^18.0.0", + "react-dom": "^18.0.0" } }, - "node_modules/@svgr/plugin-svgo": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-6.5.1.tgz", - "integrity": "sha512-omvZKf8ixP9z6GWgwbtmP9qQMPX4ODXi+wzbVZgomNFsUIlHA1sf4fThdwTWSsZGgvGAG6yE+b/F5gWUkcZ/iQ==", + "node_modules/@docusaurus/module-type-aliases": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/@docusaurus/module-type-aliases/-/module-type-aliases-3.6.3.tgz", + "integrity": "sha512-MjaXX9PN/k5ugNvfRZdWyKWq4FsrhN4LEXaj0pEmMebJuBNlFeGyKQUa9DRhJHpadNaiMLrbo9m3U7Ig5YlsZg==", "dependencies": { - "cosmiconfig": "^7.0.1", - "deepmerge": "^4.2.2", - "svgo": "^2.8.0" + "@docusaurus/types": "3.6.3", + "@types/history": "^4.7.11", + "@types/react": "*", + "@types/react-router-config": "*", + "@types/react-router-dom": "*", + "react-helmet-async": "*", + "react-loadable": "npm:@docusaurus/react-loadable@6.0.0" + }, + "peerDependencies": { + "react": "*", + "react-dom": "*" + } + }, + "node_modules/@docusaurus/plugin-content-blog": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-blog/-/plugin-content-blog-3.6.3.tgz", + "integrity": "sha512-k0ogWwwJU3pFRFfvW1kRVHxzf2DutLGaaLjAnHVEU6ju+aRP0Z5ap/13DHyPOfHeE4WKpn/M0TqjdwZAcY3kAw==", + "dependencies": { + "@docusaurus/core": "3.6.3", + "@docusaurus/logger": "3.6.3", + "@docusaurus/mdx-loader": "3.6.3", + "@docusaurus/theme-common": "3.6.3", + "@docusaurus/types": "3.6.3", + "@docusaurus/utils": "3.6.3", + "@docusaurus/utils-common": "3.6.3", + "@docusaurus/utils-validation": "3.6.3", + "cheerio": "1.0.0-rc.12", + "feed": "^4.2.2", + "fs-extra": "^11.1.1", + "lodash": "^4.17.21", + "reading-time": "^1.5.0", + "srcset": "^4.0.0", + "tslib": "^2.6.0", + "unist-util-visit": "^5.0.0", + "utility-types": "^3.10.0", + "webpack": "^5.88.1" }, "engines": { - "node": ">=10" + "node": ">=18.0" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" + "peerDependencies": { + "@docusaurus/plugin-content-docs": "*", + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/plugin-content-docs": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-docs/-/plugin-content-docs-3.6.3.tgz", + "integrity": "sha512-r2wS8y/fsaDcxkm20W5bbYJFPzdWdEaTWVYjNxlHlcmX086eqQR1Fomlg9BHTJ0dLXPzAlbC8EN4XqMr3QzNCQ==", + "dependencies": { + "@docusaurus/core": "3.6.3", + "@docusaurus/logger": "3.6.3", + "@docusaurus/mdx-loader": "3.6.3", + "@docusaurus/module-type-aliases": "3.6.3", + "@docusaurus/theme-common": "3.6.3", + "@docusaurus/types": "3.6.3", + "@docusaurus/utils": "3.6.3", + "@docusaurus/utils-common": "3.6.3", + "@docusaurus/utils-validation": "3.6.3", + "@types/react-router-config": "^5.0.7", + "combine-promises": "^1.1.0", + "fs-extra": "^11.1.1", + "js-yaml": "^4.1.0", + "lodash": "^4.17.21", + "tslib": "^2.6.0", + "utility-types": "^3.10.0", + "webpack": "^5.88.1" + }, + "engines": { + "node": ">=18.0" }, "peerDependencies": { - "@svgr/core": "*" + "react": "^18.0.0", + "react-dom": "^18.0.0" } }, - "node_modules/@svgr/webpack": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-6.5.1.tgz", - "integrity": "sha512-cQ/AsnBkXPkEK8cLbv4Dm7JGXq2XrumKnL1dRpJD9rIO2fTIlJI9a1uCciYG1F2aUsox/hJQyNGbt3soDxSRkA==", - "dependencies": { - "@babel/core": "^7.19.6", - "@babel/plugin-transform-react-constant-elements": "^7.18.12", - "@babel/preset-env": "^7.19.4", - "@babel/preset-react": "^7.18.6", - "@babel/preset-typescript": "^7.18.6", - "@svgr/core": "^6.5.1", - "@svgr/plugin-jsx": "^6.5.1", - "@svgr/plugin-svgo": "^6.5.1" + "node_modules/@docusaurus/plugin-content-pages": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-pages/-/plugin-content-pages-3.6.3.tgz", + "integrity": "sha512-eHrmTgjgLZsuqfsYr5X2xEwyIcck0wseSofWrjTwT9FLOWp+KDmMAuVK+wRo7sFImWXZk3oV/xX/g9aZrhD7OA==", + "dependencies": { + "@docusaurus/core": "3.6.3", + "@docusaurus/mdx-loader": "3.6.3", + "@docusaurus/types": "3.6.3", + "@docusaurus/utils": "3.6.3", + "@docusaurus/utils-validation": "3.6.3", + "fs-extra": "^11.1.1", + "tslib": "^2.6.0", + "webpack": "^5.88.1" }, "engines": { - "node": ">=10" + "node": ">=18.0" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" } }, - "node_modules/@szmarczak/http-timer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", - "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", + "node_modules/@docusaurus/plugin-debug": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-debug/-/plugin-debug-3.6.3.tgz", + "integrity": "sha512-zB9GXfIZNPRfzKnNjU6xGVrqn9bPXuGhpjgsuc/YtcTDjnjhasg38NdYd5LEqXex5G/zIorQgWB3n6x/Ut62vQ==", "dependencies": { - "defer-to-connect": "^2.0.1" + "@docusaurus/core": "3.6.3", + "@docusaurus/types": "3.6.3", + "@docusaurus/utils": "3.6.3", + "fs-extra": "^11.1.1", + "react-json-view-lite": "^1.2.0", + "tslib": "^2.6.0" }, "engines": { - "node": ">=14.16" + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" } }, - "node_modules/@trysound/sax": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", - "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", + "node_modules/@docusaurus/plugin-google-analytics": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-analytics/-/plugin-google-analytics-3.6.3.tgz", + "integrity": "sha512-rCDNy1QW8Dag7nZq67pcum0bpFLrwvxJhYuVprhFh8BMBDxV0bY+bAkGHbSf68P3Bk9C3hNOAXX1srGLIDvcTA==", + "dependencies": { + "@docusaurus/core": "3.6.3", + "@docusaurus/types": "3.6.3", + "@docusaurus/utils-validation": "3.6.3", + "tslib": "^2.6.0" + }, "engines": { - "node": ">=10.13.0" + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" } }, - "node_modules/@types/acorn": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@types/acorn/-/acorn-4.0.6.tgz", - "integrity": "sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ==", + "node_modules/@docusaurus/plugin-google-gtag": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-gtag/-/plugin-google-gtag-3.6.3.tgz", + "integrity": "sha512-+OyDvhM6rqVkQOmLVkQWVJAizEEfkPzVWtIHXlWPOCFGK9X4/AWeBSrU0WG4iMg9Z4zD4YDRrU+lvI4s6DSC+w==", "dependencies": { - "@types/estree": "*" + "@docusaurus/core": "3.6.3", + "@docusaurus/types": "3.6.3", + "@docusaurus/utils-validation": "3.6.3", + "@types/gtag.js": "^0.0.12", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" } }, - "node_modules/@types/body-parser": { - "version": "1.19.5", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", - "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "node_modules/@docusaurus/plugin-google-tag-manager": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-tag-manager/-/plugin-google-tag-manager-3.6.3.tgz", + "integrity": "sha512-1M6UPB13gWUtN2UHX083/beTn85PlRI9ABItTl/JL1FJ5dJTWWFXXsHf9WW/6hrVwthwTeV/AGbGKvLKV+IlCA==", "dependencies": { - "@types/connect": "*", - "@types/node": "*" + "@docusaurus/core": "3.6.3", + "@docusaurus/types": "3.6.3", + "@docusaurus/utils-validation": "3.6.3", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" } }, - "node_modules/@types/bonjour": { - "version": "3.5.13", - "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", - "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", - "dependencies": { - "@types/node": "*" + "node_modules/@docusaurus/plugin-sitemap": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-sitemap/-/plugin-sitemap-3.6.3.tgz", + "integrity": "sha512-94qOO4M9Fwv9KfVQJsgbe91k+fPJ4byf1L3Ez8TUa6TAFPo/BrLwQ80zclHkENlL1824TuxkcMKv33u6eydQCg==", + "dependencies": { + "@docusaurus/core": "3.6.3", + "@docusaurus/logger": "3.6.3", + "@docusaurus/types": "3.6.3", + "@docusaurus/utils": "3.6.3", + "@docusaurus/utils-common": "3.6.3", + "@docusaurus/utils-validation": "3.6.3", + "fs-extra": "^11.1.1", + "sitemap": "^7.1.1", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" } }, - "node_modules/@types/connect": { - "version": "3.4.38", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", - "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", - "dependencies": { - "@types/node": "*" + "node_modules/@docusaurus/preset-classic": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/@docusaurus/preset-classic/-/preset-classic-3.6.3.tgz", + "integrity": "sha512-VHSYWROT3flvNNI1SrnMOtW1EsjeHNK9dhU6s9eY5hryZe79lUqnZJyze/ymDe2LXAqzyj6y5oYvyBoZZk6ErA==", + "dependencies": { + "@docusaurus/core": "3.6.3", + "@docusaurus/plugin-content-blog": "3.6.3", + "@docusaurus/plugin-content-docs": "3.6.3", + "@docusaurus/plugin-content-pages": "3.6.3", + "@docusaurus/plugin-debug": "3.6.3", + "@docusaurus/plugin-google-analytics": "3.6.3", + "@docusaurus/plugin-google-gtag": "3.6.3", + "@docusaurus/plugin-google-tag-manager": "3.6.3", + "@docusaurus/plugin-sitemap": "3.6.3", + "@docusaurus/theme-classic": "3.6.3", + "@docusaurus/theme-common": "3.6.3", + "@docusaurus/theme-search-algolia": "3.6.3", + "@docusaurus/types": "3.6.3" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" } }, - "node_modules/@types/connect-history-api-fallback": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", - "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", - "dependencies": { - "@types/express-serve-static-core": "*", - "@types/node": "*" + "node_modules/@docusaurus/theme-classic": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-classic/-/theme-classic-3.6.3.tgz", + "integrity": "sha512-1RRLK1tSArI2c00qugWYO3jRocjOZwGF1mBzPPylDVRwWCS/rnWWR91ChdbbaxIupRJ+hX8ZBYrwr5bbU0oztQ==", + "dependencies": { + "@docusaurus/core": "3.6.3", + "@docusaurus/logger": "3.6.3", + "@docusaurus/mdx-loader": "3.6.3", + "@docusaurus/module-type-aliases": "3.6.3", + "@docusaurus/plugin-content-blog": "3.6.3", + "@docusaurus/plugin-content-docs": "3.6.3", + "@docusaurus/plugin-content-pages": "3.6.3", + "@docusaurus/theme-common": "3.6.3", + "@docusaurus/theme-translations": "3.6.3", + "@docusaurus/types": "3.6.3", + "@docusaurus/utils": "3.6.3", + "@docusaurus/utils-common": "3.6.3", + "@docusaurus/utils-validation": "3.6.3", + "@mdx-js/react": "^3.0.0", + "clsx": "^2.0.0", + "copy-text-to-clipboard": "^3.2.0", + "infima": "0.2.0-alpha.45", + "lodash": "^4.17.21", + "nprogress": "^0.2.0", + "postcss": "^8.4.26", + "prism-react-renderer": "^2.3.0", + "prismjs": "^1.29.0", + "react-router-dom": "^5.3.4", + "rtlcss": "^4.1.0", + "tslib": "^2.6.0", + "utility-types": "^3.10.0" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" } }, - "node_modules/@types/d3-scale": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.8.tgz", - "integrity": "sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ==", - "dependencies": { - "@types/d3-time": "*" + "node_modules/@docusaurus/theme-common": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-common/-/theme-common-3.6.3.tgz", + "integrity": "sha512-b8ZkhczXHDxWWyvz+YJy4t/PlPbEogTTbgnHoflYnH7rmRtyoodTsu8WVM12la5LmlMJBclBXFl29OH8kPE7gg==", + "dependencies": { + "@docusaurus/mdx-loader": "3.6.3", + "@docusaurus/module-type-aliases": "3.6.3", + "@docusaurus/utils": "3.6.3", + "@docusaurus/utils-common": "3.6.3", + "@types/history": "^4.7.11", + "@types/react": "*", + "@types/react-router-config": "*", + "clsx": "^2.0.0", + "parse-numeric-range": "^1.3.0", + "prism-react-renderer": "^2.3.0", + "tslib": "^2.6.0", + "utility-types": "^3.10.0" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "@docusaurus/plugin-content-docs": "*", + "react": "^18.0.0", + "react-dom": "^18.0.0" } }, - "node_modules/@types/d3-scale-chromatic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.0.3.tgz", - "integrity": "sha512-laXM4+1o5ImZv3RpFAsTRn3TEkzqkytiOY0Dz0sq5cnd1dtNlk6sHLon4OvqaiJb28T0S/TdsBI3Sjsy+keJrw==" - }, - "node_modules/@types/d3-time": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.3.tgz", - "integrity": "sha512-2p6olUZ4w3s+07q3Tm2dbiMZy5pCDfYwtLXXHUnVzXgQlZ/OyPtUz6OL382BkOuGlLXqfT+wqv8Fw2v8/0geBw==" - }, - "node_modules/@types/debug": { - "version": "4.1.12", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", - "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", - "dependencies": { - "@types/ms": "*" + "node_modules/@docusaurus/theme-mermaid": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-mermaid/-/theme-mermaid-3.6.3.tgz", + "integrity": "sha512-kIqpjNCP/9R2GGf8UmiDxD3CkOAEJuJIEFlaKMgQtjVxa/vH+9PLI1+DFbArGoG4+0ENTYUq8phHPW7SeL36uQ==", + "dependencies": { + "@docusaurus/core": "3.6.3", + "@docusaurus/module-type-aliases": "3.6.3", + "@docusaurus/theme-common": "3.6.3", + "@docusaurus/types": "3.6.3", + "@docusaurus/utils-validation": "3.6.3", + "mermaid": ">=10.4", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" } }, - "node_modules/@types/eslint": { - "version": "8.56.2", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.2.tgz", - "integrity": "sha512-uQDwm1wFHmbBbCZCqAlq6Do9LYwByNZHWzXppSnay9SuwJ+VRbjkbLABer54kcPnMSlG6Fdiy2yaFXm/z9Z5gw==", + "node_modules/@docusaurus/theme-search-algolia": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-search-algolia/-/theme-search-algolia-3.6.3.tgz", + "integrity": "sha512-rt+MGCCpYgPyWCGXtbxlwFbTSobu15jWBTPI2LHsHNa5B0zSmOISX6FWYAPt5X1rNDOqMGM0FATnh7TBHRohVA==", "dependencies": { - "@types/estree": "*", - "@types/json-schema": "*" + "@docsearch/react": "^3.5.2", + "@docusaurus/core": "3.6.3", + "@docusaurus/logger": "3.6.3", + "@docusaurus/plugin-content-docs": "3.6.3", + "@docusaurus/theme-common": "3.6.3", + "@docusaurus/theme-translations": "3.6.3", + "@docusaurus/utils": "3.6.3", + "@docusaurus/utils-validation": "3.6.3", + "algoliasearch": "^4.18.0", + "algoliasearch-helper": "^3.13.3", + "clsx": "^2.0.0", + "eta": "^2.2.0", + "fs-extra": "^11.1.1", + "lodash": "^4.17.21", + "tslib": "^2.6.0", + "utility-types": "^3.10.0" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" } }, - "node_modules/@types/eslint-scope": { - "version": "3.7.7", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", - "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "node_modules/@docusaurus/theme-translations": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-translations/-/theme-translations-3.6.3.tgz", + "integrity": "sha512-Gb0regclToVlngSIIwUCtBMQBq48qVUaN1XQNKW4XwlsgUyk0vP01LULdqbem7czSwIeBAFXFoORJ0RPX7ht/w==", "dependencies": { - "@types/eslint": "*", - "@types/estree": "*" + "fs-extra": "^11.1.1", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=18.0" } }, - "node_modules/@types/estree": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", - "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==" + "node_modules/@docusaurus/tsconfig": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/@docusaurus/tsconfig/-/tsconfig-3.6.3.tgz", + "integrity": "sha512-1pT/rTrRpMV15E4tJH95W5PrjboMn5JkKF+Ys8cTjMegetiXjs0gPFOSDA5hdTlberKQLDO50xPjMJHondLuzA==", + "dev": true }, - "node_modules/@types/estree-jsx": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.4.tgz", - "integrity": "sha512-5idy3hvI9lAMqsyilBM+N+boaCf1MgoefbDxN6KEO5aK17TOHwFAYT9sjxzeKAiIWRUBgLxmZ9mPcnzZXtTcRQ==", + "node_modules/@docusaurus/types": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-3.6.3.tgz", + "integrity": "sha512-xD9oTGDrouWzefkhe9ogB2fDV96/82cRpNGx2HIvI5L87JHNhQVIWimQ/3JIiiX/TEd5S9s+VO6FFguwKNRVow==", "dependencies": { - "@types/estree": "*" + "@mdx-js/mdx": "^3.0.0", + "@types/history": "^4.7.11", + "@types/react": "*", + "commander": "^5.1.0", + "joi": "^17.9.2", + "react-helmet-async": "^1.3.0", + "utility-types": "^3.10.0", + "webpack": "^5.95.0", + "webpack-merge": "^5.9.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" } }, - "node_modules/@types/express": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", - "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "node_modules/@docusaurus/types/node_modules/webpack-merge": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", + "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", "dependencies": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.33", - "@types/qs": "*", - "@types/serve-static": "*" + "clone-deep": "^4.0.1", + "flat": "^5.0.2", + "wildcard": "^2.0.0" + }, + "engines": { + "node": ">=10.0.0" } }, - "node_modules/@types/express-serve-static-core": { - "version": "4.17.41", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.41.tgz", - "integrity": "sha512-OaJ7XLaelTgrvlZD8/aa0vvvxZdUmlCn6MtWeB7TkiKW70BQLc9XEPpDLPdbo52ZhXUCrznlWdCHWxJWtdyajA==", - "dependencies": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*", - "@types/send": "*" + "node_modules/@docusaurus/utils": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/@docusaurus/utils/-/utils-3.6.3.tgz", + "integrity": "sha512-0R/FR3bKVl4yl8QwbL4TYFfR+OXBRpVUaTJdENapBGR3YMwfM6/JnhGilWQO8AOwPJGtGoDK7ib8+8UF9f3OZQ==", + "dependencies": { + "@docusaurus/logger": "3.6.3", + "@docusaurus/types": "3.6.3", + "@docusaurus/utils-common": "3.6.3", + "@svgr/webpack": "^8.1.0", + "escape-string-regexp": "^4.0.0", + "file-loader": "^6.2.0", + "fs-extra": "^11.1.1", + "github-slugger": "^1.5.0", + "globby": "^11.1.0", + "gray-matter": "^4.0.3", + "jiti": "^1.20.0", + "js-yaml": "^4.1.0", + "lodash": "^4.17.21", + "micromatch": "^4.0.5", + "prompts": "^2.4.2", + "resolve-pathname": "^3.0.0", + "shelljs": "^0.8.5", + "tslib": "^2.6.0", + "url-loader": "^4.1.1", + "utility-types": "^3.10.0", + "webpack": "^5.88.1" + }, + "engines": { + "node": ">=18.0" } }, - "node_modules/@types/gtag.js": { - "version": "0.0.12", - "resolved": "https://registry.npmjs.org/@types/gtag.js/-/gtag.js-0.0.12.tgz", - "integrity": "sha512-YQV9bUsemkzG81Ea295/nF/5GijnD2Af7QhEofh7xu+kvCN6RdodgNwwGWXB5GMI3NoyvQo0odNctoH/qLMIpg==" - }, - "node_modules/@types/hast": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", - "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "node_modules/@docusaurus/utils-common": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/@docusaurus/utils-common/-/utils-common-3.6.3.tgz", + "integrity": "sha512-v4nKDaANLgT3pMBewHYEMAl/ufY0LkXao1QkFWzI5huWFOmNQ2UFzv2BiKeHX5Ownis0/w6cAyoxPhVdDonlSQ==", "dependencies": { - "@types/unist": "*" + "@docusaurus/types": "3.6.3", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=18.0" } }, - "node_modules/@types/history": { - "version": "4.7.11", - "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.11.tgz", - "integrity": "sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==" + "node_modules/@docusaurus/utils-validation": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/@docusaurus/utils-validation/-/utils-validation-3.6.3.tgz", + "integrity": "sha512-bhEGGiN5BE38h21vjqD70Gxg++j+PfYVddDUE5UFvLDup68QOcpD33CLr+2knPorlxRbEaNfz6HQDUMQ3HuqKw==", + "dependencies": { + "@docusaurus/logger": "3.6.3", + "@docusaurus/utils": "3.6.3", + "@docusaurus/utils-common": "3.6.3", + "fs-extra": "^11.2.0", + "joi": "^17.9.2", + "js-yaml": "^4.1.0", + "lodash": "^4.17.21", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=18.0" + } }, - "node_modules/@types/html-minifier-terser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", - "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==" + "node_modules/@hapi/hoek": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", + "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==" }, - "node_modules/@types/http-cache-semantics": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", - "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==" + "node_modules/@hapi/topo": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", + "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", + "dependencies": { + "@hapi/hoek": "^9.0.0" + } }, - "node_modules/@types/http-errors": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", - "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==" + "node_modules/@iconify/types": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz", + "integrity": "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==" }, - "node_modules/@types/http-proxy": { - "version": "1.17.14", - "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.14.tgz", - "integrity": "sha512-SSrD0c1OQzlFX7pGu1eXxSEjemej64aaNPRhhVYUGqXh0BtldAAx37MG8btcumvpgKyZp1F5Gn3JkktdxiFv6w==", + "node_modules/@iconify/utils": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@iconify/utils/-/utils-2.2.0.tgz", + "integrity": "sha512-9A5eZQV9eKlNCXlI/SgYsGRS7YmGmB1oAsRpNVIYBmIzGJRgH+hfG+lo4069s+GFWFNnBAtDg10c53vQZBLfnA==", "dependencies": { - "@types/node": "*" + "@antfu/install-pkg": "^0.4.1", + "@antfu/utils": "^0.7.10", + "@iconify/types": "^2.0.0", + "debug": "^4.4.0", + "globals": "^15.13.0", + "kolorist": "^1.8.0", + "local-pkg": "^0.5.1", + "mlly": "^1.7.3" } }, - "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", - "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==" + "node_modules/@iconify/utils/node_modules/globals": { + "version": "15.13.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.13.0.tgz", + "integrity": "sha512-49TewVEz0UxZjr1WYYsWpPrhyC/B/pA8Bq0fUmet2n+eR7yn0IvNzNaoBwnK6mdkzcN+se7Ez9zUgULTz2QH4g==", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "node_modules/@types/istanbul-lib-report": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", - "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", "dependencies": { - "@types/istanbul-lib-coverage": "*" + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@types/istanbul-reports": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", - "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", + "node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", "dependencies": { - "@types/istanbul-lib-report": "*" + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==" - }, - "node_modules/@types/mdast": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.3.tgz", - "integrity": "sha512-LsjtqsyF+d2/yFOYaN22dHZI1Cpwkrj+g06G8+qtUKlhovPW89YhqSnfKtMbkgmEtYpH2gydRNULd6y8mciAFg==", + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", + "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", "dependencies": { - "@types/unist": "*" + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" } }, - "node_modules/@types/mdx": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.10.tgz", - "integrity": "sha512-Rllzc5KHk0Al5/WANwgSPl1/CwjqCy+AZrGd78zuK+jO9aDM6ffblZ+zIjgPNAaEBmlO0RYDvLNh7wD0zKVgEg==" - }, - "node_modules/@types/mime": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", - "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" - }, - "node_modules/@types/ms": { - "version": "0.7.34", - "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", - "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==" + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "engines": { + "node": ">=6.0.0" + } }, - "node_modules/@types/node": { - "version": "20.11.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.5.tgz", - "integrity": "sha512-g557vgQjUUfN76MZAN/dt1z3dzcUsimuysco0KeluHgrPdJXkP/XdAURgyO2W9fZWHRtRBiVKzKn8vyOAwlG+w==", - "dependencies": { - "undici-types": "~5.26.4" + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "engines": { + "node": ">=6.0.0" } }, - "node_modules/@types/node-forge": { - "version": "1.3.11", - "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.11.tgz", - "integrity": "sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==", + "node_modules/@jridgewell/source-map": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", "dependencies": { - "@types/node": "*" + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" } }, - "node_modules/@types/parse-json": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", - "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==" - }, - "node_modules/@types/parse5": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/@types/parse5/-/parse5-5.0.3.tgz", - "integrity": "sha512-kUNnecmtkunAoQ3CnjmMkzNU/gtxG8guhi+Fk2U/kOpIKjIMKnXGp4IJCgQJrXSgMsWYimYG4TGjz/UzbGEBTw==" - }, - "node_modules/@types/prismjs": { - "version": "1.26.3", - "resolved": "https://registry.npmjs.org/@types/prismjs/-/prismjs-1.26.3.tgz", - "integrity": "sha512-A0D0aTXvjlqJ5ZILMz3rNfDBOx9hHxLZYv2by47Sm/pqW35zzjusrZTryatjN/Rf8Us2gZrJD+KeHbUSTux1Cw==" - }, - "node_modules/@types/prop-types": { - "version": "15.7.11", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz", - "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==" - }, - "node_modules/@types/qs": { - "version": "6.9.11", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.11.tgz", - "integrity": "sha512-oGk0gmhnEJK4Yyk+oI7EfXsLayXatCWPHary1MtcmbAifkobT9cM9yutG/hZKIseOU0MqbIwQ/u2nn/Gb+ltuQ==" - }, - "node_modules/@types/range-parser": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", - "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==" + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==" }, - "node_modules/@types/react": { - "version": "18.2.48", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.48.tgz", - "integrity": "sha512-qboRCl6Ie70DQQG9hhNREz81jqC1cs9EVNcjQ1AU+jH6NFfSAhVVbrrY/+nSF+Bsk4AOwm9Qa61InvMCyV+H3w==", + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dependencies": { - "@types/prop-types": "*", - "@types/scheduler": "*", - "csstype": "^3.0.2" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@types/react-router": { - "version": "5.1.20", - "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.20.tgz", - "integrity": "sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q==", + "node_modules/@leichtgewicht/ip-codec": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", + "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==" + }, + "node_modules/@mdx-js/mdx": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-3.1.0.tgz", + "integrity": "sha512-/QxEhPAvGwbQmy1Px8F899L5Uc2KZ6JtXwlCgJmjSTBedwOZkByYcBG4GceIGPXRDsmfxhHazuS+hlOShRLeDw==", "dependencies": { - "@types/history": "^4.7.11", - "@types/react": "*" + "@types/estree": "^1.0.0", + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdx": "^2.0.0", + "collapse-white-space": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "estree-util-scope": "^1.0.0", + "estree-walker": "^3.0.0", + "hast-util-to-jsx-runtime": "^2.0.0", + "markdown-extensions": "^2.0.0", + "recma-build-jsx": "^1.0.0", + "recma-jsx": "^1.0.0", + "recma-stringify": "^1.0.0", + "rehype-recma": "^1.0.0", + "remark-mdx": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-rehype": "^11.0.0", + "source-map": "^0.7.0", + "unified": "^11.0.0", + "unist-util-position-from-estree": "^2.0.0", + "unist-util-stringify-position": "^4.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/@types/react-router-config": { - "version": "5.0.11", - "resolved": "https://registry.npmjs.org/@types/react-router-config/-/react-router-config-5.0.11.tgz", - "integrity": "sha512-WmSAg7WgqW7m4x8Mt4N6ZyKz0BubSj/2tVUMsAHp+Yd2AMwcSbeFq9WympT19p5heCFmF97R9eD5uUR/t4HEqw==", + "node_modules/@mdx-js/react": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-3.1.0.tgz", + "integrity": "sha512-QjHtSaoameoalGnKDT3FoIl4+9RwyTmo9ZJGBdLOks/YOiWHoRDI3PUwEzOE7kEmGcV3AFcp9K6dYu9rEuKLAQ==", "dependencies": { - "@types/history": "^4.7.11", - "@types/react": "*", - "@types/react-router": "^5.1.0" + "@types/mdx": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + }, + "peerDependencies": { + "@types/react": ">=16", + "react": ">=16" } }, - "node_modules/@types/react-router-dom": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.3.3.tgz", - "integrity": "sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw==", + "node_modules/@mermaid-js/parser": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@mermaid-js/parser/-/parser-0.3.0.tgz", + "integrity": "sha512-HsvL6zgE5sUPGgkIDlmAWR1HTNHz2Iy11BAWPTa4Jjabkpguy4Ze2gzfLrg6pdRuBvFwgUYyxiaNqZwrEEXepA==", "dependencies": { - "@types/history": "^4.7.11", - "@types/react": "*", - "@types/react-router": "*" + "langium": "3.0.0" } }, - "node_modules/@types/retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==" - }, - "node_modules/@types/sax": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@types/sax/-/sax-1.2.7.tgz", - "integrity": "sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==", + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dependencies": { - "@types/node": "*" + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" } }, - "node_modules/@types/scheduler": { - "version": "0.16.8", - "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz", - "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==" - }, - "node_modules/@types/send": { - "version": "0.17.4", - "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", - "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", - "dependencies": { - "@types/mime": "^1", - "@types/node": "*" + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "engines": { + "node": ">= 8" } }, - "node_modules/@types/serve-index": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", - "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dependencies": { - "@types/express": "*" + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" } }, - "node_modules/@types/serve-static": { - "version": "1.15.5", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.5.tgz", - "integrity": "sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==", - "dependencies": { - "@types/http-errors": "*", - "@types/mime": "*", - "@types/node": "*" + "node_modules/@pnpm/config.env-replace": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz", + "integrity": "sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==", + "engines": { + "node": ">=12.22.0" } }, - "node_modules/@types/sockjs": { - "version": "0.3.36", - "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", - "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", + "node_modules/@pnpm/network.ca-file": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@pnpm/network.ca-file/-/network.ca-file-1.0.2.tgz", + "integrity": "sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==", "dependencies": { - "@types/node": "*" + "graceful-fs": "4.2.10" + }, + "engines": { + "node": ">=12.22.0" } }, - "node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + "node_modules/@pnpm/network.ca-file/node_modules/graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" }, - "node_modules/@types/ws": { - "version": "8.5.10", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", - "integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==", + "node_modules/@pnpm/npm-conf": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@pnpm/npm-conf/-/npm-conf-2.3.1.tgz", + "integrity": "sha512-c83qWb22rNRuB0UaVCI0uRPNRr8Z0FWnEIvT47jiHAmOIUHbBOg5XvV7pM5x+rKn9HRpjxquDbXYSXr3fAKFcw==", "dependencies": { - "@types/node": "*" + "@pnpm/config.env-replace": "^1.1.0", + "@pnpm/network.ca-file": "^1.0.1", + "config-chain": "^1.1.11" + }, + "engines": { + "node": ">=12" } }, - "node_modules/@types/yargs": { - "version": "17.0.32", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", - "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", - "dependencies": { - "@types/yargs-parser": "*" + "node_modules/@polka/url": { + "version": "1.0.0-next.28", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.28.tgz", + "integrity": "sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==" + }, + "node_modules/@sideway/address": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz", + "integrity": "sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==", + "dependencies": { + "@hapi/hoek": "^9.0.0" + } + }, + "node_modules/@sideway/formula": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz", + "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==" + }, + "node_modules/@sideway/pinpoint": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", + "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==" + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==" + }, + "node_modules/@sindresorhus/is": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/@slorber/remark-comment": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@slorber/remark-comment/-/remark-comment-1.0.0.tgz", + "integrity": "sha512-RCE24n7jsOj1M0UPvIQCHTe7fI0sFL4S2nwKVWwHyVr/wI/H8GosgsJGyhnsZoGFnD/P2hLf1mSbrrgSLN93NA==", + "dependencies": { + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.1.0", + "micromark-util-symbol": "^1.0.1" + } + }, + "node_modules/@svgr/babel-plugin-add-jsx-attribute": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz", + "integrity": "sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-remove-jsx-attribute": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-8.0.0.tgz", + "integrity": "sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA==", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-remove-jsx-empty-expression": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-8.0.0.tgz", + "integrity": "sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA==", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-replace-jsx-attribute-value": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-8.0.0.tgz", + "integrity": "sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ==", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-svg-dynamic-title": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-8.0.0.tgz", + "integrity": "sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og==", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-svg-em-dimensions": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-8.0.0.tgz", + "integrity": "sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g==", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-transform-react-native-svg": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-8.1.0.tgz", + "integrity": "sha512-Tx8T58CHo+7nwJ+EhUwx3LfdNSG9R2OKfaIXXs5soiy5HtgoAEkDay9LIimLOcG8dJQH1wPZp/cnAv6S9CrR1Q==", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-transform-svg-component": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-8.0.0.tgz", + "integrity": "sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw==", + "engines": { + "node": ">=12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-preset": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-8.1.0.tgz", + "integrity": "sha512-7EYDbHE7MxHpv4sxvnVPngw5fuR6pw79SkcrILHJ/iMpuKySNCl5W1qcwPEpU+LgyRXOaAFgH0KhwD18wwg6ug==", + "dependencies": { + "@svgr/babel-plugin-add-jsx-attribute": "8.0.0", + "@svgr/babel-plugin-remove-jsx-attribute": "8.0.0", + "@svgr/babel-plugin-remove-jsx-empty-expression": "8.0.0", + "@svgr/babel-plugin-replace-jsx-attribute-value": "8.0.0", + "@svgr/babel-plugin-svg-dynamic-title": "8.0.0", + "@svgr/babel-plugin-svg-em-dimensions": "8.0.0", + "@svgr/babel-plugin-transform-react-native-svg": "8.1.0", + "@svgr/babel-plugin-transform-svg-component": "8.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/core": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/core/-/core-8.1.0.tgz", + "integrity": "sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==", + "dependencies": { + "@babel/core": "^7.21.3", + "@svgr/babel-preset": "8.1.0", + "camelcase": "^6.2.0", + "cosmiconfig": "^8.1.3", + "snake-case": "^3.0.4" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/hast-util-to-babel-ast": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-8.0.0.tgz", + "integrity": "sha512-EbDKwO9GpfWP4jN9sGdYwPBU0kdomaPIL2Eu4YwmgP+sJeXT+L7bMwJUBnhzfH8Q2qMBqZ4fJwpCyYsAN3mt2Q==", + "dependencies": { + "@babel/types": "^7.21.3", + "entities": "^4.4.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/plugin-jsx": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-8.1.0.tgz", + "integrity": "sha512-0xiIyBsLlr8quN+WyuxooNW9RJ0Dpr8uOnH/xrCVO8GLUcwHISwj1AG0k+LFzteTkAA0GbX0kj9q6Dk70PTiPA==", + "dependencies": { + "@babel/core": "^7.21.3", + "@svgr/babel-preset": "8.1.0", + "@svgr/hast-util-to-babel-ast": "8.0.0", + "svg-parser": "^2.0.4" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@svgr/core": "*" + } + }, + "node_modules/@svgr/plugin-svgo": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-8.1.0.tgz", + "integrity": "sha512-Ywtl837OGO9pTLIN/onoWLmDQ4zFUycI1g76vuKGEz6evR/ZTJlJuz3G/fIkb6OVBJ2g0o6CGJzaEjfmEo3AHA==", + "dependencies": { + "cosmiconfig": "^8.1.3", + "deepmerge": "^4.3.1", + "svgo": "^3.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@svgr/core": "*" + } + }, + "node_modules/@svgr/webpack": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-8.1.0.tgz", + "integrity": "sha512-LnhVjMWyMQV9ZmeEy26maJk+8HTIbd59cH4F2MJ439k9DqejRisfFNGAPvRYlKETuh9LrImlS8aKsBgKjMA8WA==", + "dependencies": { + "@babel/core": "^7.21.3", + "@babel/plugin-transform-react-constant-elements": "^7.21.3", + "@babel/preset-env": "^7.20.2", + "@babel/preset-react": "^7.18.6", + "@babel/preset-typescript": "^7.21.0", + "@svgr/core": "8.1.0", + "@svgr/plugin-jsx": "8.1.0", + "@svgr/plugin-svgo": "8.1.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@szmarczak/http-timer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", + "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", + "dependencies": { + "defer-to-connect": "^2.0.1" + }, + "engines": { + "node": ">=14.16" + } + }, + "node_modules/@trysound/sax": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", + "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/@types/acorn": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@types/acorn/-/acorn-4.0.6.tgz", + "integrity": "sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ==", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/bonjour": { + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", + "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect-history-api-fallback": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", + "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", + "dependencies": { + "@types/express-serve-static-core": "*", + "@types/node": "*" + } + }, + "node_modules/@types/d3": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/@types/d3/-/d3-7.4.3.tgz", + "integrity": "sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww==", + "dependencies": { + "@types/d3-array": "*", + "@types/d3-axis": "*", + "@types/d3-brush": "*", + "@types/d3-chord": "*", + "@types/d3-color": "*", + "@types/d3-contour": "*", + "@types/d3-delaunay": "*", + "@types/d3-dispatch": "*", + "@types/d3-drag": "*", + "@types/d3-dsv": "*", + "@types/d3-ease": "*", + "@types/d3-fetch": "*", + "@types/d3-force": "*", + "@types/d3-format": "*", + "@types/d3-geo": "*", + "@types/d3-hierarchy": "*", + "@types/d3-interpolate": "*", + "@types/d3-path": "*", + "@types/d3-polygon": "*", + "@types/d3-quadtree": "*", + "@types/d3-random": "*", + "@types/d3-scale": "*", + "@types/d3-scale-chromatic": "*", + "@types/d3-selection": "*", + "@types/d3-shape": "*", + "@types/d3-time": "*", + "@types/d3-time-format": "*", + "@types/d3-timer": "*", + "@types/d3-transition": "*", + "@types/d3-zoom": "*" + } + }, + "node_modules/@types/d3-array": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.1.tgz", + "integrity": "sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==" + }, + "node_modules/@types/d3-axis": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-axis/-/d3-axis-3.0.6.tgz", + "integrity": "sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw==", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-brush": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-brush/-/d3-brush-3.0.6.tgz", + "integrity": "sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A==", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-chord": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-chord/-/d3-chord-3.0.6.tgz", + "integrity": "sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg==" + }, + "node_modules/@types/d3-color": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz", + "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==" + }, + "node_modules/@types/d3-contour": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-contour/-/d3-contour-3.0.6.tgz", + "integrity": "sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg==", + "dependencies": { + "@types/d3-array": "*", + "@types/geojson": "*" + } + }, + "node_modules/@types/d3-delaunay": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-delaunay/-/d3-delaunay-6.0.4.tgz", + "integrity": "sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==" + }, + "node_modules/@types/d3-dispatch": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-dispatch/-/d3-dispatch-3.0.6.tgz", + "integrity": "sha512-4fvZhzMeeuBJYZXRXrRIQnvUYfyXwYmLsdiN7XXmVNQKKw1cM8a5WdID0g1hVFZDqT9ZqZEY5pD44p24VS7iZQ==" + }, + "node_modules/@types/d3-drag": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-3.0.7.tgz", + "integrity": "sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-dsv": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@types/d3-dsv/-/d3-dsv-3.0.7.tgz", + "integrity": "sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g==" + }, + "node_modules/@types/d3-ease": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz", + "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==" + }, + "node_modules/@types/d3-fetch": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@types/d3-fetch/-/d3-fetch-3.0.7.tgz", + "integrity": "sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA==", + "dependencies": { + "@types/d3-dsv": "*" + } + }, + "node_modules/@types/d3-force": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@types/d3-force/-/d3-force-3.0.10.tgz", + "integrity": "sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw==" + }, + "node_modules/@types/d3-format": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-3.0.4.tgz", + "integrity": "sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g==" + }, + "node_modules/@types/d3-geo": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/d3-geo/-/d3-geo-3.1.0.tgz", + "integrity": "sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ==", + "dependencies": { + "@types/geojson": "*" + } + }, + "node_modules/@types/d3-hierarchy": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-3.1.7.tgz", + "integrity": "sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg==" + }, + "node_modules/@types/d3-interpolate": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz", + "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==", + "dependencies": { + "@types/d3-color": "*" + } + }, + "node_modules/@types/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-P2dlU/q51fkOc/Gfl3Ul9kicV7l+ra934qBFXCFhrZMOL6du1TM0pm1ThYvENukyOn5h9v+yMJ9Fn5JK4QozrQ==" + }, + "node_modules/@types/d3-polygon": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-polygon/-/d3-polygon-3.0.2.tgz", + "integrity": "sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA==" + }, + "node_modules/@types/d3-quadtree": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-quadtree/-/d3-quadtree-3.0.6.tgz", + "integrity": "sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg==" + }, + "node_modules/@types/d3-random": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-random/-/d3-random-3.0.3.tgz", + "integrity": "sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ==" + }, + "node_modules/@types/d3-scale": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.8.tgz", + "integrity": "sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ==", + "dependencies": { + "@types/d3-time": "*" + } + }, + "node_modules/@types/d3-scale-chromatic": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz", + "integrity": "sha512-iWMJgwkK7yTRmWqRB5plb1kadXyQ5Sj8V/zYlFGMUBbIPKQScw+Dku9cAAMgJG+z5GYDoMjWGLVOvjghDEFnKQ==" + }, + "node_modules/@types/d3-selection": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.11.tgz", + "integrity": "sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w==" + }, + "node_modules/@types/d3-shape": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.6.tgz", + "integrity": "sha512-5KKk5aKGu2I+O6SONMYSNflgiP0WfZIQvVUMan50wHsLG1G94JlxEVnCpQARfTtzytuY0p/9PXXZb3I7giofIA==", + "dependencies": { + "@types/d3-path": "*" + } + }, + "node_modules/@types/d3-time": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.4.tgz", + "integrity": "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==" + }, + "node_modules/@types/d3-time-format": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-4.0.3.tgz", + "integrity": "sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg==" + }, + "node_modules/@types/d3-timer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz", + "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==" + }, + "node_modules/@types/d3-transition": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-3.0.9.tgz", + "integrity": "sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-zoom": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.8.tgz", + "integrity": "sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==", + "dependencies": { + "@types/d3-interpolate": "*", + "@types/d3-selection": "*" + } + }, + "node_modules/@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/@types/eslint": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", + "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==" + }, + "node_modules/@types/estree-jsx": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.5.tgz", + "integrity": "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/@types/express": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.0.2.tgz", + "integrity": "sha512-vluaspfvWEtE4vcSDlKRNer52DvOGrB2xv6diXy6UKyKW0lqZiWHGNApSyxOv+8DE5Z27IzVvE7hNkxg7EXIcg==", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/express/node_modules/@types/express-serve-static-core": { + "version": "4.19.6", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz", + "integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/geojson": { + "version": "7946.0.15", + "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.15.tgz", + "integrity": "sha512-9oSxFzDCT2Rj6DfcHF8G++jxBKS7mBqXl5xrRW+Kbvjry6Uduya2iiwqHPhVXpasAVMBYKkEPGgKhd3+/HZ6xA==" + }, + "node_modules/@types/gtag.js": { + "version": "0.0.12", + "resolved": "https://registry.npmjs.org/@types/gtag.js/-/gtag.js-0.0.12.tgz", + "integrity": "sha512-YQV9bUsemkzG81Ea295/nF/5GijnD2Af7QhEofh7xu+kvCN6RdodgNwwGWXB5GMI3NoyvQo0odNctoH/qLMIpg==" + }, + "node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/history": { + "version": "4.7.11", + "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.11.tgz", + "integrity": "sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==" + }, + "node_modules/@types/html-minifier-terser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", + "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==" + }, + "node_modules/@types/http-cache-semantics": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", + "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==" + }, + "node_modules/@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==" + }, + "node_modules/@types/http-proxy": { + "version": "1.17.15", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.15.tgz", + "integrity": "sha512-25g5atgiVNTIv0LBDTg1H74Hvayx0ajtJPLLcYE3whFv75J0pWNtOBzaXJQgDTmrX1bx5U9YC2w/n65BN1HwRQ==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==" + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==" + }, + "node_modules/@types/mdast": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", + "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/mdx": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.13.tgz", + "integrity": "sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==" + }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" + }, + "node_modules/@types/ms": { + "version": "0.7.34", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", + "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==" + }, + "node_modules/@types/node": { + "version": "22.10.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.2.tgz", + "integrity": "sha512-Xxr6BBRCAOQixvonOye19wnzyDiUtTeqldOOmj3CkeblonbccA12PFwlufvRdrpjXxqnmUaeiU5EOA+7s5diUQ==", + "dependencies": { + "undici-types": "~6.20.0" + } + }, + "node_modules/@types/node-forge": { + "version": "1.3.11", + "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.11.tgz", + "integrity": "sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/parse-json": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", + "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==" + }, + "node_modules/@types/parse5": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@types/parse5/-/parse5-5.0.3.tgz", + "integrity": "sha512-kUNnecmtkunAoQ3CnjmMkzNU/gtxG8guhi+Fk2U/kOpIKjIMKnXGp4IJCgQJrXSgMsWYimYG4TGjz/UzbGEBTw==" + }, + "node_modules/@types/prismjs": { + "version": "1.26.5", + "resolved": "https://registry.npmjs.org/@types/prismjs/-/prismjs-1.26.5.tgz", + "integrity": "sha512-AUZTa7hQ2KY5L7AmtSiqxlhWxb4ina0yd8hNbl4TWuqnv/pFP0nDMb3YrfSBf4hJVGLh2YEIBfKaBW/9UEl6IQ==" + }, + "node_modules/@types/prop-types": { + "version": "15.7.14", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.14.tgz", + "integrity": "sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==" + }, + "node_modules/@types/qs": { + "version": "6.9.17", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.17.tgz", + "integrity": "sha512-rX4/bPcfmvxHDv0XjfJELTTr+iB+tn032nPILqHm5wbthUUUuVtNGGqzhya9XUxjTP8Fpr0qYgSZZKxGY++svQ==" + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==" + }, + "node_modules/@types/react": { + "version": "18.3.16", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.16.tgz", + "integrity": "sha512-oh8AMIC4Y2ciKufU8hnKgs+ufgbA/dhPTACaZPM86AbwX9QwnFtSoPWEeRUj8fge+v6kFt78BXcDhAU1SrrAsw==", + "dependencies": { + "@types/prop-types": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-router": { + "version": "5.1.20", + "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.20.tgz", + "integrity": "sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q==", + "dependencies": { + "@types/history": "^4.7.11", + "@types/react": "*" + } + }, + "node_modules/@types/react-router-config": { + "version": "5.0.11", + "resolved": "https://registry.npmjs.org/@types/react-router-config/-/react-router-config-5.0.11.tgz", + "integrity": "sha512-WmSAg7WgqW7m4x8Mt4N6ZyKz0BubSj/2tVUMsAHp+Yd2AMwcSbeFq9WympT19p5heCFmF97R9eD5uUR/t4HEqw==", + "dependencies": { + "@types/history": "^4.7.11", + "@types/react": "*", + "@types/react-router": "^5.1.0" + } + }, + "node_modules/@types/react-router-dom": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.3.3.tgz", + "integrity": "sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw==", + "dependencies": { + "@types/history": "^4.7.11", + "@types/react": "*", + "@types/react-router": "*" + } + }, + "node_modules/@types/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==" + }, + "node_modules/@types/sax": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/sax/-/sax-1.2.7.tgz", + "integrity": "sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-index": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", + "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", + "dependencies": { + "@types/express": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.7", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", + "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "*" + } + }, + "node_modules/@types/sockjs": { + "version": "0.3.36", + "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", + "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/trusted-types": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", + "optional": true + }, + "node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==" + }, + "node_modules/@types/ws": { + "version": "8.5.13", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.13.tgz", + "integrity": "sha512-osM/gWBTPKgHV8XkTunnegTRIsvF6owmf5w+JtAfOw472dptdm0dlGv4xCt6GwQRcC2XVOvvRE/0bAoQcL2QkA==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/yargs": { + "version": "17.0.33", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", + "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==", + "dependencies": { + "@types/yargs-parser": "*" } }, "node_modules/@types/yargs-parser": { @@ -3702,9 +5008,9 @@ "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==" }, "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==" + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.1.tgz", + "integrity": "sha512-fEzPV3hSkSMltkw152tJKNARhOupqbH96MZWyRjNaYZOMIzbrTeQDG+MTc6Mr2pgzFQzFxAfmhGDNP5QK++2ZA==" }, "node_modules/@webassemblyjs/ast": { "version": "1.14.1", @@ -3883,6 +5189,14 @@ "node": ">= 0.6" } }, + "node_modules/accepts/node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/acorn": { "version": "8.14.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", @@ -3903,9 +5217,12 @@ } }, "node_modules/acorn-walk": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", - "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", + "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", + "dependencies": { + "acorn": "^8.11.0" + }, "engines": { "node": ">=0.4.0" } @@ -3931,14 +5248,14 @@ } }, "node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dependencies": { - "fast-deep-equal": "^3.1.1", + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" + "require-from-string": "^2.0.2" }, "funding": { "type": "github", @@ -3973,30 +5290,31 @@ } }, "node_modules/algoliasearch": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-4.22.1.tgz", - "integrity": "sha512-jwydKFQJKIx9kIZ8Jm44SdpigFwRGPESaxZBaHSV0XWN2yBJAOT4mT7ppvlrpA4UGzz92pqFnVKr/kaZXrcreg==", - "dependencies": { - "@algolia/cache-browser-local-storage": "4.22.1", - "@algolia/cache-common": "4.22.1", - "@algolia/cache-in-memory": "4.22.1", - "@algolia/client-account": "4.22.1", - "@algolia/client-analytics": "4.22.1", - "@algolia/client-common": "4.22.1", - "@algolia/client-personalization": "4.22.1", - "@algolia/client-search": "4.22.1", - "@algolia/logger-common": "4.22.1", - "@algolia/logger-console": "4.22.1", - "@algolia/requester-browser-xhr": "4.22.1", - "@algolia/requester-common": "4.22.1", - "@algolia/requester-node-http": "4.22.1", - "@algolia/transporter": "4.22.1" + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-4.24.0.tgz", + "integrity": "sha512-bf0QV/9jVejssFBmz2HQLxUadxk574t4iwjCKp5E7NBzwKkrDEhKPISIIjAU/p6K5qDx3qoeh4+26zWN1jmw3g==", + "dependencies": { + "@algolia/cache-browser-local-storage": "4.24.0", + "@algolia/cache-common": "4.24.0", + "@algolia/cache-in-memory": "4.24.0", + "@algolia/client-account": "4.24.0", + "@algolia/client-analytics": "4.24.0", + "@algolia/client-common": "4.24.0", + "@algolia/client-personalization": "4.24.0", + "@algolia/client-search": "4.24.0", + "@algolia/logger-common": "4.24.0", + "@algolia/logger-console": "4.24.0", + "@algolia/recommend": "4.24.0", + "@algolia/requester-browser-xhr": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/requester-node-http": "4.24.0", + "@algolia/transporter": "4.24.0" } }, "node_modules/algoliasearch-helper": { - "version": "3.16.2", - "resolved": "https://registry.npmjs.org/algoliasearch-helper/-/algoliasearch-helper-3.16.2.tgz", - "integrity": "sha512-Yl/Gu5Cq4Z5s/AJ0jR37OPI1H3+z7PHz657ibyaXgMOaWvPlZ3OACN13N+7HCLPUlB0BN+8BtmrG/CqTilowBA==", + "version": "3.22.6", + "resolved": "https://registry.npmjs.org/algoliasearch-helper/-/algoliasearch-helper-3.22.6.tgz", + "integrity": "sha512-F2gSb43QHyvZmvH/2hxIjbk/uFdO2MguQYTFP7J+RowMW1csjIODMobEnpLI8nbLQuzZnGZdIxl5Bpy1k9+CFQ==", "dependencies": { "@algolia/events": "^4.0.1" }, @@ -4004,6 +5322,41 @@ "algoliasearch": ">= 3.1 < 6" } }, + "node_modules/algoliasearch/node_modules/@algolia/client-common": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.24.0.tgz", + "integrity": "sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA==", + "dependencies": { + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/algoliasearch/node_modules/@algolia/client-search": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.24.0.tgz", + "integrity": "sha512-uRW6EpNapmLAD0mW47OXqTP8eiIx5F6qN9/x/7HHO6owL3N1IXqydGwW5nhDFBrV+ldouro2W1VX3XlcUXEFCA==", + "dependencies": { + "@algolia/client-common": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/algoliasearch/node_modules/@algolia/requester-browser-xhr": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.24.0.tgz", + "integrity": "sha512-Z2NxZMb6+nVXSjF13YpjYTdvV3032YTBSGm2vnYvYPA6mMxzM3v5rsCiSspndn9rzIW4Qp1lPHBvuoKJV6jnAA==", + "dependencies": { + "@algolia/requester-common": "4.24.0" + } + }, + "node_modules/algoliasearch/node_modules/@algolia/requester-node-http": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-4.24.0.tgz", + "integrity": "sha512-JF18yTjNOVYvU/L3UosRcvbPMGT9B+/GQWNWnenIImglzNVGpyzChkXLnrSf6uxwVNO6ESGu6oN8MqcGQcjQJw==", + "dependencies": { + "@algolia/requester-common": "4.24.0" + } + }, "node_modules/ansi-align": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", @@ -4030,6 +5383,31 @@ "node": ">=8" } }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/ansi-html-community": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", @@ -4104,9 +5482,9 @@ } }, "node_modules/astring": { - "version": "1.8.6", - "resolved": "https://registry.npmjs.org/astring/-/astring-1.8.6.tgz", - "integrity": "sha512-ISvCdHdlTDlH5IpxQJIex7BWBywFWgjJSVdwst+/iQCoEYnyOaQ95+X1JGshuBjGp6nxKUy1jMgE3zPqN7fQdg==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/astring/-/astring-1.9.0.tgz", + "integrity": "sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==", "bin": { "astring": "bin/astring" } @@ -4128,9 +5506,9 @@ } }, "node_modules/autoprefixer": { - "version": "10.4.17", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.17.tgz", - "integrity": "sha512-/cpVNRLSfhOtcGflT13P2794gVSgmPgTR+erw5ifnMLZb0UnSlkK4tquLmkd3BhA+nLo5tX8Cu0upUsGKvKbmg==", + "version": "10.4.20", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz", + "integrity": "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==", "funding": [ { "type": "opencollective", @@ -4146,11 +5524,11 @@ } ], "dependencies": { - "browserslist": "^4.22.2", - "caniuse-lite": "^1.0.30001578", + "browserslist": "^4.23.3", + "caniuse-lite": "^1.0.30001646", "fraction.js": "^4.3.7", "normalize-range": "^0.1.2", - "picocolors": "^1.0.0", + "picocolors": "^1.0.1", "postcss-value-parser": "^4.2.0" }, "bin": { @@ -4164,9 +5542,9 @@ } }, "node_modules/babel-loader": { - "version": "9.1.3", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.1.3.tgz", - "integrity": "sha512-xG3ST4DglodGf8qSwv0MdeWLhrDsw/32QMdTO5T1ZIp9gQur0HkCyFs7Awskr10JKXFXwpAhiCuYX5oGXnRGbw==", + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.2.1.tgz", + "integrity": "sha512-fqe8naHt46e0yIdkjUZYqddSXfej3AHajX+CSO5X7oy0EmPc6o5Xh+RClNoHjnieWz9AW4kZxW9yyFMhVB1QLA==", "dependencies": { "find-cache-dir": "^4.0.0", "schema-utils": "^4.0.0" @@ -4188,12 +5566,12 @@ } }, "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.8", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.8.tgz", - "integrity": "sha512-OtIuQfafSzpo/LhnJaykc0R/MMnuLSSVjVYy9mHArIZ9qTCSZ6TpWCuEKZYVoN//t8HqBNScHrOtCrIK5IaGLg==", + "version": "0.4.12", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.12.tgz", + "integrity": "sha512-CPWT6BwvhrTO2d8QVorhTCQw9Y43zOu7G9HigcfxvepOU6b8o3tcWad6oVgZIsZCTt42FFv97aA7ZJsbM4+8og==", "dependencies": { "@babel/compat-data": "^7.22.6", - "@babel/helper-define-polyfill-provider": "^0.5.0", + "@babel/helper-define-polyfill-provider": "^0.6.3", "semver": "^6.3.1" }, "peerDependencies": { @@ -4209,38 +5587,23 @@ } }, "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.8.7", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.7.tgz", - "integrity": "sha512-KyDvZYxAzkC0Aj2dAPyDzi2Ym15e5JKZSK+maI7NAwSqofvuFglbSsxE7wUOvTg9oFVnHMzVzBKcqEb4PJgtOA==", - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.4.4", - "core-js-compat": "^3.33.1" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/babel-plugin-polyfill-corejs3/node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.4.tgz", - "integrity": "sha512-QcJMILQCu2jm5TFPGA3lCpJJTeEP+mqeXooG/NZbg/h5FTFi6V0+99ahlRsW8/kRLyb24LZVCCiclDedhLKcBA==", + "version": "0.10.6", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.6.tgz", + "integrity": "sha512-b37+KR2i/khY5sKmWNVQAnitvquQbNdWy6lJdsr0kmquCKEEUgMKK4SboVM3HtfnZilfjr4MMQ7vY58FVWDtIA==", "dependencies": { - "@babel/helper-compilation-targets": "^7.22.6", - "@babel/helper-plugin-utils": "^7.22.5", - "debug": "^4.1.1", - "lodash.debounce": "^4.0.8", - "resolve": "^1.14.2" + "@babel/helper-define-polyfill-provider": "^0.6.2", + "core-js-compat": "^3.38.0" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.5.tgz", - "integrity": "sha512-OJGYZlhLqBh2DDHeqAxWB1XIvr49CxiJ2gIt61/PU55CQK4Z58OzMqjDe1zwQdQk+rBYsRc+1rJmdajM3gimHg==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.3.tgz", + "integrity": "sha512-LiWSbl4CRSIa5x/JAU6jZiG9eit9w6mz+yVMFwDE83LAWvt0AfGBoZ7HS/mkhrKuh2ZlzfVZYKoLjXdqw6Yt7Q==", "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.5.0" + "@babel/helper-define-polyfill-provider": "^0.6.3" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" @@ -4283,11 +5646,14 @@ } }, "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/body-parser": { @@ -4326,7 +5692,18 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dependencies": { - "ms": "2.0.0" + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" } }, "node_modules/body-parser/node_modules/ms": { @@ -4335,9 +5712,9 @@ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "node_modules/bonjour-service": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.2.1.tgz", - "integrity": "sha512-oSzCS2zV14bh2kji6vNe7vrpJYCHGvcZnlffFQ1MEoX/WOeQ/teD8SYWKR942OI3INjq8OMNJlbPK5LLLUxFDw==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.3.0.tgz", + "integrity": "sha512-3YuAUiSkWykd+2Azjgyxei8OWf8thdn8AITIog2M4UICzoqfjlqr64WIjEXZllf/W6vK1goqleSR6brGomxQqA==", "dependencies": { "fast-deep-equal": "^3.1.3", "multicast-dns": "^7.2.5" @@ -4390,9 +5767,9 @@ } }, "node_modules/browserslist": { - "version": "4.24.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz", - "integrity": "sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==", + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.3.tgz", + "integrity": "sha512-1CPmv8iobE2fyRMV97dAcMVegvvWKxmq94hkLiAkUGwKVTyDLw33K+ZxiFrREKmmps4rIw6grcCFCnTMSZ/YiA==", "funding": [ { "type": "opencollective", @@ -4408,9 +5785,9 @@ } ], "dependencies": { - "caniuse-lite": "^1.0.30001669", - "electron-to-chromium": "^1.5.41", - "node-releases": "^2.0.18", + "caniuse-lite": "^1.0.30001688", + "electron-to-chromium": "^1.5.73", + "node-releases": "^2.0.19", "update-browserslist-db": "^1.1.1" }, "bin": { @@ -4458,17 +5835,6 @@ "node": ">=14.16" } }, - "node_modules/cacheable-request/node_modules/normalize-url": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.0.tgz", - "integrity": "sha512-uVFpKhj5MheNBJRTiMZ9pE/7hD1QTeEvugSJW/OmLzAp78PB5O6adfMNTvmfKhXBkvCzC+rqifWcVYpGFwTjnw==", - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/call-bind": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", @@ -4675,16 +6041,34 @@ "url": "https://github.com/sponsors/fb55" } }, + "node_modules/chevrotain": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-11.0.3.tgz", + "integrity": "sha512-ci2iJH6LeIkvP9eJW6gpueU8cnZhv85ELY8w8WiFtNjMHA5ad6pQLaJo9mEly/9qUyCpvqX8/POVUTf18/HFdw==", + "dependencies": { + "@chevrotain/cst-dts-gen": "11.0.3", + "@chevrotain/gast": "11.0.3", + "@chevrotain/regexp-to-ast": "11.0.3", + "@chevrotain/types": "11.0.3", + "@chevrotain/utils": "11.0.3", + "lodash-es": "4.17.21" + } + }, + "node_modules/chevrotain-allstar": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/chevrotain-allstar/-/chevrotain-allstar-0.3.1.tgz", + "integrity": "sha512-b7g+y9A0v4mxCW1qUhf3BSVPg+/NvGErk/dOkrDaHA0nQIQGAtrOjlX//9OQtRlSCy+x9rfB5N8yC71lH1nvMw==", + "dependencies": { + "lodash-es": "^4.17.21" + }, + "peerDependencies": { + "chevrotain": "^11.0.0" + } + }, "node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -4697,14 +6081,17 @@ "engines": { "node": ">= 8.10.0" }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "node_modules/chrome-trace-event": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", - "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", + "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", "engines": { "node": ">=6.0" } @@ -4762,9 +6149,9 @@ } }, "node_modules/cli-table3": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.3.tgz", - "integrity": "sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==", + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.5.tgz", + "integrity": "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==", "dependencies": { "string-width": "^4.2.0" }, @@ -4806,21 +6193,10 @@ "node": ">=6" } }, - "node_modules/clone-deep/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/clsx": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.0.tgz", - "integrity": "sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", "engines": { "node": ">=6" } @@ -4877,9 +6253,9 @@ } }, "node_modules/comma-separated-tokens": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", - "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz", + "integrity": "sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -4910,30 +6286,38 @@ } }, "node_modules/compressible/node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "version": "1.53.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.53.0.tgz", + "integrity": "sha512-oHlN/w+3MQ3rba9rqFr6V/ypF10LSkdwUysQL7GkXoTgIWeV+tcXGA852TBxH+gsh8UWoyhR1hKcoMJTuWflpg==", "engines": { "node": ">= 0.6" } }, "node_modules/compression": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", - "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.5.tgz", + "integrity": "sha512-bQJ0YRck5ak3LgtnpKkiabX5pNF7tMUh1BSy2ZBOTh0Dim0BUu6aPPwByIns6/A5Prh8PufSPerMDUklpzes2Q==", "dependencies": { - "accepts": "~1.3.5", - "bytes": "3.0.0", - "compressible": "~2.0.16", + "bytes": "3.1.2", + "compressible": "~2.0.18", "debug": "2.6.9", + "negotiator": "~0.6.4", "on-headers": "~1.0.2", - "safe-buffer": "5.1.2", + "safe-buffer": "5.2.1", "vary": "~1.1.2" }, "engines": { "node": ">= 0.8.0" } }, + "node_modules/compression/node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/compression/node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -4947,16 +6331,16 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, - "node_modules/compression/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, + "node_modules/confbox": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", + "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==" + }, "node_modules/config-chain": { "version": "1.1.13", "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", @@ -4993,9 +6377,12 @@ } }, "node_modules/consola": { - "version": "2.15.3", - "resolved": "https://registry.npmjs.org/consola/-/consola-2.15.3.tgz", - "integrity": "sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==" + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/consola/-/consola-3.2.3.tgz", + "integrity": "sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==", + "engines": { + "node": "^14.18.0 || >=16.10.0" + } }, "node_modules/console-control-strings": { "version": "1.1.0", @@ -5111,9 +6498,9 @@ } }, "node_modules/core-js": { - "version": "3.35.0", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.35.0.tgz", - "integrity": "sha512-ntakECeqg81KqMueeGJ79Q5ZgQNR+6eaE8sxGCx62zMbAIj65q+uYvatToew3m6eAGdU4gNZwpZ34NMe4GYswg==", + "version": "3.39.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.39.0.tgz", + "integrity": "sha512-raM0ew0/jJUqkJ0E6e8UDtl+y/7ktFivgWvqw8dNSQeNWoSDLvQ1H/RN3aPXB9tBd4/FhyR4RDPGhsNIMsAn7g==", "hasInstallScript": true, "funding": { "type": "opencollective", @@ -5121,11 +6508,11 @@ } }, "node_modules/core-js-compat": { - "version": "3.35.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.35.0.tgz", - "integrity": "sha512-5blwFAddknKeNgsjBzilkdQ0+YK8L1PfqPYq40NOYMYFSS38qj+hpTcLLWwpIwA2A5bje/x5jmVn2tzUMg9IVw==", + "version": "3.39.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.39.0.tgz", + "integrity": "sha512-VgEUx3VwlExr5no0tXlBt+silBvhTryPwCXRI2Id1PN8WTKu7MreethvddqOubrYxkFdv/RnYrqlv1sFNAUelw==", "dependencies": { - "browserslist": "^4.22.2" + "browserslist": "^4.24.2" }, "funding": { "type": "opencollective", @@ -5133,9 +6520,9 @@ } }, "node_modules/core-js-pure": { - "version": "3.35.0", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.35.0.tgz", - "integrity": "sha512-f+eRYmkou59uh7BPcyJ8MC76DiGhspj1KMxVIcF24tzP8NA9HVa1uC7BTW2tgx7E1QVCzDzsgp7kArrzhlz8Ew==", + "version": "3.39.0", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.39.0.tgz", + "integrity": "sha512-7fEcWwKI4rJinnK+wLTezeg2smbFFdSBP6E2kQZNbnzM2s1rpKQ6aaRteZSSg7FLU3P0HGGVo/gbpfanU36urg==", "hasInstallScript": true, "funding": { "type": "opencollective", @@ -5156,18 +6543,28 @@ } }, "node_modules/cosmiconfig": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", - "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "version": "8.3.6", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", + "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", "dependencies": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.2.1", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0", + "path-type": "^4.0.0" }, "engines": { - "node": ">=10" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, "node_modules/cross-spawn": { @@ -5208,27 +6605,122 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/css-blank-pseudo": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/css-blank-pseudo/-/css-blank-pseudo-7.0.1.tgz", + "integrity": "sha512-jf+twWGDf6LDoXDUode+nc7ZlrqfaNphrBIBrcmeP3D8yw1uPaix1gCC8LUQUGQ6CycuK2opkbFFWFuq/a94ag==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/css-blank-pseudo/node_modules/postcss-selector-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz", + "integrity": "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/css-declaration-sorter": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.4.1.tgz", - "integrity": "sha512-rtdthzxKuyq6IzqX6jEcIzQF/YqccluefyCYheovBOLhFT/drQA9zj/UbRAa9J7C0o6EG6u3E6g+vKkay7/k3g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-7.2.0.tgz", + "integrity": "sha512-h70rUM+3PNFuaBDTLe8wF/cdWu+dOZmb7pJt8Z2sedYbAcQVQV/tEchueg3GWxwqS0cxtbxmaHEdkNACqcvsow==", "engines": { - "node": "^10 || ^12 || >=14" + "node": "^14 || ^16 || >=18" }, "peerDependencies": { "postcss": "^8.0.9" } }, + "node_modules/css-has-pseudo": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/css-has-pseudo/-/css-has-pseudo-7.0.2.tgz", + "integrity": "sha512-nzol/h+E0bId46Kn2dQH5VElaknX2Sr0hFuB/1EomdC7j+OISt2ZzK7EHX9DZDY53WbIVAR7FYKSO2XnSf07MQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "@csstools/selector-specificity": "^5.0.0", + "postcss-selector-parser": "^7.0.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/css-has-pseudo/node_modules/@csstools/selector-specificity": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-5.0.0.tgz", + "integrity": "sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss-selector-parser": "^7.0.0" + } + }, + "node_modules/css-has-pseudo/node_modules/postcss-selector-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz", + "integrity": "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/css-loader": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.9.0.tgz", - "integrity": "sha512-3I5Nu4ytWlHvOP6zItjiHlefBNtrH+oehq8tnQa2kO305qpVyx9XNIT1CXIj5bgCJs7qICBCkgCYxQLKPANoLA==", + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.11.0.tgz", + "integrity": "sha512-CTJ+AEQJjq5NzLga5pE39qdiSV56F8ywCIsqNIRF0r7BDgWsN25aazToqAFg7ZrtA/U016xudB3ffgweORxX7g==", "dependencies": { "icss-utils": "^5.1.0", - "postcss": "^8.4.31", - "postcss-modules-extract-imports": "^3.0.0", - "postcss-modules-local-by-default": "^4.0.3", - "postcss-modules-scope": "^3.1.0", + "postcss": "^8.4.33", + "postcss-modules-extract-imports": "^3.1.0", + "postcss-modules-local-by-default": "^4.0.5", + "postcss-modules-scope": "^3.2.0", "postcss-modules-values": "^4.0.0", "postcss-value-parser": "^4.2.0", "semver": "^7.5.4" @@ -5241,20 +6733,29 @@ "url": "https://opencollective.com/webpack" }, "peerDependencies": { + "@rspack/core": "0.x || 1.x", "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } } }, "node_modules/css-minimizer-webpack-plugin": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-4.2.2.tgz", - "integrity": "sha512-s3Of/4jKfw1Hj9CxEO1E5oXhQAxlayuHO2y/ML+C6I9sQ7FdzfEV6QgMLN3vI+qFsjJGIAFLKtQK7t8BOXAIyA==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-5.0.1.tgz", + "integrity": "sha512-3caImjKFQkS+ws1TGcFn0V1HyDJFq1Euy589JlD6/3rV2kj+w7r5G9WDMgSHvpvXHNZ2calVypZWuEDQd9wfLg==", "dependencies": { - "cssnano": "^5.1.8", - "jest-worker": "^29.1.2", - "postcss": "^8.4.17", - "schema-utils": "^4.0.0", - "serialize-javascript": "^6.0.0", - "source-map": "^0.6.1" + "@jridgewell/trace-mapping": "^0.3.18", + "cssnano": "^6.0.1", + "jest-worker": "^29.4.3", + "postcss": "^8.4.24", + "schema-utils": "^4.0.1", + "serialize-javascript": "^6.0.1" }, "engines": { "node": ">= 14.15.0" @@ -5287,12 +6788,25 @@ } } }, - "node_modules/css-minimizer-webpack-plugin/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "node_modules/css-prefers-color-scheme": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-10.0.0.tgz", + "integrity": "sha512-VCtXZAWivRglTZditUfB4StnsWr6YVZ2PRtuxQLKTNRdtAf8tpzaVPE9zXIF3VaSc7O70iK/j1+NXxyQCqdPjQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "engines": { - "node": ">=0.10.0" + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" } }, "node_modules/css-select": { @@ -5316,23 +6830,15 @@ "integrity": "sha512-HYPSb7y/Z7BNDCOrakL4raGO2zltZkbeXyAd6Tg9obzix6QhzxCotdBl6VT0Dv4vZfJGVz3WL/xaEI9Ly3ul0g==" }, "node_modules/css-tree": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", - "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", + "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", "dependencies": { - "mdn-data": "2.0.14", - "source-map": "^0.6.1" + "mdn-data": "2.0.30", + "source-map-js": "^1.0.1" }, "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/css-tree/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" } }, "node_modules/css-what": { @@ -5346,6 +6852,21 @@ "url": "https://github.com/sponsors/fb55" } }, + "node_modules/cssdb": { + "version": "8.2.3", + "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-8.2.3.tgz", + "integrity": "sha512-9BDG5XmJrJQQnJ51VFxXCAtpZ5ebDlAREmO8sxMOVU0aSxN/gocbctjIG5LMh3WBUq+xTlb/jw2LoljBEqraTA==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + } + ] + }, "node_modules/cssesc": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", @@ -5358,121 +6879,137 @@ } }, "node_modules/cssnano": { - "version": "5.1.15", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.15.tgz", - "integrity": "sha512-j+BKgDcLDQA+eDifLx0EO4XSA56b7uut3BQFH+wbSaSTuGLuiyTa/wbRYthUXX8LC9mLg+WWKe8h+qJuwTAbHw==", + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-6.1.2.tgz", + "integrity": "sha512-rYk5UeX7VAM/u0lNqewCdasdtPK81CgX8wJFLEIXHbV2oldWRgJAsZrdhRXkV1NJzA2g850KiFm9mMU2HxNxMA==", "dependencies": { - "cssnano-preset-default": "^5.2.14", - "lilconfig": "^2.0.3", - "yaml": "^1.10.2" + "cssnano-preset-default": "^6.1.2", + "lilconfig": "^3.1.1" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/cssnano" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/cssnano-preset-advanced": { - "version": "5.3.10", - "resolved": "https://registry.npmjs.org/cssnano-preset-advanced/-/cssnano-preset-advanced-5.3.10.tgz", - "integrity": "sha512-fnYJyCS9jgMU+cmHO1rPSPf9axbQyD7iUhLO5Df6O4G+fKIOMps+ZbU0PdGFejFBBZ3Pftf18fn1eG7MAPUSWQ==", + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/cssnano-preset-advanced/-/cssnano-preset-advanced-6.1.2.tgz", + "integrity": "sha512-Nhao7eD8ph2DoHolEzQs5CfRpiEP0xa1HBdnFZ82kvqdmbwVBUr2r1QuQ4t1pi+D1ZpqpcO4T+wy/7RxzJ/WPQ==", "dependencies": { - "autoprefixer": "^10.4.12", - "cssnano-preset-default": "^5.2.14", - "postcss-discard-unused": "^5.1.0", - "postcss-merge-idents": "^5.1.1", - "postcss-reduce-idents": "^5.2.0", - "postcss-zindex": "^5.1.0" + "autoprefixer": "^10.4.19", + "browserslist": "^4.23.0", + "cssnano-preset-default": "^6.1.2", + "postcss-discard-unused": "^6.0.5", + "postcss-merge-idents": "^6.0.3", + "postcss-reduce-idents": "^6.0.3", + "postcss-zindex": "^6.0.2" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/cssnano-preset-default": { - "version": "5.2.14", - "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.2.14.tgz", - "integrity": "sha512-t0SFesj/ZV2OTylqQVOrFgEh5uanxbO6ZAdeCrNsUQ6fVuXwYTxJPNAGvGTxHbD68ldIJNec7PyYZDBrfDQ+6A==", - "dependencies": { - "css-declaration-sorter": "^6.3.1", - "cssnano-utils": "^3.1.0", - "postcss-calc": "^8.2.3", - "postcss-colormin": "^5.3.1", - "postcss-convert-values": "^5.1.3", - "postcss-discard-comments": "^5.1.2", - "postcss-discard-duplicates": "^5.1.0", - "postcss-discard-empty": "^5.1.1", - "postcss-discard-overridden": "^5.1.0", - "postcss-merge-longhand": "^5.1.7", - "postcss-merge-rules": "^5.1.4", - "postcss-minify-font-values": "^5.1.0", - "postcss-minify-gradients": "^5.1.1", - "postcss-minify-params": "^5.1.4", - "postcss-minify-selectors": "^5.2.1", - "postcss-normalize-charset": "^5.1.0", - "postcss-normalize-display-values": "^5.1.0", - "postcss-normalize-positions": "^5.1.1", - "postcss-normalize-repeat-style": "^5.1.1", - "postcss-normalize-string": "^5.1.0", - "postcss-normalize-timing-functions": "^5.1.0", - "postcss-normalize-unicode": "^5.1.1", - "postcss-normalize-url": "^5.1.0", - "postcss-normalize-whitespace": "^5.1.1", - "postcss-ordered-values": "^5.1.3", - "postcss-reduce-initial": "^5.1.2", - "postcss-reduce-transforms": "^5.1.0", - "postcss-svgo": "^5.1.0", - "postcss-unique-selectors": "^5.1.1" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-6.1.2.tgz", + "integrity": "sha512-1C0C+eNaeN8OcHQa193aRgYexyJtU8XwbdieEjClw+J9d94E41LwT6ivKH0WT+fYwYWB0Zp3I3IZ7tI/BbUbrg==", + "dependencies": { + "browserslist": "^4.23.0", + "css-declaration-sorter": "^7.2.0", + "cssnano-utils": "^4.0.2", + "postcss-calc": "^9.0.1", + "postcss-colormin": "^6.1.0", + "postcss-convert-values": "^6.1.0", + "postcss-discard-comments": "^6.0.2", + "postcss-discard-duplicates": "^6.0.3", + "postcss-discard-empty": "^6.0.3", + "postcss-discard-overridden": "^6.0.2", + "postcss-merge-longhand": "^6.0.5", + "postcss-merge-rules": "^6.1.1", + "postcss-minify-font-values": "^6.1.0", + "postcss-minify-gradients": "^6.0.3", + "postcss-minify-params": "^6.1.0", + "postcss-minify-selectors": "^6.0.4", + "postcss-normalize-charset": "^6.0.2", + "postcss-normalize-display-values": "^6.0.2", + "postcss-normalize-positions": "^6.0.2", + "postcss-normalize-repeat-style": "^6.0.2", + "postcss-normalize-string": "^6.0.2", + "postcss-normalize-timing-functions": "^6.0.2", + "postcss-normalize-unicode": "^6.1.0", + "postcss-normalize-url": "^6.0.2", + "postcss-normalize-whitespace": "^6.0.2", + "postcss-ordered-values": "^6.0.2", + "postcss-reduce-initial": "^6.1.0", + "postcss-reduce-transforms": "^6.0.2", + "postcss-svgo": "^6.0.3", + "postcss-unique-selectors": "^6.0.4" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" } }, "node_modules/cssnano-utils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.1.0.tgz", - "integrity": "sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-4.0.2.tgz", + "integrity": "sha512-ZR1jHg+wZ8o4c3zqf1SIUSTIvm/9mU343FMR6Obe/unskbvpGhZOo1J6d/r8D1pzkRQYuwbcH3hToOuoA2G7oQ==", "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/csso": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", - "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", + "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", "dependencies": { - "css-tree": "^1.1.2" + "css-tree": "~2.2.0" }, "engines": { - "node": ">=8.0.0" + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/css-tree": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", + "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", + "dependencies": { + "mdn-data": "2.0.28", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" } }, + "node_modules/csso/node_modules/mdn-data": { + "version": "2.0.28", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", + "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==" + }, "node_modules/csstype": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" }, "node_modules/cytoscape": { - "version": "3.28.1", - "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.28.1.tgz", - "integrity": "sha512-xyItz4O/4zp9/239wCcH8ZcFuuZooEeF8KHRmzjDfGdXsj3OG9MFSMA0pJE0uX3uCN/ygof6hHf4L7lst+JaDg==", - "dependencies": { - "heap": "^0.2.6", - "lodash": "^4.17.21" - }, + "version": "3.30.4", + "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.30.4.tgz", + "integrity": "sha512-OxtlZwQl1WbwMmLiyPSEBuzeTIQnwZhJYYWFzZ2PhEHVFwpeaqNIkUzSiso00D98qk60l8Gwon2RP304d3BJ1A==", "engines": { "node": ">=0.10" } @@ -5488,10 +7025,34 @@ "cytoscape": "^3.2.0" } }, + "node_modules/cytoscape-fcose": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cytoscape-fcose/-/cytoscape-fcose-2.2.0.tgz", + "integrity": "sha512-ki1/VuRIHFCzxWNrsshHYPs6L7TvLu3DL+TyIGEsRcvVERmxokbf5Gdk7mFxZnTdiGtnA4cfSmjZJMviqSuZrQ==", + "dependencies": { + "cose-base": "^2.2.0" + }, + "peerDependencies": { + "cytoscape": "^3.2.0" + } + }, + "node_modules/cytoscape-fcose/node_modules/cose-base": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cose-base/-/cose-base-2.2.0.tgz", + "integrity": "sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g==", + "dependencies": { + "layout-base": "^2.0.0" + } + }, + "node_modules/cytoscape-fcose/node_modules/layout-base": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/layout-base/-/layout-base-2.0.1.tgz", + "integrity": "sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg==" + }, "node_modules/d3": { - "version": "7.8.5", - "resolved": "https://registry.npmjs.org/d3/-/d3-7.8.5.tgz", - "integrity": "sha512-JgoahDG51ncUfJu6wX/1vWQEqOflgXyl4MaHqlcSruTez7yhaRKR9i8VjjcQGeS2en/jnFivXuaIMnseMMt0XA==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/d3/-/d3-7.9.0.tgz", + "integrity": "sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==", "dependencies": { "d3-array": "3", "d3-axis": "3", @@ -5650,20 +7211,9 @@ "node_modules/d3-dsv/node_modules/commander": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "engines": { - "node": ">= 10" - } - }, - "node_modules/d3-dsv/node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", "engines": { - "node": ">=0.10.0" + "node": ">= 10" } }, "node_modules/d3-ease": { @@ -5707,9 +7257,9 @@ } }, "node_modules/d3-geo": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.0.tgz", - "integrity": "sha512-JEo5HxXDdDYXCaWdwLRt79y7giK8SbhZJbFWXqbRTolCHFI5jRqteLzCsq51NKbUoX0PjBVSohxrx+NoOUujYA==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.1.tgz", + "integrity": "sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==", "dependencies": { "d3-array": "2.5.0 - 3" }, @@ -5819,9 +7369,9 @@ } }, "node_modules/d3-scale-chromatic": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.0.0.tgz", - "integrity": "sha512-Lx9thtxAKrO2Pq6OO2Ua474opeziKr279P/TKZsMAhYyNDD3EnCffdbgeSYN5O7m2ByQsxtuP2CSDczNUIZ22g==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz", + "integrity": "sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==", "dependencies": { "d3-color": "1 - 3", "d3-interpolate": "1 - 3" @@ -5913,18 +7463,18 @@ } }, "node_modules/dagre-d3-es": { - "version": "7.0.10", - "resolved": "https://registry.npmjs.org/dagre-d3-es/-/dagre-d3-es-7.0.10.tgz", - "integrity": "sha512-qTCQmEhcynucuaZgY5/+ti3X/rnszKZhEQH/ZdWdtP1tA/y3VoHJzcVrO9pjjJCNpigfscAtoUB5ONcd2wNn0A==", + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/dagre-d3-es/-/dagre-d3-es-7.0.11.tgz", + "integrity": "sha512-tvlJLyQf834SylNKax8Wkzco/1ias1OPw8DcUMDE7oUIoSEW25riQVuiu/0OWEFqT0cxHT3Pa9/D82Jr47IONw==", "dependencies": { - "d3": "^7.8.2", + "d3": "^7.9.0", "lodash-es": "^4.17.21" } }, "node_modules/dayjs": { - "version": "1.11.10", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz", - "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==" + "version": "1.11.13", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz", + "integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==" }, "node_modules/debounce": { "version": "1.2.1", @@ -5932,11 +7482,11 @@ "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==" }, "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -6119,9 +7669,9 @@ "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==" }, "node_modules/detect-port": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.5.1.tgz", - "integrity": "sha512-aBzdj76lueB6uUst5iAs7+0H/oOjqI5D16XUWxlWMIMROhcM0rfsNVk93zTngq1dDNpoXRr++Sus7ETAExppAQ==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.6.1.tgz", + "integrity": "sha512-CmnVc+Hek2egPx1PeTFVta2W78xy2K/9Rkf6cC4T59S50tVnzKj+tnx5mmx5lwvCkujZ4uRrpRSuV+IVs3f90Q==", "dependencies": { "address": "^1.0.1", "debug": "4" @@ -6129,6 +7679,9 @@ "bin": { "detect": "bin/detect-port.js", "detect-port": "bin/detect-port.js" + }, + "engines": { + "node": ">= 4.0.0" } }, "node_modules/detect-port-alt": { @@ -6172,14 +7725,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/diff": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", - "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", - "engines": { - "node": ">=0.3.1" - } - }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -6215,9 +7760,9 @@ } }, "node_modules/docusaurus-lunr-search": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/docusaurus-lunr-search/-/docusaurus-lunr-search-3.3.2.tgz", - "integrity": "sha512-+TXfiRAwIAaNwME8bBZvC+osfoXjJSNs5BcZu92lIHoWc3Myct4Nw3jU0FMXQCQGQcQ0FgFqMDoh56LPCLVaxQ==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/docusaurus-lunr-search/-/docusaurus-lunr-search-3.5.0.tgz", + "integrity": "sha512-k3zN4jYMi/prWInJILGKOxE+BVcgYinwj9+gcECsYm52tS+4ZKzXQzbPnVJAEXmvKOfFMcDFvS3MSmm6cEaxIQ==", "dependencies": { "autocomplete.js": "^0.37.0", "clsx": "^1.2.1", @@ -6244,9 +7789,9 @@ } }, "node_modules/docusaurus-lunr-search/node_modules/@types/unist": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==" }, "node_modules/docusaurus-lunr-search/node_modules/bail": { "version": "1.0.5", @@ -6299,15 +7844,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/docusaurus-lunr-search/node_modules/unist-util-is": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz", - "integrity": "sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, "node_modules/docusaurus-lunr-search/node_modules/unist-util-stringify-position": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", @@ -6395,9 +7931,12 @@ } }, "node_modules/dompurify": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.1.6.tgz", - "integrity": "sha512-cTOAhc36AalkjtBpfG6O8JimdTMWNXjiePT2xQH/ppBGi/4uIpmj8eKyIkMJErXWARyINV/sB38yf8JCLF5pbQ==" + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.3.tgz", + "integrity": "sha512-U1U5Hzc2MO0oW3DF+G9qYN0aT7atAou4AgI0XjWz061nyBPbdxkfdhfy5uMgGn6+oLFCfn44ZGbdDqCzVmlOWA==", + "optionalDependencies": { + "@types/trusted-types": "^2.0.7" + } }, "node_modules/domutils": { "version": "3.1.0", @@ -6476,11 +8015,6 @@ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.73.tgz", "integrity": "sha512-8wGNxG9tAG5KhGd3eeA0o6ixhiNdgr0DcHWm85XPCphwZgD1lIEoi6t3VERayWao7SF7AAZTw6oARGJeVjH8Kg==" }, - "node_modules/elkjs": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/elkjs/-/elkjs-0.9.1.tgz", - "integrity": "sha512-JWKDyqAdltuUcyxaECtYG6H4sqysXSLeoXuGUBfRNESMTkj+w+qdb0jya8Z/WI0jVd03WQtCGhS6FOFtlhD5FQ==" - }, "node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", @@ -6500,9 +8034,9 @@ } }, "node_modules/emoticon": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/emoticon/-/emoticon-4.0.1.tgz", - "integrity": "sha512-dqx7eA9YaqyvYtUhJwT4rC1HIp82j5ybS1/vQ42ur+jBe17dJMwZE4+gvL1XadSFfxaPFFGt3Xsw+Y8akThDlw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/emoticon/-/emoticon-4.1.0.tgz", + "integrity": "sha512-VWZfnxqwNcc51hIy/sbOdEem6D+cVtpPzEEtVAFdaas30+1dgkyaOQ4sQ6Bp0tOMqWO1v+HQfYaoodOkdhK6SQ==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -6564,9 +8098,9 @@ } }, "node_modules/es-module-lexer": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.4.1.tgz", - "integrity": "sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==" + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", + "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==" }, "node_modules/es-object-atoms": { "version": "1.0.0", @@ -6579,6 +8113,36 @@ "node": ">= 0.4" } }, + "node_modules/esast-util-from-estree": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/esast-util-from-estree/-/esast-util-from-estree-2.0.0.tgz", + "integrity": "sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "devlop": "^1.0.0", + "estree-util-visit": "^2.0.0", + "unist-util-position-from-estree": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/esast-util-from-js": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/esast-util-from-js/-/esast-util-from-js-2.0.1.tgz", + "integrity": "sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "acorn": "^8.0.0", + "esast-util-from-estree": "^2.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/escalade": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", @@ -6701,6 +8265,19 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/estree-util-scope": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/estree-util-scope/-/estree-util-scope-1.0.0.tgz", + "integrity": "sha512-2CAASclonf+JFWBNJPndcOpA8EMJwa0Q8LUFJEKqXLW6+qBvbFZuF5gItbQOs/umBUkjviCSDCbBwU2cXbmrhQ==", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/estree-util-to-js": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/estree-util-to-js/-/estree-util-to-js-2.0.0.tgz", @@ -6716,15 +8293,11 @@ } }, "node_modules/estree-util-value-to-estree": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/estree-util-value-to-estree/-/estree-util-value-to-estree-3.0.1.tgz", - "integrity": "sha512-b2tdzTurEIbwRh+mKrEcaWfu1wgb8J1hVsgREg7FFiecWwK/PhO8X0kyc+0bIcKNtD4sqxIdNoRy6/p/TvECEA==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/estree-util-value-to-estree/-/estree-util-value-to-estree-3.2.1.tgz", + "integrity": "sha512-Vt2UOjyPbNQQgT5eJh+K5aATti0OjCIAGc9SgMdOFYbohuifsWclR74l0iZTJwePMgWYdX1hlVS+dedH9XV8kw==", "dependencies": { - "@types/estree": "^1.0.0", - "is-plain-obj": "^4.0.0" - }, - "engines": { - "node": ">=16.0.0" + "@types/estree": "^1.0.0" }, "funding": { "url": "https://github.com/sponsors/remcohaszing" @@ -6948,18 +8521,15 @@ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" }, - "node_modules/fast-url-parser": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/fast-url-parser/-/fast-url-parser-1.1.3.tgz", - "integrity": "sha512-5jOCVXADYNuRkKFzNJ0dCCewsZiYo0dz8QNYljkOpFC6r2U4OBmKtvm/Tsuh4w1YYdDqDb31a8TVhBJ2OJKdqQ==", - "dependencies": { - "punycode": "^1.3.2" - } + "node_modules/fast-uri": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.3.tgz", + "integrity": "sha512-aLrHthzCjH5He4Z2H9YZ+v6Ujb9ocRuW6ZzkJQOrTxleEijANq4v1TsaPaVG1PZcuurEzrLcWRyYBYXD5cEiaw==" }, "node_modules/fastq": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.16.0.tgz", - "integrity": "sha512-ifCoaXsDrsdkWTtiNJX5uzHDsrck5TzfKKDcuFFTIrrc/BS076qgEIfoIy1VeZqViznfKiysPYTh/QeHtnIsYA==", + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", "dependencies": { "reusify": "^1.0.4" } @@ -6998,6 +8568,28 @@ "node": ">=0.4.0" } }, + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/figures/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/file-loader": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", @@ -7346,9 +8938,9 @@ } }, "node_modules/fs-monkey": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.5.tgz", - "integrity": "sha512-8uMbBjrhzW76TYgEV27Y5E//W2f/lTFmx78P2w19FZSxarhI/798APGQyuGCwmkNxgwGRhrLfvWyLBvNtuOmew==" + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.6.tgz", + "integrity": "sha512-b1FMfwetIKymC0eioW7mTywihSQE4oLzQn1dB6rZB5fx/3NpNEdAWeCSMB+60/AeT0TCXsxzAlcYVEFCTAksWg==" }, "node_modules/fs.realpath": { "version": "1.0.0", @@ -7380,6 +8972,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", + "deprecated": "This package is no longer supported.", "dependencies": { "aproba": "^1.0.3 || ^2.0.0", "color-support": "^1.1.2", @@ -7469,6 +9062,7 @@ "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -7683,6 +9277,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/hachure-fill": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/hachure-fill/-/hachure-fill-0.5.2.tgz", + "integrity": "sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg==" + }, "node_modules/handle-thing": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", @@ -7710,1575 +9309,1295 @@ "node_modules/has-symbols": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", - "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==" - }, - "node_modules/has-yarn": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-3.0.0.tgz", - "integrity": "sha512-IrsVwUHhEULx3R8f/aA8AHuEzAorplsab/v8HBzEiIukwq5i/EC+xmOW+HfP1OaDP+2JkgT1yILHN2O3UFIbcA==", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/hast-util-from-parse5": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-8.0.1.tgz", - "integrity": "sha512-Er/Iixbc7IEa7r/XLtuG52zoqn/b3Xng/w6aZQ0xGVxzhw5xUFxcRqdPzP6yFi/4HBYRaifaI5fQ1RH8n0ZeOQ==", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "devlop": "^1.0.0", - "hastscript": "^8.0.0", - "property-information": "^6.0.0", - "vfile": "^6.0.0", - "vfile-location": "^5.0.0", - "web-namespaces": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-has-property": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/hast-util-has-property/-/hast-util-has-property-1.0.4.tgz", - "integrity": "sha512-ghHup2voGfgFoHMGnaLHOjbYFACKrRh9KFttdCzMCbFoBMJXiNi2+XTrPP8+q6cDJM/RSqlCfVWrjp1H201rZg==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-is-element": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-1.1.0.tgz", - "integrity": "sha512-oUmNua0bFbdrD/ELDSSEadRVtWZOf3iF6Lbv81naqsIV99RnSCieTbWuWCY8BAeEfKJTKl0gRdokv+dELutHGQ==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-parse-selector": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", - "integrity": "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==", - "dependencies": { - "@types/hast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-raw": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-9.0.2.tgz", - "integrity": "sha512-PldBy71wO9Uq1kyaMch9AHIghtQvIwxBUkv823pKmkTM3oV1JxtsTNYdevMxvUHqcnOAuO65JKU2+0NOxc2ksA==", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "@ungap/structured-clone": "^1.0.0", - "hast-util-from-parse5": "^8.0.0", - "hast-util-to-parse5": "^8.0.0", - "html-void-elements": "^3.0.0", - "mdast-util-to-hast": "^13.0.0", - "parse5": "^7.0.0", - "unist-util-position": "^5.0.0", - "unist-util-visit": "^5.0.0", - "vfile": "^6.0.0", - "web-namespaces": "^2.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-select": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/hast-util-select/-/hast-util-select-4.0.2.tgz", - "integrity": "sha512-8EEG2//bN5rrzboPWD2HdS3ugLijNioS1pqOTIolXNf67xxShYw4SQEmVXd3imiBG+U2bC2nVTySr/iRAA7Cjg==", - "dependencies": { - "bcp-47-match": "^1.0.0", - "comma-separated-tokens": "^1.0.0", - "css-selector-parser": "^1.0.0", - "direction": "^1.0.0", - "hast-util-has-property": "^1.0.0", - "hast-util-is-element": "^1.0.0", - "hast-util-to-string": "^1.0.0", - "hast-util-whitespace": "^1.0.0", - "not": "^0.1.0", - "nth-check": "^2.0.0", - "property-information": "^5.0.0", - "space-separated-tokens": "^1.0.0", - "unist-util-visit": "^2.0.0", - "zwitch": "^1.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-select/node_modules/@types/unist": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" - }, - "node_modules/hast-util-select/node_modules/comma-separated-tokens": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz", - "integrity": "sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/hast-util-select/node_modules/hast-util-whitespace": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-1.0.4.tgz", - "integrity": "sha512-I5GTdSfhYfAPNztx2xJRQpG8cuDSNt599/7YUn7Gx/WxNMsG+a835k97TDkFgk123cwjfwINaZknkKkphx/f2A==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-select/node_modules/property-information": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/property-information/-/property-information-5.6.0.tgz", - "integrity": "sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==", - "dependencies": { - "xtend": "^4.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/hast-util-select/node_modules/space-separated-tokens": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz", - "integrity": "sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "engines": { + "node": ">= 0.4" + }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/hast-util-select/node_modules/unist-util-is": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz", - "integrity": "sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==", + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==" + }, + "node_modules/has-yarn": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-3.0.0.tgz", + "integrity": "sha512-IrsVwUHhEULx3R8f/aA8AHuEzAorplsab/v8HBzEiIukwq5i/EC+xmOW+HfP1OaDP+2JkgT1yILHN2O3UFIbcA==", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/hast-util-select/node_modules/unist-util-visit": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz", - "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==", + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-is": "^4.0.0", - "unist-util-visit-parents": "^3.0.0" + "function-bind": "^1.1.2" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "engines": { + "node": ">= 0.4" } }, - "node_modules/hast-util-select/node_modules/unist-util-visit-parents": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz", - "integrity": "sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==", + "node_modules/hast-util-from-parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-6.0.1.tgz", + "integrity": "sha512-jeJUWiN5pSxW12Rh01smtVkZgZr33wBokLzKLwinYOUfSzm1Nl/c3GUGebDyOKjdsRgMvoVbV0VpAcpjF4NrJA==", "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-is": "^4.0.0" + "@types/parse5": "^5.0.0", + "hastscript": "^6.0.0", + "property-information": "^5.0.0", + "vfile": "^4.0.0", + "vfile-location": "^3.2.0", + "web-namespaces": "^1.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/hast-util-select/node_modules/zwitch": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-1.0.5.tgz", - "integrity": "sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } + "node_modules/hast-util-from-parse5/node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==" }, - "node_modules/hast-util-to-estree": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hast-util-to-estree/-/hast-util-to-estree-3.1.0.tgz", - "integrity": "sha512-lfX5g6hqVh9kjS/B9E2gSkvHH4SZNiQFiqWS0x9fENzEl+8W12RqdRxX6d/Cwxi30tPQs3bIO+aolQJNp1bIyw==", + "node_modules/hast-util-from-parse5/node_modules/unist-util-stringify-position": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", + "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==", "dependencies": { - "@types/estree": "^1.0.0", - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "comma-separated-tokens": "^2.0.0", - "devlop": "^1.0.0", - "estree-util-attach-comments": "^3.0.0", - "estree-util-is-identifier-name": "^3.0.0", - "hast-util-whitespace": "^3.0.0", - "mdast-util-mdx-expression": "^2.0.0", - "mdast-util-mdx-jsx": "^3.0.0", - "mdast-util-mdxjs-esm": "^2.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0", - "style-to-object": "^0.4.0", - "unist-util-position": "^5.0.0", - "zwitch": "^2.0.0" + "@types/unist": "^2.0.2" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/hast-util-to-jsx-runtime": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.0.tgz", - "integrity": "sha512-H/y0+IWPdsLLS738P8tDnrQ8Z+dj12zQQ6WC11TIM21C8WFVoIxcqWXf2H3hiTVZjF1AWqoimGwrTWecWrnmRQ==", + "node_modules/hast-util-from-parse5/node_modules/vfile": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.2.1.tgz", + "integrity": "sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==", "dependencies": { - "@types/estree": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "comma-separated-tokens": "^2.0.0", - "devlop": "^1.0.0", - "estree-util-is-identifier-name": "^3.0.0", - "hast-util-whitespace": "^3.0.0", - "mdast-util-mdx-expression": "^2.0.0", - "mdast-util-mdx-jsx": "^3.0.0", - "mdast-util-mdxjs-esm": "^2.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0", - "style-to-object": "^1.0.0", - "unist-util-position": "^5.0.0", - "vfile-message": "^4.0.0" + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^2.0.0", + "vfile-message": "^2.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/hast-util-to-jsx-runtime/node_modules/inline-style-parser": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.2.tgz", - "integrity": "sha512-EcKzdTHVe8wFVOGEYXiW9WmJXPjqi1T+234YpJr98RiFYKHV3cdy1+3mkTE+KHTHxFFLH51SfaGOoUdW+v7ViQ==" - }, - "node_modules/hast-util-to-jsx-runtime/node_modules/style-to-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.5.tgz", - "integrity": "sha512-rDRwHtoDD3UMMrmZ6BzOW0naTjMsVZLIjsGleSKS/0Oz+cgCfAPRspaqJuE8rDzpKha/nEvnM0IF4seEAZUTKQ==", - "dependencies": { - "inline-style-parser": "0.2.2" - } - }, - "node_modules/hast-util-to-parse5": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-8.0.0.tgz", - "integrity": "sha512-3KKrV5ZVI8if87DVSi1vDeByYrkGzg4mEfeu4alwgmmIeARiBLKCZS2uw5Gb6nU9x9Yufyj3iudm6i7nl52PFw==", + "node_modules/hast-util-from-parse5/node_modules/vfile-message": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz", + "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==", "dependencies": { - "@types/hast": "^3.0.0", - "comma-separated-tokens": "^2.0.0", - "devlop": "^1.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0", - "web-namespaces": "^2.0.0", - "zwitch": "^2.0.0" + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^2.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/hast-util-to-string": { + "node_modules/hast-util-has-property": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/hast-util-to-string/-/hast-util-to-string-1.0.4.tgz", - "integrity": "sha512-eK0MxRX47AV2eZ+Lyr18DCpQgodvaS3fAQO2+b9Two9F5HEoRPhiUMNzoXArMJfZi2yieFzUBMRl3HNJ3Jus3w==", + "resolved": "https://registry.npmjs.org/hast-util-has-property/-/hast-util-has-property-1.0.4.tgz", + "integrity": "sha512-ghHup2voGfgFoHMGnaLHOjbYFACKrRh9KFttdCzMCbFoBMJXiNi2+XTrPP8+q6cDJM/RSqlCfVWrjp1H201rZg==", "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/hast-util-to-text": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/hast-util-to-text/-/hast-util-to-text-2.0.1.tgz", - "integrity": "sha512-8nsgCARfs6VkwH2jJU9b8LNTuR4700na+0h3PqCaEk4MAnMDeu5P0tP8mjk9LLNGxIeQRLbiDbZVw6rku+pYsQ==", - "dependencies": { - "hast-util-is-element": "^1.0.0", - "repeat-string": "^1.0.0", - "unist-util-find-after": "^3.0.0" - }, + "node_modules/hast-util-is-element": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-1.1.0.tgz", + "integrity": "sha512-oUmNua0bFbdrD/ELDSSEadRVtWZOf3iF6Lbv81naqsIV99RnSCieTbWuWCY8BAeEfKJTKl0gRdokv+dELutHGQ==", "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/hast-util-whitespace": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", - "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", - "dependencies": { - "@types/hast": "^3.0.0" - }, + "node_modules/hast-util-parse-selector": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz", + "integrity": "sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==", "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/hastscript": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-8.0.0.tgz", - "integrity": "sha512-dMOtzCEd3ABUeSIISmrETiKuyydk1w0pa+gE/uormcTpSYuaNJPbX1NU3JLyscSLjwAQM8bWMhhIlnCqnRvDTw==", + "node_modules/hast-util-raw": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-9.1.0.tgz", + "integrity": "sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==", "dependencies": { "@types/hast": "^3.0.0", - "comma-separated-tokens": "^2.0.0", - "hast-util-parse-selector": "^4.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0" + "@types/unist": "^3.0.0", + "@ungap/structured-clone": "^1.0.0", + "hast-util-from-parse5": "^8.0.0", + "hast-util-to-parse5": "^8.0.0", + "html-void-elements": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "parse5": "^7.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "bin": { - "he": "bin/he" - } - }, - "node_modules/heap": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/heap/-/heap-0.2.7.tgz", - "integrity": "sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg==" - }, - "node_modules/history": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", - "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", - "dependencies": { - "@babel/runtime": "^7.1.2", - "loose-envify": "^1.2.0", - "resolve-pathname": "^3.0.0", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0", - "value-equal": "^1.0.1" + "node_modules/hast-util-raw/node_modules/comma-separated-tokens": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", + "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/hogan.js": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/hogan.js/-/hogan.js-3.0.2.tgz", - "integrity": "sha512-RqGs4wavGYJWE07t35JQccByczmNUXQT0E12ZYV1VKYu5UiAU9lsos/yBAcf840+zrUQQxgVduCR5/B8nNtibg==", + "node_modules/hast-util-raw/node_modules/hast-util-from-parse5": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-8.0.2.tgz", + "integrity": "sha512-SfMzfdAi/zAoZ1KkFEyyeXBn7u/ShQrfd675ZEE9M3qj+PMFX05xubzRyF76CCSJu8au9jgVxDV1+okFvgZU4A==", "dependencies": { - "mkdirp": "0.3.0", - "nopt": "1.0.10" + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "hastscript": "^9.0.0", + "property-information": "^6.0.0", + "vfile": "^6.0.0", + "vfile-location": "^5.0.0", + "web-namespaces": "^2.0.0" }, - "bin": { - "hulk": "bin/hulk" - } - }, - "node_modules/hoist-non-react-statics": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", - "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", - "dependencies": { - "react-is": "^16.7.0" - } - }, - "node_modules/hpack.js": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", - "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", - "dependencies": { - "inherits": "^2.0.1", - "obuf": "^1.0.0", - "readable-stream": "^2.0.1", - "wbuf": "^1.1.0" - } - }, - "node_modules/hpack.js/node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } }, - "node_modules/hpack.js/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "node_modules/hast-util-raw/node_modules/hast-util-parse-selector": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", + "integrity": "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==", "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/hpack.js/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "node_modules/hpack.js/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "node_modules/hast-util-raw/node_modules/hastscript": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-9.0.0.tgz", + "integrity": "sha512-jzaLBGavEDKHrc5EfFImKN7nZKKBdSLIdGvCwDZ9TfzbF2ffXiov8CKE445L2Z1Ek2t/m4SKQ2j6Ipv7NyUolw==", "dependencies": { - "safe-buffer": "~5.1.0" + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-parse-selector": "^4.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/html-entities": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.4.0.tgz", - "integrity": "sha512-igBTJcNNNhvZFRtm8uA6xMY6xYleeDwn3PeBCkDz7tHttv4F2hsDI2aPgNERWzvRcNYHNT3ymRaQzllmXj4YsQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/mdevils" - }, - { - "type": "patreon", - "url": "https://patreon.com/mdevils" - } - ] + "node_modules/hast-util-raw/node_modules/property-information": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.5.0.tgz", + "integrity": "sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } }, - "node_modules/html-escaper": { + "node_modules/hast-util-raw/node_modules/space-separated-tokens": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==" + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", + "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } }, - "node_modules/html-minifier-terser": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-7.2.0.tgz", - "integrity": "sha512-tXgn3QfqPIpGl9o+K5tpcj3/MN4SfLtsx2GWwBC3SSd0tXQGyF3gsSqad8loJgKZGM3ZxbYDd5yhiBIdWpmvLA==", + "node_modules/hast-util-raw/node_modules/vfile-location": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-5.0.3.tgz", + "integrity": "sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==", "dependencies": { - "camel-case": "^4.1.2", - "clean-css": "~5.3.2", - "commander": "^10.0.0", - "entities": "^4.4.0", - "param-case": "^3.0.4", - "relateurl": "^0.2.7", - "terser": "^5.15.1" - }, - "bin": { - "html-minifier-terser": "cli.js" + "@types/unist": "^3.0.0", + "vfile": "^6.0.0" }, - "engines": { - "node": "^14.13.1 || >=16.0.0" - } - }, - "node_modules/html-minifier-terser/node_modules/commander": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", - "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", - "engines": { - "node": ">=14" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/html-tags": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz", - "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==", - "engines": { - "node": ">=8" - }, + "node_modules/hast-util-raw/node_modules/web-namespaces": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", + "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==", "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/html-void-elements": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", - "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==", + "node_modules/hast-util-raw/node_modules/zwitch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/html-webpack-plugin": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.6.0.tgz", - "integrity": "sha512-iwaY4wzbe48AfKLZ/Cc8k0L+FKG6oSNRaZ8x5A/T/IVDGyXcbHncM9TdDa93wn0FsSm82FhTKW7f3vS61thXAw==", + "node_modules/hast-util-select": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/hast-util-select/-/hast-util-select-4.0.2.tgz", + "integrity": "sha512-8EEG2//bN5rrzboPWD2HdS3ugLijNioS1pqOTIolXNf67xxShYw4SQEmVXd3imiBG+U2bC2nVTySr/iRAA7Cjg==", "dependencies": { - "@types/html-minifier-terser": "^6.0.0", - "html-minifier-terser": "^6.0.2", - "lodash": "^4.17.21", - "pretty-error": "^4.0.0", - "tapable": "^2.0.0" - }, - "engines": { - "node": ">=10.13.0" + "bcp-47-match": "^1.0.0", + "comma-separated-tokens": "^1.0.0", + "css-selector-parser": "^1.0.0", + "direction": "^1.0.0", + "hast-util-has-property": "^1.0.0", + "hast-util-is-element": "^1.0.0", + "hast-util-to-string": "^1.0.0", + "hast-util-whitespace": "^1.0.0", + "not": "^0.1.0", + "nth-check": "^2.0.0", + "property-information": "^5.0.0", + "space-separated-tokens": "^1.0.0", + "unist-util-visit": "^2.0.0", + "zwitch": "^1.0.0" }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/html-webpack-plugin" - }, - "peerDependencies": { - "@rspack/core": "0.x || 1.x", - "webpack": "^5.20.0" - }, - "peerDependenciesMeta": { - "@rspack/core": { - "optional": true - }, - "webpack": { - "optional": true - } + "url": "https://opencollective.com/unified" } }, - "node_modules/html-webpack-plugin/node_modules/commander": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", - "engines": { - "node": ">= 12" - } + "node_modules/hast-util-select/node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==" }, - "node_modules/html-webpack-plugin/node_modules/html-minifier-terser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", - "integrity": "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==", + "node_modules/hast-util-select/node_modules/unist-util-visit": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz", + "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==", "dependencies": { - "camel-case": "^4.1.2", - "clean-css": "^5.2.2", - "commander": "^8.3.0", - "he": "^1.2.0", - "param-case": "^3.0.4", - "relateurl": "^0.2.7", - "terser": "^5.10.0" - }, - "bin": { - "html-minifier-terser": "cli.js" + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" }, - "engines": { - "node": ">=12" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/htmlparser2": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", - "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", - "funding": [ - "https://github.com/fb55/htmlparser2?sponsor=1", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], + "node_modules/hast-util-select/node_modules/unist-util-visit-parents": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz", + "integrity": "sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==", "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1", - "entities": "^4.4.0" + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/http-cache-semantics": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", - "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==" + "node_modules/hast-util-to-estree": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hast-util-to-estree/-/hast-util-to-estree-3.1.0.tgz", + "integrity": "sha512-lfX5g6hqVh9kjS/B9E2gSkvHH4SZNiQFiqWS0x9fENzEl+8W12RqdRxX6d/Cwxi30tPQs3bIO+aolQJNp1bIyw==", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-attach-comments": "^3.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "style-to-object": "^0.4.0", + "unist-util-position": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } }, - "node_modules/http-deceiver": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", - "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==" + "node_modules/hast-util-to-estree/node_modules/comma-separated-tokens": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", + "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } }, - "node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "node_modules/hast-util-to-estree/node_modules/hast-util-whitespace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", + "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" + "@types/hast": "^3.0.0" }, - "engines": { - "node": ">= 0.8" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/http-parser-js": { - "version": "0.5.8", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", - "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==" + "node_modules/hast-util-to-estree/node_modules/inline-style-parser": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz", + "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==" }, - "node_modules/http-proxy": { - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", - "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", - "dependencies": { - "eventemitter3": "^4.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" - }, - "engines": { - "node": ">=8.0.0" + "node_modules/hast-util-to-estree/node_modules/property-information": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.5.0.tgz", + "integrity": "sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/http-proxy-middleware": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.7.tgz", - "integrity": "sha512-fgVY8AV7qU7z/MmXJ/rxwbrtQH4jBQ9m7kp3llF0liB7glmFeVZFBepQb32T3y8n8k2+AEYuMPCpinYW+/CuRA==", + "node_modules/hast-util-to-estree/node_modules/space-separated-tokens": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", + "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/hast-util-to-estree/node_modules/style-to-object": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.4.4.tgz", + "integrity": "sha512-HYNoHZa2GorYNyqiCaBgsxvcJIn7OHq6inEga+E6Ke3m5JkoqpQbnFssk4jwe+K7AhGa2fcha4wSOf1Kn01dMg==", "dependencies": { - "@types/http-proxy": "^1.17.8", - "http-proxy": "^1.18.1", - "is-glob": "^4.0.1", - "is-plain-obj": "^3.0.0", - "micromatch": "^4.0.2" - }, - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "@types/express": "^4.17.13" - }, - "peerDependenciesMeta": { - "@types/express": { - "optional": true - } + "inline-style-parser": "0.1.1" } }, - "node_modules/http-proxy-middleware/node_modules/is-plain-obj": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", - "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", - "engines": { - "node": ">=10" - }, + "node_modules/hast-util-to-estree/node_modules/zwitch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/http2-wrapper": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.1.tgz", - "integrity": "sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==", + "node_modules/hast-util-to-jsx-runtime": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.2.tgz", + "integrity": "sha512-1ngXYb+V9UT5h+PxNRa1O1FYguZK/XL+gkeqvp7EdHlB9oHUG0eYRo/vY5inBdcqo3RkPMC58/H94HvkbfGdyg==", "dependencies": { - "quick-lru": "^5.1.1", - "resolve-alpn": "^1.2.0" + "@types/estree": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "style-to-object": "^1.0.0", + "unist-util-position": "^5.0.0", + "vfile-message": "^4.0.0" }, - "engines": { - "node": ">=10.19.0" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "engines": { - "node": ">=10.17.0" + "node_modules/hast-util-to-jsx-runtime/node_modules/comma-separated-tokens": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", + "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "node_modules/hast-util-to-jsx-runtime/node_modules/hast-util-whitespace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", + "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" + "@types/hast": "^3.0.0" }, - "engines": { - "node": ">=0.10.0" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/icss-utils": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", - "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" + "node_modules/hast-util-to-jsx-runtime/node_modules/property-information": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.5.0.tgz", + "integrity": "sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/ignore": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz", - "integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==", - "engines": { - "node": ">= 4" + "node_modules/hast-util-to-jsx-runtime/node_modules/space-separated-tokens": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", + "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/image-size": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/image-size/-/image-size-1.1.1.tgz", - "integrity": "sha512-541xKlUw6jr/6gGuk92F+mYM5zaFAc5ahphvkqvNe2bQ6gVBkd6bfrmVJ2t4KDAfikAYZyIqTnktX3i6/aQDrQ==", + "node_modules/hast-util-to-parse5": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-8.0.0.tgz", + "integrity": "sha512-3KKrV5ZVI8if87DVSi1vDeByYrkGzg4mEfeu4alwgmmIeARiBLKCZS2uw5Gb6nU9x9Yufyj3iudm6i7nl52PFw==", "dependencies": { - "queue": "6.0.2" - }, - "bin": { - "image-size": "bin/image-size.js" + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" }, - "engines": { - "node": ">=16.x" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/immediate": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.3.0.tgz", - "integrity": "sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q==" + "node_modules/hast-util-to-parse5/node_modules/comma-separated-tokens": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", + "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } }, - "node_modules/immer": { - "version": "9.0.21", - "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz", - "integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==", + "node_modules/hast-util-to-parse5/node_modules/property-information": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.5.0.tgz", + "integrity": "sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==", "funding": { - "type": "opencollective", - "url": "https://opencollective.com/immer" + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, + "node_modules/hast-util-to-parse5/node_modules/space-separated-tokens": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", + "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/import-lazy": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", - "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", - "engines": { - "node": ">=8" + "node_modules/hast-util-to-parse5/node_modules/web-namespaces": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", + "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "engines": { - "node": ">=0.8.19" + "node_modules/hast-util-to-parse5/node_modules/zwitch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/hast-util-to-string": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/hast-util-to-string/-/hast-util-to-string-1.0.4.tgz", + "integrity": "sha512-eK0MxRX47AV2eZ+Lyr18DCpQgodvaS3fAQO2+b9Two9F5HEoRPhiUMNzoXArMJfZi2yieFzUBMRl3HNJ3Jus3w==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-text": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/hast-util-to-text/-/hast-util-to-text-2.0.1.tgz", + "integrity": "sha512-8nsgCARfs6VkwH2jJU9b8LNTuR4700na+0h3PqCaEk4MAnMDeu5P0tP8mjk9LLNGxIeQRLbiDbZVw6rku+pYsQ==", + "dependencies": { + "hast-util-is-element": "^1.0.0", + "repeat-string": "^1.0.0", + "unist-util-find-after": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "engines": { - "node": ">=8" + "node_modules/hast-util-whitespace": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-1.0.4.tgz", + "integrity": "sha512-I5GTdSfhYfAPNztx2xJRQpG8cuDSNt599/7YUn7Gx/WxNMsG+a835k97TDkFgk123cwjfwINaZknkKkphx/f2A==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/infima": { - "version": "0.2.0-alpha.43", - "resolved": "https://registry.npmjs.org/infima/-/infima-0.2.0-alpha.43.tgz", - "integrity": "sha512-2uw57LvUqW0rK/SWYnd/2rRfxNA5DDNOh33jxF7fy46VWoNhGxiUQyVZHbBMjQ33mQem0cjdDVwgWVAmlRfgyQ==", - "engines": { - "node": ">=12" + "node_modules/hastscript": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-6.0.0.tgz", + "integrity": "sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==", + "dependencies": { + "@types/hast": "^2.0.0", + "comma-separated-tokens": "^1.0.0", + "hast-util-parse-selector": "^2.0.0", + "property-information": "^5.0.0", + "space-separated-tokens": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "node_modules/hastscript/node_modules/@types/hast": { + "version": "2.3.10", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.10.tgz", + "integrity": "sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==", "dependencies": { - "once": "^1.3.0", - "wrappy": "1" + "@types/unist": "^2" } }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" - }, - "node_modules/inline-style-parser": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz", - "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==" + "node_modules/hastscript/node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==" }, - "node_modules/internmap": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", - "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", - "engines": { - "node": ">=12" + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "bin": { + "he": "bin/he" } }, - "node_modules/interpret": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", - "engines": { - "node": ">= 0.10" + "node_modules/history": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", + "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", + "dependencies": { + "@babel/runtime": "^7.1.2", + "loose-envify": "^1.2.0", + "resolve-pathname": "^3.0.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0", + "value-equal": "^1.0.1" } }, - "node_modules/invariant": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "node_modules/hogan.js": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/hogan.js/-/hogan.js-3.0.2.tgz", + "integrity": "sha512-RqGs4wavGYJWE07t35JQccByczmNUXQT0E12ZYV1VKYu5UiAU9lsos/yBAcf840+zrUQQxgVduCR5/B8nNtibg==", "dependencies": { - "loose-envify": "^1.0.0" + "mkdirp": "0.3.0", + "nopt": "1.0.10" + }, + "bin": { + "hulk": "bin/hulk" } }, - "node_modules/ipaddr.js": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.1.0.tgz", - "integrity": "sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ==", - "engines": { - "node": ">= 10" + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "dependencies": { + "react-is": "^16.7.0" } }, - "node_modules/is-alphabetical": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", - "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "node_modules/hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", + "dependencies": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" } }, - "node_modules/is-alphanumerical": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", - "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", + "node_modules/hpack.js/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "node_modules/hpack.js/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dependencies": { - "is-alphabetical": "^2.0.0", - "is-decimal": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" + "node_modules/hpack.js/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "node_modules/hpack.js/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" + "safe-buffer": "~5.1.0" } }, - "node_modules/is-buffer": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", - "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", + "node_modules/html-entities": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.5.2.tgz", + "integrity": "sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==", "funding": [ { "type": "github", - "url": "https://github.com/sponsors/feross" + "url": "https://github.com/sponsors/mdevils" }, { "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" + "url": "https://patreon.com/mdevils" } - ], - "engines": { - "node": ">=4" - } + ] }, - "node_modules/is-ci": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", - "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", - "dependencies": { - "ci-info": "^3.2.0" - }, - "bin": { - "is-ci": "bin.js" - } + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==" }, - "node_modules/is-core-module": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", - "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "node_modules/html-minifier-terser": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-7.2.0.tgz", + "integrity": "sha512-tXgn3QfqPIpGl9o+K5tpcj3/MN4SfLtsx2GWwBC3SSd0tXQGyF3gsSqad8loJgKZGM3ZxbYDd5yhiBIdWpmvLA==", "dependencies": { - "hasown": "^2.0.0" + "camel-case": "^4.1.2", + "clean-css": "~5.3.2", + "commander": "^10.0.0", + "entities": "^4.4.0", + "param-case": "^3.0.4", + "relateurl": "^0.2.7", + "terser": "^5.15.1" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-decimal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", - "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": ">=8" + "html-minifier-terser": "cli.js" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", "engines": { - "node": ">=0.10.0" + "node": "^14.13.1 || >=16.0.0" } }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "node_modules/html-minifier-terser/node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", "engines": { - "node": ">=0.10.0" + "node": ">=14" } }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "node_modules/html-tags": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz", + "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==", "engines": { "node": ">=8" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dependencies": { - "is-extglob": "^2.1.1" }, - "engines": { - "node": ">=0.10.0" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-hexadecimal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", - "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", + "node_modules/html-void-elements": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", + "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/is-installed-globally": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", - "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", + "node_modules/html-webpack-plugin": { + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.6.3.tgz", + "integrity": "sha512-QSf1yjtSAsmf7rYBV7XX86uua4W/vkhIt0xNXKbsi2foEeW7vjJQz4bhnpL3xH+l1ryl1680uNv968Z+X6jSYg==", "dependencies": { - "global-dirs": "^3.0.0", - "is-path-inside": "^3.0.2" + "@types/html-minifier-terser": "^6.0.0", + "html-minifier-terser": "^6.0.2", + "lodash": "^4.17.21", + "pretty-error": "^4.0.0", + "tapable": "^2.0.0" }, "engines": { - "node": ">=10" + "node": ">=10.13.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "type": "opencollective", + "url": "https://opencollective.com/html-webpack-plugin" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "webpack": "^5.20.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } } }, - "node_modules/is-npm": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-6.0.0.tgz", - "integrity": "sha512-JEjxbSmtPSt1c8XTkVrlujcXdKV1/tvuQ7GwKcAlyiVLeYFQ2VHat8xfrDJsIkhCdF/tZ7CiIR3sy141c6+gPQ==", + "node_modules/html-webpack-plugin/node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 12" } }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "node_modules/html-webpack-plugin/node_modules/html-minifier-terser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", + "integrity": "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==", + "dependencies": { + "camel-case": "^4.1.2", + "clean-css": "^5.2.2", + "commander": "^8.3.0", + "he": "^1.2.0", + "param-case": "^3.0.4", + "relateurl": "^0.2.7", + "terser": "^5.10.0" + }, + "bin": { + "html-minifier-terser": "cli.js" + }, "engines": { - "node": ">=0.12.0" + "node": ">=12" } }, - "node_modules/is-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", - "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==", - "engines": { - "node": ">=0.10.0" + "node_modules/htmlparser2": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", + "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1", + "entities": "^4.4.0" } }, - "node_modules/is-path-cwd": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", - "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", + "node_modules/http-cache-semantics": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==" + }, + "node_modules/http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==" + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, "engines": { - "node": ">=6" + "node": ">= 0.8" } }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "node_modules/http-parser-js": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", + "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==" + }, + "node_modules/http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, "engines": { - "node": ">=8" + "node": ">=8.0.0" } }, - "node_modules/is-plain-obj": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", - "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "node_modules/http-proxy-middleware": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.7.tgz", + "integrity": "sha512-fgVY8AV7qU7z/MmXJ/rxwbrtQH4jBQ9m7kp3llF0liB7glmFeVZFBepQb32T3y8n8k2+AEYuMPCpinYW+/CuRA==", + "dependencies": { + "@types/http-proxy": "^1.17.8", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" + }, "engines": { - "node": ">=12" + "node": ">=12.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "@types/express": "^4.17.13" + }, + "peerDependenciesMeta": { + "@types/express": { + "optional": true + } } }, - "node_modules/is-plain-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "node_modules/http-proxy-middleware/node_modules/is-plain-obj": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", + "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", "engines": { - "node": ">=0.10.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-reference": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.2.tgz", - "integrity": "sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==", + "node_modules/http2-wrapper": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.1.tgz", + "integrity": "sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==", "dependencies": { - "@types/estree": "*" - } - }, - "node_modules/is-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", - "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==", + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.2.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=10.19.0" } }, - "node_modules/is-root": { + "node_modules/human-signals": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-root/-/is-root-2.1.0.tgz", - "integrity": "sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=10.17.0" } }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" - }, - "node_modules/is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", "dependencies": { - "is-docker": "^2.0.0" + "safer-buffer": ">= 2.1.2 < 3.0.0" }, "engines": { - "node": ">=8" + "node": ">=0.10.0" } }, - "node_modules/is-yarn-global": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.4.1.tgz", - "integrity": "sha512-/kppl+R+LO5VmhYSEWARUFjodS25D68gvj8W7z0I7OWhUla5xWu8KL6CtB2V0R6yqhnRgbcaREMr4EEM6htLPQ==", + "node_modules/icss-utils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", "engines": { - "node": ">=12" + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" } }, - "node_modules/isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" - }, - "node_modules/isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "engines": { - "node": ">=0.10.0" + "node": ">= 4" } }, - "node_modules/jest-util": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", - "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "node_modules/image-size": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-1.1.1.tgz", + "integrity": "sha512-541xKlUw6jr/6gGuk92F+mYM5zaFAc5ahphvkqvNe2bQ6gVBkd6bfrmVJ2t4KDAfikAYZyIqTnktX3i6/aQDrQ==", "dependencies": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" + "queue": "6.0.2" + }, + "bin": { + "image-size": "bin/image-size.js" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=16.x" } }, - "node_modules/jest-worker": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", - "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", - "dependencies": { - "@types/node": "*", - "jest-util": "^29.7.0", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node_modules/immediate": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.3.0.tgz", + "integrity": "sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q==" + }, + "node_modules/immer": { + "version": "9.0.21", + "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz", + "integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" } }, - "node_modules/jest-worker/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dependencies": { - "has-flag": "^4.0.0" + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" }, "engines": { - "node": ">=10" + "node": ">=6" }, "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/jiti": { - "version": "1.21.0", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.0.tgz", - "integrity": "sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==", - "bin": { - "jiti": "bin/jiti.js" + "node_modules/import-lazy": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", + "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", + "engines": { + "node": ">=8" } }, - "node_modules/joi": { - "version": "17.12.1", - "resolved": "https://registry.npmjs.org/joi/-/joi-17.12.1.tgz", - "integrity": "sha512-vtxmq+Lsc5SlfqotnfVjlViWfOL9nt/avKNbKYizwf6gsCfq9NYY/ceYRMFD8XDdrjJ9abJyScWmhmIiy+XRtQ==", - "dependencies": { - "@hapi/hoek": "^9.3.0", - "@hapi/topo": "^5.1.0", - "@sideway/address": "^4.1.5", - "@sideway/formula": "^3.0.1", - "@sideway/pinpoint": "^2.0.0" + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "engines": { + "node": ">=0.8.19" } }, - "node_modules/js-tokens": { + "node_modules/indent-string": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "engines": { + "node": ">=8" } }, - "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "bin": { - "jsesc": "bin/jsesc" - }, + "node_modules/infima": { + "version": "0.2.0-alpha.45", + "resolved": "https://registry.npmjs.org/infima/-/infima-0.2.0-alpha.45.tgz", + "integrity": "sha512-uyH0zfr1erU1OohLk0fT4Rrb94AOhguWNOcD9uGrSpRvNB+6gZXUoJX5J0NtvzBO10YZ9PgvA4NFgt+fYg8ojw==", "engines": { - "node": ">=4" + "node": ">=12" } }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, - "node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "bin": { - "json5": "lib/cli.js" - }, + "node_modules/inline-style-parser": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.4.tgz", + "integrity": "sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q==" + }, + "node_modules/internmap": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", + "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", "engines": { - "node": ">=6" + "node": ">=12" } }, - "node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" + "node_modules/interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", + "engines": { + "node": ">= 0.10" } }, - "node_modules/katex": { - "version": "0.16.15", - "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.15.tgz", - "integrity": "sha512-yE9YJIEAk2aZ+FL/G8r+UGw0CTUzEA8ZFy6E+8tc3spHUKq3qBnzCkI1CQwGoI9atJhVyFPEypQsTY7mJ1Pi9w==", - "funding": [ - "https://opencollective.com/katex", - "https://github.com/sponsors/katex" - ], + "node_modules/invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", "dependencies": { - "commander": "^8.3.0" - }, - "bin": { - "katex": "cli.js" + "loose-envify": "^1.0.0" } }, - "node_modules/katex/node_modules/commander": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "node_modules/ipaddr.js": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz", + "integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==", "engines": { - "node": ">= 12" + "node": ">= 10" } }, - "node_modules/keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "node_modules/is-alphabetical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", + "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-alphanumerical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", + "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", "dependencies": { - "json-buffer": "3.0.1" + "is-alphabetical": "^2.0.0", + "is-decimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/khroma": { + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" + }, + "node_modules/is-binary-path": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/khroma/-/khroma-2.1.0.tgz", - "integrity": "sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw==" - }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dependencies": { + "binary-extensions": "^2.0.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "node_modules/is-buffer": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], "engines": { - "node": ">=6" + "node": ">=4" } }, - "node_modules/latest-version": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-7.0.0.tgz", - "integrity": "sha512-KvNT4XqAMzdcL6ka6Tl3i2lYeFDgXNCuIX+xNx6ZMVR1dFq+idXd9FLKNMOIx0t9mJ9/HudyX4oZWXZQ0UJHeg==", + "node_modules/is-ci": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", + "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", "dependencies": { - "package-json": "^8.1.0" + "ci-info": "^3.2.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/is-core-module": { + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.0.tgz", + "integrity": "sha512-urTSINYfAYgcbLb0yDQ6egFm6h3Mo1DcF9EkyXSRjjzdHbsulg01qhwWuXdOoUBuTkbQ80KDboXa0vFJ+BDH+g==", + "dependencies": { + "hasown": "^2.0.2" }, "engines": { - "node": ">=14.16" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/launch-editor": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.6.1.tgz", - "integrity": "sha512-eB/uXmFVpY4zezmGp5XtU21kwo7GBbKB+EQ+UZeWtGb9yAM5xt/Evk+lYH3eRNAtId+ej4u7TYPFZ07w4s7rRw==", - "dependencies": { - "picocolors": "^1.0.0", - "shell-quote": "^1.8.1" + "node_modules/is-decimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", + "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/layout-base": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/layout-base/-/layout-base-1.0.2.tgz", - "integrity": "sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==" - }, - "node_modules/leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "bin": { + "is-docker": "cli.js" + }, "engines": { - "node": ">=6" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/lilconfig": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", - "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", + "node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", "engines": { - "node": ">=10" + "node": ">=0.10.0" } }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" - }, - "node_modules/loader-runner": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", - "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "engines": { - "node": ">=6.11.5" + "node": ">=0.10.0" } }, - "node_modules/loader-utils": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", - "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "engines": { - "node": ">=8.9.0" + "node": ">=8" } }, - "node_modules/locate-path": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", - "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dependencies": { - "p-locate": "^6.0.0" + "is-extglob": "^2.1.1" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=0.10.0" } }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "node_modules/lodash-es": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", - "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" - }, - "node_modules/lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" - }, - "node_modules/lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==" - }, - "node_modules/lodash.uniq": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==" - }, - "node_modules/longest-streak": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", - "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", + "node_modules/is-hexadecimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", + "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "node_modules/is-installed-globally": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", + "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", "dependencies": { - "js-tokens": "^3.0.0 || ^4.0.0" + "global-dirs": "^3.0.0", + "is-path-inside": "^3.0.2" }, - "bin": { - "loose-envify": "cli.js" - } - }, - "node_modules/lower-case": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", - "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", - "dependencies": { - "tslib": "^2.0.3" - } - }, - "node_modules/lowercase-keys": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", - "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/lunr": { - "version": "2.3.9", - "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", - "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==" - }, - "node_modules/lunr-languages": { - "version": "1.14.0", - "resolved": "https://registry.npmjs.org/lunr-languages/-/lunr-languages-1.14.0.tgz", - "integrity": "sha512-hWUAb2KqM3L7J5bcrngszzISY4BxrXn/Xhbb9TTCJYEGqlR1nG67/M14sp09+PTIRklobrn57IAxcdcO/ZFyNA==" - }, - "node_modules/mark.js": { - "version": "8.11.1", - "resolved": "https://registry.npmjs.org/mark.js/-/mark.js-8.11.1.tgz", - "integrity": "sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==" - }, - "node_modules/markdown-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/markdown-extensions/-/markdown-extensions-2.0.0.tgz", - "integrity": "sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==", + "node_modules/is-npm": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-6.0.0.tgz", + "integrity": "sha512-JEjxbSmtPSt1c8XTkVrlujcXdKV1/tvuQ7GwKcAlyiVLeYFQ2VHat8xfrDJsIkhCdF/tZ7CiIR3sy141c6+gPQ==", "engines": { - "node": ">=16" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/markdown-table": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.3.tgz", - "integrity": "sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "engines": { + "node": ">=0.12.0" } }, - "node_modules/math-intrinsics": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.0.0.tgz", - "integrity": "sha512-4MqMiKP90ybymYvsut0CH2g4XWbfLtmlCkXmtmdcDCxNB+mQcu1w/1+L/VD7vi/PSv7X2JYV7SCcR+jiPXnQtA==", + "node_modules/is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==", "engines": { - "node": ">= 0.4" + "node": ">=0.10.0" } }, - "node_modules/mdast-util-directive": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-directive/-/mdast-util-directive-3.0.0.tgz", - "integrity": "sha512-JUpYOqKI4mM3sZcNxmF/ox04XYFFkNwr0CFlrQIkCwbvH0xzMCqkMqAde9wRd80VAhaUrwFwKm2nxretdT1h7Q==", - "dependencies": { - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "devlop": "^1.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0", - "parse-entities": "^4.0.0", - "stringify-entities": "^4.0.0", - "unist-util-visit-parents": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "node_modules/is-path-cwd": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", + "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", + "engines": { + "node": ">=6" } }, - "node_modules/mdast-util-find-and-replace": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.1.tgz", - "integrity": "sha512-SG21kZHGC3XRTSUhtofZkBzZTJNM5ecCi0SK2IMKmSXR8vO3peL+kb1O0z7Zl83jKtutG4k5Wv/W7V3/YHvzPA==", - "dependencies": { - "@types/mdast": "^4.0.0", - "escape-string-regexp": "^5.0.0", - "unist-util-is": "^6.0.0", - "unist-util-visit-parents": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "engines": { + "node": ">=8" } }, - "node_modules/mdast-util-find-and-replace/node_modules/escape-string-regexp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", "engines": { "node": ">=12" }, @@ -9286,724 +10605,598 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/mdast-util-from-markdown": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.0.tgz", - "integrity": "sha512-n7MTOr/z+8NAX/wmhhDji8O3bRvPTV/U0oTCaZJkjhPSKTPhS3xufVhKGF8s1pJ7Ox4QgoIU7KHseh09S+9rTA==", + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "dependencies": { - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "mdast-util-to-string": "^4.0.0", - "micromark": "^4.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-decode-string": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unist-util-stringify-position": "^4.0.0" + "isobject": "^3.0.1" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/mdast-util-from-markdown/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] + "node_modules/is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==", + "engines": { + "node": ">=0.10.0" + } }, - "node_modules/mdast-util-frontmatter": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-frontmatter/-/mdast-util-frontmatter-2.0.1.tgz", - "integrity": "sha512-LRqI9+wdgC25P0URIJY9vwocIzCcksduHQ9OF2joxQoyTNVduwLAFUzjoopuRJbJAReaKrNQKAZKL3uCMugWJA==", - "dependencies": { - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "escape-string-regexp": "^5.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0", - "micromark-extension-frontmatter": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "node_modules/is-root": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-root/-/is-root-2.1.0.tgz", + "integrity": "sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg==", + "engines": { + "node": ">=6" } }, - "node_modules/mdast-util-frontmatter/node_modules/escape-string-regexp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "engines": { - "node": ">=12" + "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/mdast-util-gfm": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.0.0.tgz", - "integrity": "sha512-dgQEX5Amaq+DuUqf26jJqSK9qgixgd6rYDHAv4aTBuA92cTknZlKpPfa86Z/s8Dj8xsAQpFfBmPUHWJBWqS4Bw==", + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", "dependencies": { - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-gfm-autolink-literal": "^2.0.0", - "mdast-util-gfm-footnote": "^2.0.0", - "mdast-util-gfm-strikethrough": "^2.0.0", - "mdast-util-gfm-table": "^2.0.0", - "mdast-util-gfm-task-list-item": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" + "is-docker": "^2.0.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "engines": { + "node": ">=8" } }, - "node_modules/mdast-util-gfm-autolink-literal": { + "node_modules/is-yarn-global": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.4.1.tgz", + "integrity": "sha512-/kppl+R+LO5VmhYSEWARUFjodS25D68gvj8W7z0I7OWhUla5xWu8KL6CtB2V0R6yqhnRgbcaREMr4EEM6htLPQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" + }, + "node_modules/isexe": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.0.tgz", - "integrity": "sha512-FyzMsduZZHSc3i0Px3PQcBT4WJY/X/RCtEJKuybiC6sjPqLv7h1yqAkmILZtuxMSsUyaLUWNp71+vQH2zqp5cg==", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", "dependencies": { - "@types/mdast": "^4.0.0", - "ccount": "^2.0.0", - "devlop": "^1.0.0", - "mdast-util-find-and-replace": "^3.0.0", - "micromark-util-character": "^2.0.0" + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/mdast-util-gfm-autolink-literal/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], + "node_modules/jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/mdast-util-gfm-autolink-literal/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/mdast-util-gfm-footnote": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.0.0.tgz", - "integrity": "sha512-5jOT2boTSVkMnQ7LTrd6n/18kqwjmuYqo7JUPe+tRCY6O7dAuTFMtTPauYYrMPpox9hlN0uOx/FL8XvEfG9/mQ==", + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dependencies": { - "@types/mdast": "^4.0.0", - "devlop": "^1.1.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0" + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/mdast-util-gfm-strikethrough": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", - "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", + "node_modules/jiti": { + "version": "1.21.6", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz", + "integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==", + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/joi": { + "version": "17.13.3", + "resolved": "https://registry.npmjs.org/joi/-/joi-17.13.3.tgz", + "integrity": "sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==", "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "@hapi/hoek": "^9.3.0", + "@hapi/topo": "^5.1.0", + "@sideway/address": "^4.1.5", + "@sideway/formula": "^3.0.1", + "@sideway/pinpoint": "^2.0.0" } }, - "node_modules/mdast-util-gfm-table": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", - "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dependencies": { - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "markdown-table": "^3.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" + "argparse": "^2.0.1" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "node_modules/mdast-util-gfm-task-list-item": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", - "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", - "dependencies": { - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "bin": { + "jsesc": "bin/jsesc" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "engines": { + "node": ">=6" } }, - "node_modules/mdast-util-mdx": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-mdx/-/mdast-util-mdx-3.0.0.tgz", - "integrity": "sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==", - "dependencies": { - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-mdx-expression": "^2.0.0", - "mdast-util-mdx-jsx": "^3.0.0", - "mdast-util-mdxjs-esm": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "bin": { + "json5": "lib/cli.js" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "engines": { + "node": ">=6" } }, - "node_modules/mdast-util-mdx-expression": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.0.tgz", - "integrity": "sha512-fGCu8eWdKUKNu5mohVGkhBXCXGnOTLuFqOvGMvdikr+J1w7lDJgxThOKpwRWzzbyXAU2hhSwsmssOY4yTokluw==", + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", "dependencies": { - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" + "universalify": "^2.0.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "optionalDependencies": { + "graceful-fs": "^4.1.6" } }, - "node_modules/mdast-util-mdx-jsx": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.1.0.tgz", - "integrity": "sha512-A8AJHlR7/wPQ3+Jre1+1rq040fX9A4Q1jG8JxmSNp/PLPHg80A6475wxTp3KzHpApFH6yWxFotHrJQA3dXP6/w==", + "node_modules/katex": { + "version": "0.16.15", + "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.15.tgz", + "integrity": "sha512-yE9YJIEAk2aZ+FL/G8r+UGw0CTUzEA8ZFy6E+8tc3spHUKq3qBnzCkI1CQwGoI9atJhVyFPEypQsTY7mJ1Pi9w==", + "funding": [ + "https://opencollective.com/katex", + "https://github.com/sponsors/katex" + ], "dependencies": { - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "ccount": "^2.0.0", - "devlop": "^1.1.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0", - "parse-entities": "^4.0.0", - "stringify-entities": "^4.0.0", - "unist-util-remove-position": "^5.0.0", - "unist-util-stringify-position": "^4.0.0", - "vfile-message": "^4.0.0" + "commander": "^8.3.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "bin": { + "katex": "cli.js" } }, - "node_modules/mdast-util-mdxjs-esm": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz", - "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==", + "node_modules/katex/node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "engines": { + "node": ">= 12" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", "dependencies": { - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "json-buffer": "3.0.1" } }, - "node_modules/mdast-util-phrasing": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", - "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", + "node_modules/khroma": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/khroma/-/khroma-2.1.0.tgz", + "integrity": "sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw==" + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "engines": { + "node": ">=6" + } + }, + "node_modules/kolorist": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/kolorist/-/kolorist-1.8.0.tgz", + "integrity": "sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==" + }, + "node_modules/langium": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/langium/-/langium-3.0.0.tgz", + "integrity": "sha512-+Ez9EoiByeoTu/2BXmEaZ06iPNXM6thWJp02KfBO/raSMyCJ4jw7AkWWa+zBCTm0+Tw1Fj9FOxdqSskyN5nAwg==", "dependencies": { - "@types/mdast": "^4.0.0", - "unist-util-is": "^6.0.0" + "chevrotain": "~11.0.3", + "chevrotain-allstar": "~0.3.0", + "vscode-languageserver": "~9.0.1", + "vscode-languageserver-textdocument": "~1.0.11", + "vscode-uri": "~3.0.8" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "engines": { + "node": ">=16.0.0" } }, - "node_modules/mdast-util-to-hast": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.1.0.tgz", - "integrity": "sha512-/e2l/6+OdGp/FB+ctrJ9Avz71AN/GRH3oi/3KAx/kMnoUsD6q0woXlDT8lLEeViVKE7oZxE7RXzvO3T8kF2/sA==", + "node_modules/latest-version": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-7.0.0.tgz", + "integrity": "sha512-KvNT4XqAMzdcL6ka6Tl3i2lYeFDgXNCuIX+xNx6ZMVR1dFq+idXd9FLKNMOIx0t9mJ9/HudyX4oZWXZQ0UJHeg==", "dependencies": { - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "@ungap/structured-clone": "^1.0.0", - "devlop": "^1.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "trim-lines": "^3.0.0", - "unist-util-position": "^5.0.0", - "unist-util-visit": "^5.0.0", - "vfile": "^6.0.0" + "package-json": "^8.1.0" + }, + "engines": { + "node": ">=14.16" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/mdast-util-to-markdown": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.0.tgz", - "integrity": "sha512-SR2VnIEdVNCJbP6y7kVTJgPLifdr8WEU440fQec7qHoHOUz/oJ2jmNRqdDQ3rbiStOXb2mCDGTuwsK5OPUgYlQ==", + "node_modules/launch-editor": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.9.1.tgz", + "integrity": "sha512-Gcnl4Bd+hRO9P9icCP/RVVT2o8SFlPXofuCxvA2SaZuH45whSvf5p8x5oih5ftLiVhEI4sp5xDY+R+b3zJBh5w==", "dependencies": { - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "longest-streak": "^3.0.0", - "mdast-util-phrasing": "^4.0.0", - "mdast-util-to-string": "^4.0.0", - "micromark-util-decode-string": "^2.0.0", - "unist-util-visit": "^5.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "picocolors": "^1.0.0", + "shell-quote": "^1.8.1" + } + }, + "node_modules/layout-base": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/layout-base/-/layout-base-1.0.2.tgz", + "integrity": "sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==" + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "engines": { + "node": ">=6" } }, - "node_modules/mdast-util-to-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", - "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", - "dependencies": { - "@types/mdast": "^4.0.0" + "node_modules/lilconfig": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", + "engines": { + "node": ">=14" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "url": "https://github.com/sponsors/antonk52" } }, - "node_modules/mdn-data": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", - "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==" + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "node_modules/loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", "engines": { - "node": ">= 0.6" + "node": ">=6.11.5" } }, - "node_modules/memfs": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", - "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", + "node_modules/loader-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", "dependencies": { - "fs-monkey": "^1.0.4" + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" }, "engines": { - "node": ">= 4.0.0" + "node": ">=8.9.0" } }, - "node_modules/merge-descriptors": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", - "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "node_modules/local-pkg": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.5.1.tgz", + "integrity": "sha512-9rrA30MRRP3gBD3HTGnC6cDFpaE1kVDWxWgqWJUN0RvDNAo+Nz/9GxB+nHOH0ifbVFy0hSA1V6vFDvnx54lTEQ==", + "dependencies": { + "mlly": "^1.7.3", + "pkg-types": "^1.2.1" + }, + "engines": { + "node": ">=14" + }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/antfu" } }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "node_modules/locate-path": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", + "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", + "dependencies": { + "p-locate": "^6.0.0" + }, "engines": { - "node": ">= 8" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/mermaid": { - "version": "10.9.3", - "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-10.9.3.tgz", - "integrity": "sha512-V80X1isSEvAewIL3xhmz/rVmc27CVljcsbWxkxlWJWY/1kQa4XOABqpDl2qQLGKzpKm6WbTfUEKImBlUfFYArw==", - "dependencies": { - "@braintree/sanitize-url": "^6.0.1", - "@types/d3-scale": "^4.0.3", - "@types/d3-scale-chromatic": "^3.0.0", - "cytoscape": "^3.28.1", - "cytoscape-cose-bilkent": "^4.1.0", - "d3": "^7.4.0", - "d3-sankey": "^0.12.3", - "dagre-d3-es": "7.0.10", - "dayjs": "^1.11.7", - "dompurify": "^3.0.5 <3.1.7", - "elkjs": "^0.9.0", - "katex": "^0.16.9", - "khroma": "^2.0.0", - "lodash-es": "^4.17.21", - "mdast-util-from-markdown": "^1.3.0", - "non-layered-tidy-tree-layout": "^2.0.2", - "stylis": "^4.1.3", - "ts-dedent": "^2.2.0", - "uuid": "^9.0.0", - "web-worker": "^1.2.0" - } + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, - "node_modules/mermaid/node_modules/@types/mdast": { - "version": "3.0.15", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", - "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", - "dependencies": { - "@types/unist": "^2" - } + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" }, - "node_modules/mermaid/node_modules/@types/unist": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" }, - "node_modules/mermaid/node_modules/mdast-util-from-markdown": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.3.1.tgz", - "integrity": "sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww==", - "dependencies": { - "@types/mdast": "^3.0.0", - "@types/unist": "^2.0.0", - "decode-named-character-reference": "^1.0.0", - "mdast-util-to-string": "^3.1.0", - "micromark": "^3.0.0", - "micromark-util-decode-numeric-character-reference": "^1.0.0", - "micromark-util-decode-string": "^1.0.0", - "micromark-util-normalize-identifier": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "unist-util-stringify-position": "^3.0.0", - "uvu": "^0.5.0" - }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==" + }, + "node_modules/lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==" + }, + "node_modules/longest-streak": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", + "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/mermaid/node_modules/mdast-util-to-string": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz", - "integrity": "sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==", + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", "dependencies": { - "@types/mdast": "^3.0.0" + "js-tokens": "^3.0.0 || ^4.0.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "bin": { + "loose-envify": "cli.js" } }, - "node_modules/mermaid/node_modules/micromark": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-3.2.0.tgz", - "integrity": "sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], + "node_modules/lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", "dependencies": { - "@types/debug": "^4.0.0", - "debug": "^4.0.0", - "decode-named-character-reference": "^1.0.0", - "micromark-core-commonmark": "^1.0.1", - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-chunked": "^1.0.0", - "micromark-util-combine-extensions": "^1.0.0", - "micromark-util-decode-numeric-character-reference": "^1.0.0", - "micromark-util-encode": "^1.0.0", - "micromark-util-normalize-identifier": "^1.0.0", - "micromark-util-resolve-all": "^1.0.0", - "micromark-util-sanitize-uri": "^1.0.0", - "micromark-util-subtokenize": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.1", - "uvu": "^0.5.0" + "tslib": "^2.0.3" } }, - "node_modules/mermaid/node_modules/micromark-core-commonmark": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-1.1.0.tgz", - "integrity": "sha512-BgHO1aRbolh2hcrzL2d1La37V0Aoz73ymF8rAcKnohLy93titmv62E0gP8Hrx9PKcKrqCZ1BbLGbP3bEhoXYlw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "micromark-factory-destination": "^1.0.0", - "micromark-factory-label": "^1.0.0", - "micromark-factory-space": "^1.0.0", - "micromark-factory-title": "^1.0.0", - "micromark-factory-whitespace": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-chunked": "^1.0.0", - "micromark-util-classify-character": "^1.0.0", - "micromark-util-html-tag-name": "^1.0.0", - "micromark-util-normalize-identifier": "^1.0.0", - "micromark-util-resolve-all": "^1.0.0", - "micromark-util-subtokenize": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.1", - "uvu": "^0.5.0" + "node_modules/lowercase-keys": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", + "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/mermaid/node_modules/micromark-factory-destination": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-1.1.0.tgz", - "integrity": "sha512-XaNDROBgx9SgSChd69pjiGKbV+nfHGDPVYFs5dOoDd7ZnMAE+Cuu91BCpsY8RT2NP9vo/B8pds2VQNCLiu0zhg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dependencies": { - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" + "yallist": "^3.0.2" } }, - "node_modules/mermaid/node_modules/micromark-factory-label": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-1.1.0.tgz", - "integrity": "sha512-OLtyez4vZo/1NjxGhcpDSbHQ+m0IIGnT8BoPamh+7jVlzLJBH98zzuCoUeMxvM6WsNeh8wx8cKvqLiPHEACn0w==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "uvu": "^0.5.0" + "node_modules/lunr": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", + "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==" + }, + "node_modules/lunr-languages": { + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/lunr-languages/-/lunr-languages-1.14.0.tgz", + "integrity": "sha512-hWUAb2KqM3L7J5bcrngszzISY4BxrXn/Xhbb9TTCJYEGqlR1nG67/M14sp09+PTIRklobrn57IAxcdcO/ZFyNA==" + }, + "node_modules/mark.js": { + "version": "8.11.1", + "resolved": "https://registry.npmjs.org/mark.js/-/mark.js-8.11.1.tgz", + "integrity": "sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==" + }, + "node_modules/markdown-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/markdown-extensions/-/markdown-extensions-2.0.0.tgz", + "integrity": "sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/mermaid/node_modules/micromark-factory-title": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-1.1.0.tgz", - "integrity": "sha512-J7n9R3vMmgjDOCY8NPw55jiyaQnH5kBdV2/UXCtZIpnHH3P6nHUKaH7XXEYuWwx/xUJcawa8plLBEjMPU24HzQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" + "node_modules/markdown-table": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz", + "integrity": "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/mermaid/node_modules/micromark-factory-whitespace": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-1.1.0.tgz", - "integrity": "sha512-v2WlmiymVSp5oMg+1Q0N1Lxmt6pMhIHD457whWM7/GUlEks1hI9xj5w3zbc4uuMKXGisksZk8DzP2UyGbGqNsQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" + "node_modules/marked": { + "version": "13.0.3", + "resolved": "https://registry.npmjs.org/marked/-/marked-13.0.3.tgz", + "integrity": "sha512-rqRix3/TWzE9rIoFGIn8JmsVfhiuC8VIQ8IdX5TfzmeBucdY05/0UlzKaw0eVtpcN/OdVFpBk7CjKGo9iHJ/zA==", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 18" } }, - "node_modules/mermaid/node_modules/micromark-util-chunked": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-1.1.0.tgz", - "integrity": "sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^1.0.0" + "node_modules/math-intrinsics": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.0.0.tgz", + "integrity": "sha512-4MqMiKP90ybymYvsut0CH2g4XWbfLtmlCkXmtmdcDCxNB+mQcu1w/1+L/VD7vi/PSv7X2JYV7SCcR+jiPXnQtA==", + "engines": { + "node": ">= 0.4" } }, - "node_modules/mermaid/node_modules/micromark-util-classify-character": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-1.1.0.tgz", - "integrity": "sha512-SL0wLxtKSnklKSUplok1WQFoGhUdWYKggKUiqhX+Swala+BtptGCu5iPRc+xvzJ4PXE/hwM3FNXsfEVgoZsWbw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], + "node_modules/mdast-util-directive": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-directive/-/mdast-util-directive-3.0.0.tgz", + "integrity": "sha512-JUpYOqKI4mM3sZcNxmF/ox04XYFFkNwr0CFlrQIkCwbvH0xzMCqkMqAde9wRd80VAhaUrwFwKm2nxretdT1h7Q==", "dependencies": { - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "parse-entities": "^4.0.0", + "stringify-entities": "^4.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/mermaid/node_modules/micromark-util-combine-extensions": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-1.1.0.tgz", - "integrity": "sha512-Q20sp4mfNf9yEqDL50WwuWZHUrCO4fEyeDCnMGmG5Pr0Cz15Uo7KBs6jq+dq0EgX4DPwwrh9m0X+zPV1ypFvUA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], + "node_modules/mdast-util-find-and-replace": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.1.tgz", + "integrity": "sha512-SG21kZHGC3XRTSUhtofZkBzZTJNM5ecCi0SK2IMKmSXR8vO3peL+kb1O0z7Zl83jKtutG4k5Wv/W7V3/YHvzPA==", "dependencies": { - "micromark-util-chunked": "^1.0.0", - "micromark-util-types": "^1.0.0" + "@types/mdast": "^4.0.0", + "escape-string-regexp": "^5.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/mermaid/node_modules/micromark-util-decode-numeric-character-reference": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-1.1.0.tgz", - "integrity": "sha512-m9V0ExGv0jB1OT21mrWcuf4QhP46pH1KkfWy9ZEezqHKAxkj4mPCy3nIH1rkbdMlChLHX531eOrymlwyZIf2iw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], + "node_modules/mdast-util-find-and-replace/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mdast-util-find-and-replace/node_modules/unist-util-is": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", + "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", "dependencies": { - "micromark-util-symbol": "^1.0.0" + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/mermaid/node_modules/micromark-util-decode-string": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-1.1.0.tgz", - "integrity": "sha512-YphLGCK8gM1tG1bd54azwyrQRjCFcmgj2S2GoJDNnh4vYtnL38JS8M4gpxzOPNyHdNEpheyWXCTnnTDY3N+NVQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], + "node_modules/mdast-util-from-markdown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz", + "integrity": "sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==", "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", "decode-named-character-reference": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-decode-numeric-character-reference": "^1.0.0", - "micromark-util-symbol": "^1.0.0" + "devlop": "^1.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark": "^4.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/mermaid/node_modules/micromark-util-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-1.1.0.tgz", - "integrity": "sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/mermaid/node_modules/micromark-util-html-tag-name": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.2.0.tgz", - "integrity": "sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q==", + "node_modules/mdast-util-from-markdown/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", "funding": [ { "type": "GitHub Sponsors", @@ -10015,66 +11208,72 @@ } ] }, - "node_modules/mermaid/node_modules/micromark-util-normalize-identifier": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.1.0.tgz", - "integrity": "sha512-N+w5vhqrBihhjdpM8+5Xsxy71QWqGn7HYNUvch71iV2PM7+E3uWGox1Qp90loa1ephtCxG2ftRV/Conitc6P2Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], + "node_modules/mdast-util-frontmatter": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-frontmatter/-/mdast-util-frontmatter-2.0.1.tgz", + "integrity": "sha512-LRqI9+wdgC25P0URIJY9vwocIzCcksduHQ9OF2joxQoyTNVduwLAFUzjoopuRJbJAReaKrNQKAZKL3uCMugWJA==", "dependencies": { - "micromark-util-symbol": "^1.0.0" + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "escape-string-regexp": "^5.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "micromark-extension-frontmatter": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/mermaid/node_modules/micromark-util-resolve-all": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-1.1.0.tgz", - "integrity": "sha512-b/G6BTMSg+bX+xVCshPTPyAu2tmA0E4X98NSR7eIbeC6ycCqCeE7wjfDIgzEbkzdEVJXRtOG4FbEm/uGbCRouA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], + "node_modules/mdast-util-frontmatter/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mdast-util-gfm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.0.0.tgz", + "integrity": "sha512-dgQEX5Amaq+DuUqf26jJqSK9qgixgd6rYDHAv4aTBuA92cTknZlKpPfa86Z/s8Dj8xsAQpFfBmPUHWJBWqS4Bw==", "dependencies": { - "micromark-util-types": "^1.0.0" + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-gfm-autolink-literal": "^2.0.0", + "mdast-util-gfm-footnote": "^2.0.0", + "mdast-util-gfm-strikethrough": "^2.0.0", + "mdast-util-gfm-table": "^2.0.0", + "mdast-util-gfm-task-list-item": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/mermaid/node_modules/micromark-util-sanitize-uri": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.2.0.tgz", - "integrity": "sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], + "node_modules/mdast-util-gfm-autolink-literal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz", + "integrity": "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==", "dependencies": { - "micromark-util-character": "^1.0.0", - "micromark-util-encode": "^1.0.0", - "micromark-util-symbol": "^1.0.0" + "@types/mdast": "^4.0.0", + "ccount": "^2.0.0", + "devlop": "^1.0.0", + "mdast-util-find-and-replace": "^3.0.0", + "micromark-util-character": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/mermaid/node_modules/micromark-util-subtokenize": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-1.1.0.tgz", - "integrity": "sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A==", + "node_modules/mdast-util-gfm-autolink-literal/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", "funding": [ { "type": "GitHub Sponsors", @@ -10086,16 +11285,14 @@ } ], "dependencies": { - "micromark-util-chunked": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "uvu": "^0.5.0" + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" } }, - "node_modules/mermaid/node_modules/micromark-util-types": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", - "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", + "node_modules/mdast-util-gfm-autolink-literal/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", "funding": [ { "type": "GitHub Sponsors", @@ -10107,28 +11304,296 @@ } ] }, - "node_modules/mermaid/node_modules/unist-util-stringify-position": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz", - "integrity": "sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==", + "node_modules/mdast-util-gfm-footnote": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.0.0.tgz", + "integrity": "sha512-5jOT2boTSVkMnQ7LTrd6n/18kqwjmuYqo7JUPe+tRCY6O7dAuTFMtTPauYYrMPpox9hlN0uOx/FL8XvEfG9/mQ==", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-strikethrough": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", + "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-table": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", + "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "markdown-table": "^3.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-task-list-item": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", + "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-mdx/-/mdast-util-mdx-3.0.0.tgz", + "integrity": "sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==", + "dependencies": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-expression": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.1.tgz", + "integrity": "sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-jsx": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.1.3.tgz", + "integrity": "sha512-bfOjvNt+1AcbPLTFMFWY149nJz0OjmewJs3LQQ5pIyVGxP4CdOqNVJL6kTaM5c68p8q82Xv3nCyFfUnuEcH3UQ==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "parse-entities": "^4.0.0", + "stringify-entities": "^4.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdxjs-esm": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz", + "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-phrasing": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", + "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", + "dependencies": { + "@types/mdast": "^4.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-phrasing/node_modules/unist-util-is": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", + "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-hast": { + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz", + "integrity": "sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@ungap/structured-clone": "^1.0.0", + "devlop": "^1.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "trim-lines": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-markdown": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz", + "integrity": "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "longest-streak": "^3.0.0", + "mdast-util-phrasing": "^4.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "unist-util-visit": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-markdown/node_modules/zwitch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/mdast-util-to-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", + "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", "dependencies": { - "@types/unist": "^2.0.0" + "@types/mdast": "^4.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/mermaid/node_modules/uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], - "bin": { - "uuid": "dist/bin/uuid" + "node_modules/mdn-data": { + "version": "2.0.30", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==" + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/memfs": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", + "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", + "dependencies": { + "fs-monkey": "^1.0.4" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/mermaid": { + "version": "11.4.1", + "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-11.4.1.tgz", + "integrity": "sha512-Mb01JT/x6CKDWaxigwfZYuYmDZ6xtrNwNlidKZwkSrDaY9n90tdrJTV5Umk+wP1fZscGptmKFXHsXMDEVZ+Q6A==", + "dependencies": { + "@braintree/sanitize-url": "^7.0.1", + "@iconify/utils": "^2.1.32", + "@mermaid-js/parser": "^0.3.0", + "@types/d3": "^7.4.3", + "cytoscape": "^3.29.2", + "cytoscape-cose-bilkent": "^4.1.0", + "cytoscape-fcose": "^2.2.0", + "d3": "^7.9.0", + "d3-sankey": "^0.12.3", + "dagre-d3-es": "7.0.11", + "dayjs": "^1.11.10", + "dompurify": "^3.2.1", + "katex": "^0.16.9", + "khroma": "^2.1.0", + "lodash-es": "^4.17.21", + "marked": "^13.0.2", + "roughjs": "^4.6.6", + "stylis": "^4.3.1", + "ts-dedent": "^2.2.0", + "uuid": "^9.0.1" } }, "node_modules/methods": { @@ -10140,9 +11605,9 @@ } }, "node_modules/micromark": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.0.tgz", - "integrity": "sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.1.tgz", + "integrity": "sha512-eBPdkcoCNvYcxQOAKAlceo5SNdzZWfF+FcSupREAzdAh9rRmE239CEQAiTwIgblwnoM8zzj35sZ5ZwvSEOF6Kw==", "funding": [ { "type": "GitHub Sponsors", @@ -10174,9 +11639,9 @@ } }, "node_modules/micromark-core-commonmark": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.0.tgz", - "integrity": "sha512-jThOz/pVmAYUtkroV3D5c1osFXAMv9e0ypGDOIZuCeAe91/sD6BoE2Sjzt30yuXtwOYUmySOhMas/PVyh02itA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.2.tgz", + "integrity": "sha512-FKjQKbxd1cibWMM1P9N+H8TwlgGgSkWZMmfuVucLCHaYqeSvJ0hFeHsIa65pA2nYbes0f8LDHPMrd9X7Ujxg9w==", "funding": [ { "type": "GitHub Sponsors", @@ -10207,9 +11672,9 @@ } }, "node_modules/micromark-core-commonmark/node_modules/micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", "funding": [ { "type": "GitHub Sponsors", @@ -10226,9 +11691,9 @@ } }, "node_modules/micromark-core-commonmark/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", "funding": [ { "type": "GitHub Sponsors", @@ -10245,9 +11710,9 @@ } }, "node_modules/micromark-core-commonmark/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", "funding": [ { "type": "GitHub Sponsors", @@ -10260,9 +11725,9 @@ ] }, "node_modules/micromark-extension-directive": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-directive/-/micromark-extension-directive-3.0.0.tgz", - "integrity": "sha512-61OI07qpQrERc+0wEysLHMvoiO3s2R56x5u7glHq2Yqq6EHbH4dW25G9GfDdGCDYqA21KE6DWgNSzxSwHc2hSg==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/micromark-extension-directive/-/micromark-extension-directive-3.0.2.tgz", + "integrity": "sha512-wjcXHgk+PPdmvR58Le9d7zQYWy+vKEU9Se44p2CrCDPiLr2FMyiT4Fyb5UFKFC66wGB3kPlgD7q3TnoqPS7SZA==", "dependencies": { "devlop": "^1.0.0", "micromark-factory-space": "^2.0.0", @@ -10278,9 +11743,9 @@ } }, "node_modules/micromark-extension-directive/node_modules/micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", "funding": [ { "type": "GitHub Sponsors", @@ -10297,9 +11762,9 @@ } }, "node_modules/micromark-extension-directive/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", "funding": [ { "type": "GitHub Sponsors", @@ -10316,9 +11781,9 @@ } }, "node_modules/micromark-extension-directive/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", "funding": [ { "type": "GitHub Sponsors", @@ -10346,9 +11811,9 @@ } }, "node_modules/micromark-extension-frontmatter/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", "funding": [ { "type": "GitHub Sponsors", @@ -10365,9 +11830,9 @@ } }, "node_modules/micromark-extension-frontmatter/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", "funding": [ { "type": "GitHub Sponsors", @@ -10399,9 +11864,9 @@ } }, "node_modules/micromark-extension-gfm-autolink-literal": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.0.0.tgz", - "integrity": "sha512-rTHfnpt/Q7dEAK1Y5ii0W8bhfJlVJFnJMHIPisfPK3gpVNuOP0VnRl96+YJ3RYWV/P4gFeQoGKNlT3RhuvpqAg==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", + "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-sanitize-uri": "^2.0.0", @@ -10414,9 +11879,9 @@ } }, "node_modules/micromark-extension-gfm-autolink-literal/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", "funding": [ { "type": "GitHub Sponsors", @@ -10433,9 +11898,9 @@ } }, "node_modules/micromark-extension-gfm-autolink-literal/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", "funding": [ { "type": "GitHub Sponsors", @@ -10448,9 +11913,9 @@ ] }, "node_modules/micromark-extension-gfm-footnote": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.0.0.tgz", - "integrity": "sha512-6Rzu0CYRKDv3BfLAUnZsSlzx3ak6HAoI85KTiijuKIz5UxZxbUI+pD6oHgw+6UtQuiRwnGRhzMmPRv4smcz0fg==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", "dependencies": { "devlop": "^1.0.0", "micromark-core-commonmark": "^2.0.0", @@ -10467,9 +11932,9 @@ } }, "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", "funding": [ { "type": "GitHub Sponsors", @@ -10486,9 +11951,9 @@ } }, "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", "funding": [ { "type": "GitHub Sponsors", @@ -10505,9 +11970,9 @@ } }, "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", "funding": [ { "type": "GitHub Sponsors", @@ -10520,9 +11985,9 @@ ] }, "node_modules/micromark-extension-gfm-strikethrough": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.0.0.tgz", - "integrity": "sha512-c3BR1ClMp5fxxmwP6AoOY2fXO9U8uFMKs4ADD66ahLTNcwzSCyRVU4k7LPV5Nxo/VJiR4TdzxRQY2v3qIUceCw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz", + "integrity": "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==", "dependencies": { "devlop": "^1.0.0", "micromark-util-chunked": "^2.0.0", @@ -10537,9 +12002,9 @@ } }, "node_modules/micromark-extension-gfm-strikethrough/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", "funding": [ { "type": "GitHub Sponsors", @@ -10552,9 +12017,9 @@ ] }, "node_modules/micromark-extension-gfm-table": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.0.0.tgz", - "integrity": "sha512-PoHlhypg1ItIucOaHmKE8fbin3vTLpDOUg8KAr8gRCF1MOZI9Nquq2i/44wFvviM4WuxJzc3demT8Y3dkfvYrw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.0.tgz", + "integrity": "sha512-Ub2ncQv+fwD70/l4ou27b4YzfNaCJOvyX4HxXU15m7mpYY+rjuWzsLIPZHJL253Z643RpbcP1oeIJlQ/SKW67g==", "dependencies": { "devlop": "^1.0.0", "micromark-factory-space": "^2.0.0", @@ -10568,9 +12033,9 @@ } }, "node_modules/micromark-extension-gfm-table/node_modules/micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", "funding": [ { "type": "GitHub Sponsors", @@ -10587,9 +12052,9 @@ } }, "node_modules/micromark-extension-gfm-table/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", "funding": [ { "type": "GitHub Sponsors", @@ -10606,9 +12071,9 @@ } }, "node_modules/micromark-extension-gfm-table/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", "funding": [ { "type": "GitHub Sponsors", @@ -10633,9 +12098,9 @@ } }, "node_modules/micromark-extension-gfm-task-list-item": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.0.1.tgz", - "integrity": "sha512-cY5PzGcnULaN5O7T+cOzfMoHjBW7j+T9D2sucA5d/KbsBTPcYdebm9zUd9zzdgJGCwahV+/W78Z3nbulBYVbTw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz", + "integrity": "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==", "dependencies": { "devlop": "^1.0.0", "micromark-factory-space": "^2.0.0", @@ -10649,9 +12114,9 @@ } }, "node_modules/micromark-extension-gfm-task-list-item/node_modules/micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", "funding": [ { "type": "GitHub Sponsors", @@ -10668,9 +12133,9 @@ } }, "node_modules/micromark-extension-gfm-task-list-item/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", "funding": [ { "type": "GitHub Sponsors", @@ -10687,9 +12152,9 @@ } }, "node_modules/micromark-extension-gfm-task-list-item/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", "funding": [ { "type": "GitHub Sponsors", @@ -10727,9 +12192,9 @@ } }, "node_modules/micromark-extension-mdx-expression/node_modules/micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", "funding": [ { "type": "GitHub Sponsors", @@ -10746,9 +12211,9 @@ } }, "node_modules/micromark-extension-mdx-expression/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", "funding": [ { "type": "GitHub Sponsors", @@ -10765,9 +12230,9 @@ } }, "node_modules/micromark-extension-mdx-expression/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", "funding": [ { "type": "GitHub Sponsors", @@ -10780,9 +12245,9 @@ ] }, "node_modules/micromark-extension-mdx-jsx": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-mdx-jsx/-/micromark-extension-mdx-jsx-3.0.0.tgz", - "integrity": "sha512-uvhhss8OGuzR4/N17L1JwvmJIpPhAd8oByMawEKx6NVdBCbesjH4t+vjEp3ZXft9DwvlKSD07fCeI44/N0Vf2w==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-jsx/-/micromark-extension-mdx-jsx-3.0.1.tgz", + "integrity": "sha512-vNuFb9czP8QCtAQcEJn0UJQJZA8Dk6DXKBqx+bg/w0WGuSxDxNr7hErW89tHUY31dUW4NqEOWwmEUNhjTFmHkg==", "dependencies": { "@types/acorn": "^4.0.0", "@types/estree": "^1.0.0", @@ -10791,6 +12256,7 @@ "micromark-factory-mdx-expression": "^2.0.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0", "vfile-message": "^4.0.0" @@ -10801,9 +12267,9 @@ } }, "node_modules/micromark-extension-mdx-jsx/node_modules/micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", "funding": [ { "type": "GitHub Sponsors", @@ -10820,9 +12286,9 @@ } }, "node_modules/micromark-extension-mdx-jsx/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", "funding": [ { "type": "GitHub Sponsors", @@ -10839,9 +12305,9 @@ } }, "node_modules/micromark-extension-mdx-jsx/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", "funding": [ { "type": "GitHub Sponsors", @@ -10905,9 +12371,9 @@ } }, "node_modules/micromark-extension-mdxjs-esm/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", "funding": [ { "type": "GitHub Sponsors", @@ -10924,9 +12390,9 @@ } }, "node_modules/micromark-extension-mdxjs-esm/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", "funding": [ { "type": "GitHub Sponsors", @@ -10939,9 +12405,9 @@ ] }, "node_modules/micromark-factory-destination": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.0.tgz", - "integrity": "sha512-j9DGrQLm/Uhl2tCzcbLhy5kXsgkHUrjJHg4fFAeoMRwJmJerT9aw4FEhIbZStWN8A3qMwOp1uzHr4UL8AInxtA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", + "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==", "funding": [ { "type": "GitHub Sponsors", @@ -10959,9 +12425,9 @@ } }, "node_modules/micromark-factory-destination/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", "funding": [ { "type": "GitHub Sponsors", @@ -10978,9 +12444,9 @@ } }, "node_modules/micromark-factory-destination/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", "funding": [ { "type": "GitHub Sponsors", @@ -10993,9 +12459,9 @@ ] }, "node_modules/micromark-factory-label": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.0.tgz", - "integrity": "sha512-RR3i96ohZGde//4WSe/dJsxOX6vxIg9TimLAS3i4EhBAFx8Sm5SmqVfR8E87DPSR31nEAjZfbt91OMZWcNgdZw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz", + "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==", "funding": [ { "type": "GitHub Sponsors", @@ -11014,9 +12480,9 @@ } }, "node_modules/micromark-factory-label/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", "funding": [ { "type": "GitHub Sponsors", @@ -11033,9 +12499,9 @@ } }, "node_modules/micromark-factory-label/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", "funding": [ { "type": "GitHub Sponsors", @@ -11048,9 +12514,9 @@ ] }, "node_modules/micromark-factory-mdx-expression": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-mdx-expression/-/micromark-factory-mdx-expression-2.0.1.tgz", - "integrity": "sha512-F0ccWIUHRLRrYp5TC9ZYXmZo+p2AM13ggbsW4T0b5CRKP8KHVRB8t4pwtBgTxtjRmwrK0Irwm7vs2JOZabHZfg==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-factory-mdx-expression/-/micromark-factory-mdx-expression-2.0.2.tgz", + "integrity": "sha512-5E5I2pFzJyg2CtemqAbcyCktpHXuJbABnsb32wX2U8IQKhhVFBqkcZR5LRm1WVoFqa4kTueZK4abep7wdo9nrw==", "funding": [ { "type": "GitHub Sponsors", @@ -11064,6 +12530,7 @@ "dependencies": { "@types/estree": "^1.0.0", "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-events-to-acorn": "^2.0.0", "micromark-util-symbol": "^2.0.0", @@ -11072,10 +12539,29 @@ "vfile-message": "^4.0.0" } }, + "node_modules/micromark-factory-mdx-expression/node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, "node_modules/micromark-factory-mdx-expression/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", "funding": [ { "type": "GitHub Sponsors", @@ -11092,9 +12578,9 @@ } }, "node_modules/micromark-factory-mdx-expression/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", "funding": [ { "type": "GitHub Sponsors", @@ -11141,9 +12627,9 @@ ] }, "node_modules/micromark-factory-title": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.0.tgz", - "integrity": "sha512-jY8CSxmpWLOxS+t8W+FG3Xigc0RDQA9bKMY/EwILvsesiRniiVMejYTE4wumNc2f4UbAa4WsHqe3J1QS1sli+A==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz", + "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==", "funding": [ { "type": "GitHub Sponsors", @@ -11162,9 +12648,9 @@ } }, "node_modules/micromark-factory-title/node_modules/micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", "funding": [ { "type": "GitHub Sponsors", @@ -11181,9 +12667,9 @@ } }, "node_modules/micromark-factory-title/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", "funding": [ { "type": "GitHub Sponsors", @@ -11200,9 +12686,9 @@ } }, "node_modules/micromark-factory-title/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", "funding": [ { "type": "GitHub Sponsors", @@ -11215,9 +12701,9 @@ ] }, "node_modules/micromark-factory-whitespace": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.0.tgz", - "integrity": "sha512-28kbwaBjc5yAI1XadbdPYHX/eDnqaUFVikLwrO7FDnKG7lpgxnvk/XGRhX/PN0mOZ+dBSZ+LgunHS+6tYQAzhA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz", + "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==", "funding": [ { "type": "GitHub Sponsors", @@ -11236,9 +12722,9 @@ } }, "node_modules/micromark-factory-whitespace/node_modules/micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", "funding": [ { "type": "GitHub Sponsors", @@ -11255,9 +12741,9 @@ } }, "node_modules/micromark-factory-whitespace/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", "funding": [ { "type": "GitHub Sponsors", @@ -11274,9 +12760,9 @@ } }, "node_modules/micromark-factory-whitespace/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", "funding": [ { "type": "GitHub Sponsors", @@ -11323,9 +12809,9 @@ ] }, "node_modules/micromark-util-chunked": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.0.tgz", - "integrity": "sha512-anK8SWmNphkXdaKgz5hJvGa7l00qmcaUQoMYsBwDlSKFKjc6gjGXPDw3FNL3Nbwq5L8gE+RCbGqTw49FK5Qyvg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz", + "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==", "funding": [ { "type": "GitHub Sponsors", @@ -11341,9 +12827,9 @@ } }, "node_modules/micromark-util-chunked/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", "funding": [ { "type": "GitHub Sponsors", @@ -11356,9 +12842,9 @@ ] }, "node_modules/micromark-util-classify-character": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.0.tgz", - "integrity": "sha512-S0ze2R9GH+fu41FA7pbSqNWObo/kzwf8rN/+IGlW/4tC6oACOs8B++bh+i9bVyNnwCcuksbFwsBme5OCKXCwIw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz", + "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==", "funding": [ { "type": "GitHub Sponsors", @@ -11376,9 +12862,9 @@ } }, "node_modules/micromark-util-classify-character/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", "funding": [ { "type": "GitHub Sponsors", @@ -11395,9 +12881,9 @@ } }, "node_modules/micromark-util-classify-character/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", "funding": [ { "type": "GitHub Sponsors", @@ -11410,9 +12896,9 @@ ] }, "node_modules/micromark-util-combine-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.0.tgz", - "integrity": "sha512-vZZio48k7ON0fVS3CUgFatWHoKbbLTK/rT7pzpJ4Bjp5JjkZeasRfrS9wsBdDJK2cJLHMckXZdzPSSr1B8a4oQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz", + "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==", "funding": [ { "type": "GitHub Sponsors", @@ -11429,9 +12915,9 @@ } }, "node_modules/micromark-util-decode-numeric-character-reference": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.1.tgz", - "integrity": "sha512-bmkNc7z8Wn6kgjZmVHOX3SowGmVdhYS7yBpMnuMnPzDq/6xwVA604DuOXMZTO1lvq01g+Adfa0pE2UKGlxL1XQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz", + "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==", "funding": [ { "type": "GitHub Sponsors", @@ -11447,9 +12933,9 @@ } }, "node_modules/micromark-util-decode-numeric-character-reference/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", "funding": [ { "type": "GitHub Sponsors", @@ -11462,9 +12948,9 @@ ] }, "node_modules/micromark-util-decode-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.0.tgz", - "integrity": "sha512-r4Sc6leeUTn3P6gk20aFMj2ntPwn6qpDZqWvYmAG6NgvFTIlj4WtrAudLi65qYoaGdXYViXYw2pkmn7QnIFasA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz", + "integrity": "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==", "funding": [ { "type": "GitHub Sponsors", @@ -11483,9 +12969,9 @@ } }, "node_modules/micromark-util-decode-string/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", "funding": [ { "type": "GitHub Sponsors", @@ -11502,9 +12988,9 @@ } }, "node_modules/micromark-util-decode-string/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", "funding": [ { "type": "GitHub Sponsors", @@ -11517,9 +13003,9 @@ ] }, "node_modules/micromark-util-encode": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.0.tgz", - "integrity": "sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", + "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", "funding": [ { "type": "GitHub Sponsors", @@ -11557,9 +13043,9 @@ } }, "node_modules/micromark-util-events-to-acorn/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", "funding": [ { "type": "GitHub Sponsors", @@ -11572,9 +13058,9 @@ ] }, "node_modules/micromark-util-html-tag-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.0.tgz", - "integrity": "sha512-xNn4Pqkj2puRhKdKTm8t1YHC/BAjx6CEwRFXntTaRf/x16aqka6ouVoutm+QdkISTlT7e2zU7U4ZdlDLJd2Mcw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz", + "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==", "funding": [ { "type": "GitHub Sponsors", @@ -11587,9 +13073,9 @@ ] }, "node_modules/micromark-util-normalize-identifier": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.0.tgz", - "integrity": "sha512-2xhYT0sfo85FMrUPtHcPo2rrp1lwbDEEzpx7jiH2xXJLqBuy4H0GgXk5ToU8IEwoROtXuL8ND0ttVa4rNqYK3w==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz", + "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==", "funding": [ { "type": "GitHub Sponsors", @@ -11605,9 +13091,9 @@ } }, "node_modules/micromark-util-normalize-identifier/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", "funding": [ { "type": "GitHub Sponsors", @@ -11620,9 +13106,9 @@ ] }, "node_modules/micromark-util-resolve-all": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.0.tgz", - "integrity": "sha512-6KU6qO7DZ7GJkaCgwBNtplXCvGkJToU86ybBAUdavvgsCiG8lSSvYxr9MhwmQ+udpzywHsl4RpGJsYWG1pDOcA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz", + "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==", "funding": [ { "type": "GitHub Sponsors", @@ -11638,9 +13124,9 @@ } }, "node_modules/micromark-util-sanitize-uri": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.0.tgz", - "integrity": "sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", + "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", "funding": [ { "type": "GitHub Sponsors", @@ -11658,9 +13144,9 @@ } }, "node_modules/micromark-util-sanitize-uri/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", "funding": [ { "type": "GitHub Sponsors", @@ -11677,9 +13163,9 @@ } }, "node_modules/micromark-util-sanitize-uri/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", "funding": [ { "type": "GitHub Sponsors", @@ -11692,9 +13178,9 @@ ] }, "node_modules/micromark-util-subtokenize": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.0.0.tgz", - "integrity": "sha512-vc93L1t+gpR3p8jxeVdaYlbV2jTYteDje19rNSS/H5dlhxUYll5Fy6vJ2cDwP8RnsXi818yGty1ayP55y3W6fg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.0.3.tgz", + "integrity": "sha512-VXJJuNxYWSoYL6AJ6OQECCFGhIU2GGHMw8tahogePBrjkG8aCCas3ibkp7RnVOSTClg2is05/R7maAhF1XyQMg==", "funding": [ { "type": "GitHub Sponsors", @@ -11713,9 +13199,9 @@ } }, "node_modules/micromark-util-subtokenize/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", "funding": [ { "type": "GitHub Sponsors", @@ -11743,9 +13229,9 @@ ] }, "node_modules/micromark-util-types": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.0.tgz", - "integrity": "sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.1.tgz", + "integrity": "sha512-534m2WhVTddrcKVepwmVEVnUAmtrx9bfIjNoQHRqfnvdaHQiFytEhJoTgpWJvDEXCO5gLTQh3wYC1PgOJA4NSQ==", "funding": [ { "type": "GitHub Sponsors", @@ -11758,9 +13244,9 @@ ] }, "node_modules/micromark/node_modules/micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", "funding": [ { "type": "GitHub Sponsors", @@ -11777,9 +13263,9 @@ } }, "node_modules/micromark/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", "funding": [ { "type": "GitHub Sponsors", @@ -11796,9 +13282,9 @@ } }, "node_modules/micromark/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", "funding": [ { "type": "GitHub Sponsors", @@ -11872,11 +13358,12 @@ } }, "node_modules/mini-css-extract-plugin": { - "version": "2.7.7", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.7.7.tgz", - "integrity": "sha512-+0n11YGyRavUR3IlaOzJ0/4Il1avMvJ1VJfhWfCn24ITQXhRr1gghbhhrda6tgtNcpZaWKdSuwKq20Jb7fnlyw==", + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.2.tgz", + "integrity": "sha512-GJuACcS//jtq4kCtd5ii/M0SZf7OZRH+BxdqXZHaJfb8TJiVl+NgQRPwiYt2EuqeSkNydn/7vP+bcE27C5mb9w==", "dependencies": { - "schema-utils": "^4.0.0" + "schema-utils": "^4.0.0", + "tapable": "^2.2.1" }, "engines": { "node": ">= 12.13.0" @@ -11922,12 +13409,15 @@ "node": "*" } }, - "node_modules/mri": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", - "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", - "engines": { - "node": ">=4" + "node_modules/mlly": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.3.tgz", + "integrity": "sha512-xUsx5n/mN0uQf4V548PKQ+YShA4/IW0KI1dZhrNrPCLG+xizETbHTkOa1f8/xut9JRPp8kQuMnz0oqwkTiLo/A==", + "dependencies": { + "acorn": "^8.14.0", + "pathe": "^1.1.2", + "pkg-types": "^1.2.1", + "ufo": "^1.5.4" } }, "node_modules/mrmime": { @@ -11939,9 +13429,9 @@ } }, "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, "node_modules/multicast-dns": { "version": "7.2.5", @@ -11973,9 +13463,9 @@ } }, "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", + "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", "engines": { "node": ">= 0.6" } @@ -11995,9 +13485,9 @@ } }, "node_modules/node-emoji": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-2.1.3.tgz", - "integrity": "sha512-E2WEOVsgs7O16zsURJ/eH8BqhF029wGpEOnv7Urwdo2wmQanOACwJQh0devF9D9RhoZru0+9JXIS0dBXIAz+lA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-2.2.0.tgz", + "integrity": "sha512-Z3lTE9pLaJF47NyMhd4ww1yFTAP8YhYI8SleJiHzM46Fgpm5cnNzSl9XfzFNqbaz+VlJrIj3fXQ4DeN1Rjm6cw==", "dependencies": { "@sindresorhus/is": "^4.6.0", "char-regex": "^1.0.2", @@ -12021,11 +13511,6 @@ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==" }, - "node_modules/non-layered-tidy-tree-layout": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/non-layered-tidy-tree-layout/-/non-layered-tidy-tree-layout-2.0.2.tgz", - "integrity": "sha512-gkXMxRzUH+PB0ax9dUN0yYF0S25BqeAYqhgMaLUFmpXLEk7Fcu8f4emJuOAY0V8kjDICxROIKsTAKsV/v355xw==" - }, "node_modules/nopt": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", @@ -12057,11 +13542,11 @@ } }, "node_modules/normalize-url": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", - "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.1.tgz", + "integrity": "sha512-IO9QvjUMWxPQQhs60oOu10CRkWCiZzSUkzbXGGV9pviYl1fXYcvkzQ5jV9z8Y6un8ARoVRl4EtC6v6jNqbaJ/w==", "engines": { - "node": ">=10" + "node": ">=14.16" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -12077,26 +13562,90 @@ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", "dependencies": { - "path-key": "^3.0.0" + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nprogress": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/nprogress/-/nprogress-0.2.0.tgz", + "integrity": "sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA==" + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/null-loader": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/null-loader/-/null-loader-4.0.1.tgz", + "integrity": "sha512-pxqVbi4U6N26lq+LmgIbB5XATP0VdZKOG25DhHi8btMmJJefGArFyDg1yc4U3hWCJbMqSrw0qyrz1UQX+qYXqg==", + "dependencies": { + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/null-loader/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" }, - "engines": { - "node": ">=8" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/nprogress": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/nprogress/-/nprogress-0.2.0.tgz", - "integrity": "sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA==" + "node_modules/null-loader/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "peerDependencies": { + "ajv": "^6.9.1" + } }, - "node_modules/nth-check": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", - "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "node_modules/null-loader/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "node_modules/null-loader/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", "dependencies": { - "boolbase": "^1.0.0" + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" }, "funding": { - "url": "https://github.com/fb55/nth-check?sponsor=1" + "type": "opencollective", + "url": "https://opencollective.com/webpack" } }, "node_modules/object-assign": { @@ -12300,6 +13849,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/package-manager-detector": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-0.2.7.tgz", + "integrity": "sha512-g4+387DXDKlZzHkP+9FLt8yKj8+/3tOkPv7DVTJGGRm00RkEWgqbFstX1mXJ4M0VDYhUqsTOiISqNOJnhAu3PQ==" + }, "node_modules/param-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", @@ -12321,12 +13875,11 @@ } }, "node_modules/parse-entities": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.1.tgz", - "integrity": "sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.2.tgz", + "integrity": "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==", "dependencies": { "@types/unist": "^2.0.0", - "character-entities": "^2.0.0", "character-entities-legacy": "^3.0.0", "character-reference-invalid": "^2.0.0", "decode-named-character-reference": "^1.0.0", @@ -12340,9 +13893,9 @@ } }, "node_modules/parse-entities/node_modules/@types/unist": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==" }, "node_modules/parse-json": { "version": "5.2.0", @@ -12367,22 +13920,22 @@ "integrity": "sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ==" }, "node_modules/parse5": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", - "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.1.tgz", + "integrity": "sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==", "dependencies": { - "entities": "^4.4.0" + "entities": "^4.5.0" }, "funding": { "url": "https://github.com/inikulin/parse5?sponsor=1" } }, "node_modules/parse5-htmlparser2-tree-adapter": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz", - "integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz", + "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==", "dependencies": { - "domhandler": "^5.0.2", + "domhandler": "^5.0.3", "parse5": "^7.0.0" }, "funding": { @@ -12406,6 +13959,11 @@ "tslib": "^2.0.3" } }, + "node_modules/path-data-parser": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/path-data-parser/-/path-data-parser-0.1.0.tgz", + "integrity": "sha512-NOnmBpt5Y2RWbuv0LMzsayp3lVylAHLPUTut412ZA3l+C4uw4ZVkQbjShYCQ8TCpUMdPapr4YjUqLYD6v68j+w==" + }, "node_modules/path-exists": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", @@ -12441,9 +13999,9 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, "node_modules/path-to-regexp": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", - "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.9.0.tgz", + "integrity": "sha512-xIp7/apCFJuUHdDLWe8O1HIkb0kQrOMb/0u6FXQjemHn/ii5LrIzU6bdECnsiTF/GjZkMEKg1xdiZwNqDYlZ6g==", "dependencies": { "isarray": "0.0.1" } @@ -12456,15 +14014,10 @@ "node": ">=8" } }, - "node_modules/periscopic": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz", - "integrity": "sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==", - "dependencies": { - "@types/estree": "^1.0.0", - "estree-walker": "^3.0.0", - "is-reference": "^3.0.0" - } + "node_modules/pathe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==" }, "node_modules/picocolors": { "version": "1.1.1", @@ -12478,218 +14031,683 @@ "engines": { "node": ">=8.6" }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pkg-dir": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-7.0.0.tgz", + "integrity": "sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==", + "dependencies": { + "find-up": "^6.3.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-types": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.2.1.tgz", + "integrity": "sha512-sQoqa8alT3nHjGuTjuKgOnvjo4cljkufdtLMnO2LBP/wRwuDlo1tkaEdMxCRhyGRPacv/ztlZgDPm2b7FAmEvw==", + "dependencies": { + "confbox": "^0.1.8", + "mlly": "^1.7.2", + "pathe": "^1.1.2" + } + }, + "node_modules/pkg-up": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", + "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", + "dependencies": { + "find-up": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-up/node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-up/node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-up/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-up/node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-up/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/points-on-curve": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/points-on-curve/-/points-on-curve-0.2.0.tgz", + "integrity": "sha512-0mYKnYYe9ZcqMCWhUjItv/oHjvgEsfKvnUTg8sAtnHr3GVy7rGkXCb6d5cSyqrWqL4k81b9CPg3urd+T7aop3A==" + }, + "node_modules/points-on-path": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/points-on-path/-/points-on-path-0.2.1.tgz", + "integrity": "sha512-25ClnWWuw7JbWZcgqY/gJ4FQWadKxGWk+3kR/7kD0tCaDtPPMj7oHu2ToLaVhfpnHrZzYby2w6tUA0eOIuUg8g==", + "dependencies": { + "path-data-parser": "0.1.0", + "points-on-curve": "0.2.0" + } + }, + "node_modules/postcss": { + "version": "8.4.49", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz", + "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-attribute-case-insensitive": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-7.0.1.tgz", + "integrity": "sha512-Uai+SupNSqzlschRyNx3kbCTWgY/2hcwtHEI/ej2LJWc9JJ77qKgGptd8DHwY1mXtZ7Aoh4z4yxfwMBue9eNgw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-attribute-case-insensitive/node_modules/postcss-selector-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz", + "integrity": "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-calc": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-9.0.1.tgz", + "integrity": "sha512-TipgjGyzP5QzEhsOZUaIkeO5mKeMFpebWzRogWG/ysonUlnHcq5aJe0jOjpfzUU8PeSaBQnrE8ehR0QA5vs8PQ==", + "dependencies": { + "postcss-selector-parser": "^6.0.11", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.2.2" + } + }, + "node_modules/postcss-clamp": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/postcss-clamp/-/postcss-clamp-4.1.0.tgz", + "integrity": "sha512-ry4b1Llo/9zz+PKC+030KUnPITTJAHeOwjfAyyB60eT0AorGLdzp52s31OsPRHRf8NchkgFoG2y6fCfn1IV1Ow==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=7.6.0" + }, + "peerDependencies": { + "postcss": "^8.4.6" + } + }, + "node_modules/postcss-color-functional-notation": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/postcss-color-functional-notation/-/postcss-color-functional-notation-7.0.6.tgz", + "integrity": "sha512-wLXvm8RmLs14Z2nVpB4CWlnvaWPRcOZFltJSlcbYwSJ1EDZKsKDhPKIMecCnuU054KSmlmubkqczmm6qBPCBhA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "@csstools/css-color-parser": "^3.0.6", + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3", + "@csstools/postcss-progressive-custom-properties": "^4.0.0", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-color-hex-alpha": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/postcss-color-hex-alpha/-/postcss-color-hex-alpha-10.0.0.tgz", + "integrity": "sha512-1kervM2cnlgPs2a8Vt/Qbe5cQ++N7rkYo/2rz2BkqJZIHQwaVuJgQH38REHrAi4uM0b1fqxMkWYmese94iMp3w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "@csstools/utilities": "^2.0.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" } }, - "node_modules/pkg-dir": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-7.0.0.tgz", - "integrity": "sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==", + "node_modules/postcss-color-rebeccapurple": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-10.0.0.tgz", + "integrity": "sha512-JFta737jSP+hdAIEhk1Vs0q0YF5P8fFcj+09pweS8ktuGuZ8pPlykHsk6mPxZ8awDl4TrcxUqJo9l1IhVr/OjQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "dependencies": { - "find-up": "^6.3.0" + "@csstools/utilities": "^2.0.0", + "postcss-value-parser": "^4.2.0" }, "engines": { - "node": ">=14.16" + "node": ">=18" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "postcss": "^8.4" } }, - "node_modules/pkg-up": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", - "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", + "node_modules/postcss-colormin": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-6.1.0.tgz", + "integrity": "sha512-x9yX7DOxeMAR+BgGVnNSAxmAj98NX/YxEMNFP+SDCEeNLb2r3i6Hh1ksMsnW8Ub5SLCpbescQqn9YEbE9554Sw==", "dependencies": { - "find-up": "^3.0.0" + "browserslist": "^4.23.0", + "caniuse-api": "^3.0.0", + "colord": "^2.9.3", + "postcss-value-parser": "^4.2.0" }, "engines": { - "node": ">=8" + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" } }, - "node_modules/pkg-up/node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "node_modules/postcss-convert-values": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-6.1.0.tgz", + "integrity": "sha512-zx8IwP/ts9WvUM6NkVSkiU902QZL1bwPhaVaLynPtCsOTqp+ZKbNi+s6XJg3rfqpKGA/oc7Oxk5t8pOQJcwl/w==", "dependencies": { - "locate-path": "^3.0.0" + "browserslist": "^4.23.0", + "postcss-value-parser": "^4.2.0" }, "engines": { - "node": ">=6" + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" } }, - "node_modules/pkg-up/node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "node_modules/postcss-custom-media": { + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-11.0.5.tgz", + "integrity": "sha512-SQHhayVNgDvSAdX9NQ/ygcDQGEY+aSF4b/96z7QUX6mqL5yl/JgG/DywcF6fW9XbnCRE+aVYk+9/nqGuzOPWeQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" + "@csstools/cascade-layer-name-parser": "^2.0.4", + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3", + "@csstools/media-query-list-parser": "^4.0.2" }, "engines": { - "node": ">=6" + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" } }, - "node_modules/pkg-up/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "node_modules/postcss-custom-properties": { + "version": "14.0.4", + "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-14.0.4.tgz", + "integrity": "sha512-QnW8FCCK6q+4ierwjnmXF9Y9KF8q0JkbgVfvQEMa93x1GT8FvOiUevWCN2YLaOWyByeDX8S6VFbZEeWoAoXs2A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "dependencies": { - "p-try": "^2.0.0" + "@csstools/cascade-layer-name-parser": "^2.0.4", + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3", + "@csstools/utilities": "^2.0.0", + "postcss-value-parser": "^4.2.0" }, "engines": { - "node": ">=6" + "node": ">=18" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "postcss": "^8.4" } }, - "node_modules/pkg-up/node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "node_modules/postcss-custom-selectors": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/postcss-custom-selectors/-/postcss-custom-selectors-8.0.4.tgz", + "integrity": "sha512-ASOXqNvDCE0dAJ/5qixxPeL1aOVGHGW2JwSy7HyjWNbnWTQCl+fDc968HY1jCmZI0+BaYT5CxsOiUhavpG/7eg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "dependencies": { - "p-limit": "^2.0.0" + "@csstools/cascade-layer-name-parser": "^2.0.4", + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3", + "postcss-selector-parser": "^7.0.0" }, "engines": { - "node": ">=6" + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" } }, - "node_modules/pkg-up/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "node_modules/postcss-custom-selectors/node_modules/postcss-selector-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz", + "integrity": "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, "engines": { "node": ">=4" } }, - "node_modules/postcss": { - "version": "8.4.33", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.33.tgz", - "integrity": "sha512-Kkpbhhdjw2qQs2O2DGX+8m5OVqEcbB9HRBvuYM9pgrjEFUg30A9LmXNlTAUj4S9kgtGyrMbTzVjH7E+s5Re2yg==", + "node_modules/postcss-dir-pseudo-class": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-9.0.1.tgz", + "integrity": "sha512-tRBEK0MHYvcMUrAuYMEOa0zg9APqirBcgzi6P21OhxtJyJADo/SWBwY1CAwEohQ/6HDaa9jCjLRG7K3PVQYHEA==", "funding": [ { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" + "type": "github", + "url": "https://github.com/sponsors/csstools" }, { - "type": "github", - "url": "https://github.com/sponsors/ai" + "type": "opencollective", + "url": "https://opencollective.com/csstools" } ], "dependencies": { - "nanoid": "^3.3.7", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" + "postcss-selector-parser": "^7.0.0" }, "engines": { - "node": "^10 || ^12 || >=14" + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" } }, - "node_modules/postcss-calc": { - "version": "8.2.4", - "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-8.2.4.tgz", - "integrity": "sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q==", + "node_modules/postcss-dir-pseudo-class/node_modules/postcss-selector-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz", + "integrity": "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==", "dependencies": { - "postcss-selector-parser": "^6.0.9", - "postcss-value-parser": "^4.2.0" + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-discard-comments": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-6.0.2.tgz", + "integrity": "sha512-65w/uIqhSBBfQmYnG92FO1mWZjJ4GL5b8atm5Yw2UgrwD7HiNiSSNwJor1eCFGzUgYnN/iIknhNRVqjrrpuglw==", + "engines": { + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.2" + "postcss": "^8.4.31" } }, - "node_modules/postcss-colormin": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.3.1.tgz", - "integrity": "sha512-UsWQG0AqTFQmpBegeLLc1+c3jIqBNB0zlDGRWR+dQ3pRKJL1oeMzyqmH3o2PIfn9MBdNrVPWhDbT769LxCTLJQ==", + "node_modules/postcss-discard-duplicates": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-6.0.3.tgz", + "integrity": "sha512-+JA0DCvc5XvFAxwx6f/e68gQu/7Z9ud584VLmcgto28eB8FqSFZwtrLwB5Kcp70eIoWP/HXqz4wpo8rD8gpsTw==", + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-discard-empty": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-6.0.3.tgz", + "integrity": "sha512-znyno9cHKQsK6PtxL5D19Fj9uwSzC2mB74cpT66fhgOadEUPyXFkbgwm5tvc3bt3NAy8ltE5MrghxovZRVnOjQ==", + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-discard-overridden": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-6.0.2.tgz", + "integrity": "sha512-j87xzI4LUggC5zND7KdjsI25APtyMuynXZSujByMaav2roV6OZX+8AaCUcZSWqckZpjAjRyFDdpqybgjFO0HJQ==", + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-discard-unused": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-6.0.5.tgz", + "integrity": "sha512-wHalBlRHkaNnNwfC8z+ppX57VhvS+HWgjW508esjdaEYr3Mx7Gnn2xA4R/CKf5+Z9S5qsqC+Uzh4ueENWwCVUA==", "dependencies": { - "browserslist": "^4.21.4", - "caniuse-api": "^3.0.0", - "colord": "^2.9.1", - "postcss-value-parser": "^4.2.0" + "postcss-selector-parser": "^6.0.16" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, - "node_modules/postcss-convert-values": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.1.3.tgz", - "integrity": "sha512-82pC1xkJZtcJEfiLw6UXnXVXScgtBrjlO5CBmuDQc+dlb88ZYheFsjTn40+zBVi3DkfF7iezO0nJUPLcJK3pvA==", + "node_modules/postcss-double-position-gradients": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-double-position-gradients/-/postcss-double-position-gradients-6.0.0.tgz", + "integrity": "sha512-JkIGah3RVbdSEIrcobqj4Gzq0h53GG4uqDPsho88SgY84WnpkTpI0k50MFK/sX7XqVisZ6OqUfFnoUO6m1WWdg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "dependencies": { - "browserslist": "^4.21.4", + "@csstools/postcss-progressive-custom-properties": "^4.0.0", + "@csstools/utilities": "^2.0.0", "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": ">=18" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4" } }, - "node_modules/postcss-discard-comments": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.1.2.tgz", - "integrity": "sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==", + "node_modules/postcss-focus-visible": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/postcss-focus-visible/-/postcss-focus-visible-10.0.1.tgz", + "integrity": "sha512-U58wyjS/I1GZgjRok33aE8juW9qQgQUNwTSdxQGuShHzwuYdcklnvK/+qOWX1Q9kr7ysbraQ6ht6r+udansalA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": ">=18" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4" } }, - "node_modules/postcss-discard-duplicates": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz", - "integrity": "sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==", + "node_modules/postcss-focus-visible/node_modules/postcss-selector-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz", + "integrity": "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-focus-within": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/postcss-focus-within/-/postcss-focus-within-9.0.1.tgz", + "integrity": "sha512-fzNUyS1yOYa7mOjpci/bR+u+ESvdar6hk8XNK/TRR0fiGTp2QT5N+ducP0n3rfH/m9I7H/EQU6lsa2BrgxkEjw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": ">=18" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4" } }, - "node_modules/postcss-discard-empty": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz", - "integrity": "sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==", + "node_modules/postcss-focus-within/node_modules/postcss-selector-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz", + "integrity": "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-font-variant": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-font-variant/-/postcss-font-variant-5.0.0.tgz", + "integrity": "sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA==", + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-gap-properties": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-6.0.0.tgz", + "integrity": "sha512-Om0WPjEwiM9Ru+VhfEDPZJAKWUd0mV1HmNXqp2C29z80aQ2uP9UVhLc7e3aYMIor/S5cVhoPgYQ7RtfeZpYTRw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "engines": { - "node": "^10 || ^12 || >=14.0" + "node": ">=18" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4" } }, - "node_modules/postcss-discard-overridden": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz", - "integrity": "sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==", + "node_modules/postcss-image-set-function": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-image-set-function/-/postcss-image-set-function-7.0.0.tgz", + "integrity": "sha512-QL7W7QNlZuzOwBTeXEmbVckNt1FSmhQtbMRvGGqqU4Nf4xk6KUEQhAoWuMzwbSv5jxiRiSZ5Tv7eiDB9U87znA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "@csstools/utilities": "^2.0.0", + "postcss-value-parser": "^4.2.0" + }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": ">=18" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4" } }, - "node_modules/postcss-discard-unused": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-5.1.0.tgz", - "integrity": "sha512-KwLWymI9hbwXmJa0dkrzpRbSJEh0vVUd7r8t0yOGPcfKzyJJxFM8kLyC5Ev9avji6nY95pOp1W6HqIrfT+0VGw==", + "node_modules/postcss-lab-function": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-7.0.6.tgz", + "integrity": "sha512-HPwvsoK7C949vBZ+eMyvH2cQeMr3UREoHvbtra76/UhDuiViZH6pir+z71UaJQohd7VDSVUdR6TkWYKExEc9aQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "dependencies": { - "postcss-selector-parser": "^6.0.5" + "@csstools/css-color-parser": "^3.0.6", + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3", + "@csstools/postcss-progressive-custom-properties": "^4.0.0", + "@csstools/utilities": "^2.0.0" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": ">=18" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4" } }, "node_modules/postcss-loader": { @@ -12713,142 +14731,141 @@ "webpack": "^5.0.0" } }, - "node_modules/postcss-loader/node_modules/cosmiconfig": { - "version": "8.3.6", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", - "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", + "node_modules/postcss-logical": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-8.0.0.tgz", + "integrity": "sha512-HpIdsdieClTjXLOyYdUPAX/XQASNIwdKt5hoZW08ZOAiI+tbV0ta1oclkpVkW5ANU+xJvk3KkA0FejkjGLXUkg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "dependencies": { - "import-fresh": "^3.3.0", - "js-yaml": "^4.1.0", - "parse-json": "^5.2.0", - "path-type": "^4.0.0" + "postcss-value-parser": "^4.2.0" }, "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/d-fischer" + "node": ">=18" }, "peerDependencies": { - "typescript": ">=4.9.5" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "postcss": "^8.4" } }, "node_modules/postcss-merge-idents": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-merge-idents/-/postcss-merge-idents-5.1.1.tgz", - "integrity": "sha512-pCijL1TREiCoog5nQp7wUe+TUonA2tC2sQ54UGeMmryK3UFGIYKqDyjnqd6RcuI4znFn9hWSLNN8xKE/vWcUQw==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-merge-idents/-/postcss-merge-idents-6.0.3.tgz", + "integrity": "sha512-1oIoAsODUs6IHQZkLQGO15uGEbK3EAl5wi9SS8hs45VgsxQfMnxvt+L+zIr7ifZFIH14cfAeVe2uCTa+SPRa3g==", "dependencies": { - "cssnano-utils": "^3.1.0", + "cssnano-utils": "^4.0.2", "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-merge-longhand": { - "version": "5.1.7", - "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-5.1.7.tgz", - "integrity": "sha512-YCI9gZB+PLNskrK0BB3/2OzPnGhPkBEwmwhfYk1ilBHYVAZB7/tkTHFBAnCrvBBOmeYyMYw3DMjT55SyxMBzjQ==", + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-6.0.5.tgz", + "integrity": "sha512-5LOiordeTfi64QhICp07nzzuTDjNSO8g5Ksdibt44d+uvIIAE1oZdRn8y/W5ZtYgRH/lnLDlvi9F8btZcVzu3w==", "dependencies": { "postcss-value-parser": "^4.2.0", - "stylehacks": "^5.1.1" + "stylehacks": "^6.1.1" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-merge-rules": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.1.4.tgz", - "integrity": "sha512-0R2IuYpgU93y9lhVbO/OylTtKMVcHb67zjWIfCiKR9rWL3GUk1677LAqD/BcHizukdZEjT8Ru3oHRoAYoJy44g==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-6.1.1.tgz", + "integrity": "sha512-KOdWF0gju31AQPZiD+2Ar9Qjowz1LTChSjFFbS+e2sFgc4uHOp3ZvVX4sNeTlk0w2O31ecFGgrFzhO0RSWbWwQ==", "dependencies": { - "browserslist": "^4.21.4", + "browserslist": "^4.23.0", "caniuse-api": "^3.0.0", - "cssnano-utils": "^3.1.0", - "postcss-selector-parser": "^6.0.5" + "cssnano-utils": "^4.0.2", + "postcss-selector-parser": "^6.0.16" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-minify-font-values": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-5.1.0.tgz", - "integrity": "sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-6.1.0.tgz", + "integrity": "sha512-gklfI/n+9rTh8nYaSJXlCo3nOKqMNkxuGpTn/Qm0gstL3ywTr9/WRKznE+oy6fvfolH6dF+QM4nCo8yPLdvGJg==", "dependencies": { "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-minify-gradients": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-5.1.1.tgz", - "integrity": "sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-6.0.3.tgz", + "integrity": "sha512-4KXAHrYlzF0Rr7uc4VrfwDJ2ajrtNEpNEuLxFgwkhFZ56/7gaE4Nr49nLsQDZyUe+ds+kEhf+YAUolJiYXF8+Q==", "dependencies": { - "colord": "^2.9.1", - "cssnano-utils": "^3.1.0", + "colord": "^2.9.3", + "cssnano-utils": "^4.0.2", "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-minify-params": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-5.1.4.tgz", - "integrity": "sha512-+mePA3MgdmVmv6g+30rn57USjOGSAyuxUmkfiWpzalZ8aiBkdPYjXWtHuwJGm1v5Ojy0Z0LaSYhHaLJQB0P8Jw==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-6.1.0.tgz", + "integrity": "sha512-bmSKnDtyyE8ujHQK0RQJDIKhQ20Jq1LYiez54WiaOoBtcSuflfK3Nm596LvbtlFcpipMjgClQGyGr7GAs+H1uA==", "dependencies": { - "browserslist": "^4.21.4", - "cssnano-utils": "^3.1.0", + "browserslist": "^4.23.0", + "cssnano-utils": "^4.0.2", "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-minify-selectors": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-5.2.1.tgz", - "integrity": "sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg==", + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-6.0.4.tgz", + "integrity": "sha512-L8dZSwNLgK7pjTto9PzWRoMbnLq5vsZSTu8+j1P/2GB8qdtGQfn+K1uSvFgYvgh83cbyxT5m43ZZhUMTJDSClQ==", "dependencies": { - "postcss-selector-parser": "^6.0.5" + "postcss-selector-parser": "^6.0.16" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-modules-extract-imports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", - "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz", + "integrity": "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==", "engines": { "node": "^10 || ^12 || >= 14" }, @@ -12857,12 +14874,12 @@ } }, "node_modules/postcss-modules-local-by-default": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.4.tgz", - "integrity": "sha512-L4QzMnOdVwRm1Qb8m4x8jsZzKAaPAgrUF1r/hjDR2Xj7R+8Zsf97jAlSQzWtKx5YNiNGN8QxmPFIc/sh+RQl+Q==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.2.0.tgz", + "integrity": "sha512-5kcJm/zk+GJDSfw+V/42fJ5fhjL5YbFDl8nVdXkJPLLW+Vf9mTD5Xe0wqIaDnLuL2U6cDNpTr+UQ+v2HWIBhzw==", "dependencies": { "icss-utils": "^5.0.0", - "postcss-selector-parser": "^6.0.2", + "postcss-selector-parser": "^7.0.0", "postcss-value-parser": "^4.1.0" }, "engines": { @@ -12872,12 +14889,24 @@ "postcss": "^8.1.0" } }, + "node_modules/postcss-modules-local-by-default/node_modules/postcss-selector-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz", + "integrity": "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/postcss-modules-scope": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.1.0.tgz", - "integrity": "sha512-SaIbK8XW+MZbd0xHPf7kdfA/3eOt7vxJ72IRecn3EzuZVLr1r0orzf0MX/pN8m+NMDoo6X/SQd8oeKqGZd8PXg==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.1.tgz", + "integrity": "sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA==", "dependencies": { - "postcss-selector-parser": "^6.0.4" + "postcss-selector-parser": "^7.0.0" }, "engines": { "node": "^10 || ^12 || >= 14" @@ -12886,6 +14915,18 @@ "postcss": "^8.1.0" } }, + "node_modules/postcss-modules-scope/node_modules/postcss-selector-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz", + "integrity": "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/postcss-modules-values": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", @@ -12900,193 +14941,515 @@ "postcss": "^8.1.0" } }, + "node_modules/postcss-nesting": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-13.0.1.tgz", + "integrity": "sha512-VbqqHkOBOt4Uu3G8Dm8n6lU5+9cJFxiuty9+4rcoyRPO9zZS1JIs6td49VIoix3qYqELHlJIn46Oih9SAKo+yQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "@csstools/selector-resolve-nested": "^3.0.0", + "@csstools/selector-specificity": "^5.0.0", + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-nesting/node_modules/@csstools/selector-resolve-nested": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-resolve-nested/-/selector-resolve-nested-3.0.0.tgz", + "integrity": "sha512-ZoK24Yku6VJU1gS79a5PFmC8yn3wIapiKmPgun0hZgEI5AOqgH2kiPRsPz1qkGv4HL+wuDLH83yQyk6inMYrJQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss-selector-parser": "^7.0.0" + } + }, + "node_modules/postcss-nesting/node_modules/@csstools/selector-specificity": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-5.0.0.tgz", + "integrity": "sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss-selector-parser": "^7.0.0" + } + }, + "node_modules/postcss-nesting/node_modules/postcss-selector-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz", + "integrity": "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/postcss-normalize-charset": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz", - "integrity": "sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-6.0.2.tgz", + "integrity": "sha512-a8N9czmdnrjPHa3DeFlwqst5eaL5W8jYu3EBbTTkI5FHkfMhFZh1EGbku6jhHhIzTA6tquI2P42NtZ59M/H/kQ==", "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-normalize-display-values": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-5.1.0.tgz", - "integrity": "sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-6.0.2.tgz", + "integrity": "sha512-8H04Mxsb82ON/aAkPeq8kcBbAtI5Q2a64X/mnRRfPXBq7XeogoQvReqxEfc0B4WPq1KimjezNC8flUtC3Qz6jg==", "dependencies": { "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-normalize-positions": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-5.1.1.tgz", - "integrity": "sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-6.0.2.tgz", + "integrity": "sha512-/JFzI441OAB9O7VnLA+RtSNZvQ0NCFZDOtp6QPFo1iIyawyXg0YI3CYM9HBy1WvwCRHnPep/BvI1+dGPKoXx/Q==", "dependencies": { "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-normalize-repeat-style": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.1.1.tgz", - "integrity": "sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-6.0.2.tgz", + "integrity": "sha512-YdCgsfHkJ2jEXwR4RR3Tm/iOxSfdRt7jplS6XRh9Js9PyCR/aka/FCb6TuHT2U8gQubbm/mPmF6L7FY9d79VwQ==", "dependencies": { "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-normalize-string": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-5.1.0.tgz", - "integrity": "sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-6.0.2.tgz", + "integrity": "sha512-vQZIivlxlfqqMp4L9PZsFE4YUkWniziKjQWUtsxUiVsSSPelQydwS8Wwcuw0+83ZjPWNTl02oxlIvXsmmG+CiQ==", "dependencies": { "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-normalize-timing-functions": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.1.0.tgz", - "integrity": "sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-6.0.2.tgz", + "integrity": "sha512-a+YrtMox4TBtId/AEwbA03VcJgtyW4dGBizPl7e88cTFULYsprgHWTbfyjSLyHeBcK/Q9JhXkt2ZXiwaVHoMzA==", "dependencies": { "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-normalize-unicode": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.1.tgz", - "integrity": "sha512-qnCL5jzkNUmKVhZoENp1mJiGNPcsJCs1aaRmURmeJGES23Z/ajaln+EPTD+rBeNkSryI+2WTdW+lwcVdOikrpA==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-6.1.0.tgz", + "integrity": "sha512-QVC5TQHsVj33otj8/JD869Ndr5Xcc/+fwRh4HAsFsAeygQQXm+0PySrKbr/8tkDKzW+EVT3QkqZMfFrGiossDg==", + "dependencies": { + "browserslist": "^4.23.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-url": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-6.0.2.tgz", + "integrity": "sha512-kVNcWhCeKAzZ8B4pv/DnrU1wNh458zBNp8dh4y5hhxih5RZQ12QWMuQrDgPRw3LRl8mN9vOVfHl7uhvHYMoXsQ==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-whitespace": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-6.0.2.tgz", + "integrity": "sha512-sXZ2Nj1icbJOKmdjXVT9pnyHQKiSAyuNQHSgRCUgThn2388Y9cGVDR+E9J9iAYbSbLHI+UUwLVl1Wzco/zgv0Q==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-opacity-percentage": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-opacity-percentage/-/postcss-opacity-percentage-3.0.0.tgz", + "integrity": "sha512-K6HGVzyxUxd/VgZdX04DCtdwWJ4NGLG212US4/LA1TLAbHgmAsTWVR86o+gGIbFtnTkfOpb9sCRBx8K7HO66qQ==", + "funding": [ + { + "type": "kofi", + "url": "https://ko-fi.com/mrcgrtz" + }, + { + "type": "liberapay", + "url": "https://liberapay.com/mrcgrtz" + } + ], + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-ordered-values": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-6.0.2.tgz", + "integrity": "sha512-VRZSOB+JU32RsEAQrO94QPkClGPKJEL/Z9PCBImXMhIeK5KAYo6slP/hBYlLgrCjFxyqvn5VC81tycFEDBLG1Q==", + "dependencies": { + "cssnano-utils": "^4.0.2", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-overflow-shorthand": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-overflow-shorthand/-/postcss-overflow-shorthand-6.0.0.tgz", + "integrity": "sha512-BdDl/AbVkDjoTofzDQnwDdm/Ym6oS9KgmO7Gr+LHYjNWJ6ExORe4+3pcLQsLA9gIROMkiGVjjwZNoL/mpXHd5Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-page-break": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/postcss-page-break/-/postcss-page-break-3.0.4.tgz", + "integrity": "sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ==", + "peerDependencies": { + "postcss": "^8" + } + }, + "node_modules/postcss-place": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/postcss-place/-/postcss-place-10.0.0.tgz", + "integrity": "sha512-5EBrMzat2pPAxQNWYavwAfoKfYcTADJ8AXGVPcUZ2UkNloUTWzJQExgrzrDkh3EKzmAx1evfTAzF9I8NGcc+qw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "dependencies": { - "browserslist": "^4.21.4", "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-preset-env": { + "version": "10.1.2", + "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-10.1.2.tgz", + "integrity": "sha512-OqUBZ9ByVfngWhMNuBEMy52Izj07oIFA6K/EOGBlaSv+P12MiE1+S2cqXtS1VuW82demQ/Tzc7typYk3uHunkA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "@csstools/postcss-cascade-layers": "^5.0.1", + "@csstools/postcss-color-function": "^4.0.6", + "@csstools/postcss-color-mix-function": "^3.0.6", + "@csstools/postcss-content-alt-text": "^2.0.4", + "@csstools/postcss-exponential-functions": "^2.0.5", + "@csstools/postcss-font-format-keywords": "^4.0.0", + "@csstools/postcss-gamut-mapping": "^2.0.6", + "@csstools/postcss-gradients-interpolation-method": "^5.0.6", + "@csstools/postcss-hwb-function": "^4.0.6", + "@csstools/postcss-ic-unit": "^4.0.0", + "@csstools/postcss-initial": "^2.0.0", + "@csstools/postcss-is-pseudo-class": "^5.0.1", + "@csstools/postcss-light-dark-function": "^2.0.7", + "@csstools/postcss-logical-float-and-clear": "^3.0.0", + "@csstools/postcss-logical-overflow": "^2.0.0", + "@csstools/postcss-logical-overscroll-behavior": "^2.0.0", + "@csstools/postcss-logical-resize": "^3.0.0", + "@csstools/postcss-logical-viewport-units": "^3.0.3", + "@csstools/postcss-media-minmax": "^2.0.5", + "@csstools/postcss-media-queries-aspect-ratio-number-values": "^3.0.4", + "@csstools/postcss-nested-calc": "^4.0.0", + "@csstools/postcss-normalize-display-values": "^4.0.0", + "@csstools/postcss-oklab-function": "^4.0.6", + "@csstools/postcss-progressive-custom-properties": "^4.0.0", + "@csstools/postcss-random-function": "^1.0.1", + "@csstools/postcss-relative-color-syntax": "^3.0.6", + "@csstools/postcss-scope-pseudo-class": "^4.0.1", + "@csstools/postcss-sign-functions": "^1.1.0", + "@csstools/postcss-stepped-value-functions": "^4.0.5", + "@csstools/postcss-text-decoration-shorthand": "^4.0.1", + "@csstools/postcss-trigonometric-functions": "^4.0.5", + "@csstools/postcss-unset-value": "^4.0.0", + "autoprefixer": "^10.4.19", + "browserslist": "^4.23.1", + "css-blank-pseudo": "^7.0.1", + "css-has-pseudo": "^7.0.2", + "css-prefers-color-scheme": "^10.0.0", + "cssdb": "^8.2.3", + "postcss-attribute-case-insensitive": "^7.0.1", + "postcss-clamp": "^4.1.0", + "postcss-color-functional-notation": "^7.0.6", + "postcss-color-hex-alpha": "^10.0.0", + "postcss-color-rebeccapurple": "^10.0.0", + "postcss-custom-media": "^11.0.5", + "postcss-custom-properties": "^14.0.4", + "postcss-custom-selectors": "^8.0.4", + "postcss-dir-pseudo-class": "^9.0.1", + "postcss-double-position-gradients": "^6.0.0", + "postcss-focus-visible": "^10.0.1", + "postcss-focus-within": "^9.0.1", + "postcss-font-variant": "^5.0.0", + "postcss-gap-properties": "^6.0.0", + "postcss-image-set-function": "^7.0.0", + "postcss-lab-function": "^7.0.6", + "postcss-logical": "^8.0.0", + "postcss-nesting": "^13.0.1", + "postcss-opacity-percentage": "^3.0.0", + "postcss-overflow-shorthand": "^6.0.0", + "postcss-page-break": "^3.0.4", + "postcss-place": "^10.0.0", + "postcss-pseudo-class-any-link": "^10.0.1", + "postcss-replace-overflow-wrap": "^4.0.0", + "postcss-selector-not": "^8.0.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-pseudo-class-any-link": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-10.0.1.tgz", + "integrity": "sha512-3el9rXlBOqTFaMFkWDOkHUTQekFIYnaQY55Rsp8As8QQkpiSgIYEcF/6Ond93oHiDsGb4kad8zjt+NPlOC1H0Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4" } }, - "node_modules/postcss-normalize-url": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-5.1.0.tgz", - "integrity": "sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew==", + "node_modules/postcss-pseudo-class-any-link/node_modules/postcss-selector-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz", + "integrity": "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==", "dependencies": { - "normalize-url": "^6.0.1", - "postcss-value-parser": "^4.2.0" + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" }, "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" + "node": ">=4" } }, - "node_modules/postcss-normalize-whitespace": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.1.1.tgz", - "integrity": "sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA==", + "node_modules/postcss-reduce-idents": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-reduce-idents/-/postcss-reduce-idents-6.0.3.tgz", + "integrity": "sha512-G3yCqZDpsNPoQgbDUy3T0E6hqOQ5xigUtBQyrmq3tn2GxlyiL0yyl7H+T8ulQR6kOcHJ9t7/9H4/R2tv8tJbMA==", "dependencies": { "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, - "node_modules/postcss-ordered-values": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-5.1.3.tgz", - "integrity": "sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ==", + "node_modules/postcss-reduce-initial": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-6.1.0.tgz", + "integrity": "sha512-RarLgBK/CrL1qZags04oKbVbrrVK2wcxhvta3GCxrZO4zveibqbRPmm2VI8sSgCXwoUHEliRSbOfpR0b/VIoiw==", "dependencies": { - "cssnano-utils": "^3.1.0", - "postcss-value-parser": "^4.2.0" + "browserslist": "^4.23.0", + "caniuse-api": "^3.0.0" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, - "node_modules/postcss-reduce-idents": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/postcss-reduce-idents/-/postcss-reduce-idents-5.2.0.tgz", - "integrity": "sha512-BTrLjICoSB6gxbc58D5mdBK8OhXRDqud/zodYfdSi52qvDHdMwk+9kB9xsM8yJThH/sZU5A6QVSmMmaN001gIg==", + "node_modules/postcss-reduce-transforms": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-6.0.2.tgz", + "integrity": "sha512-sB+Ya++3Xj1WaT9+5LOOdirAxP7dJZms3GRcYheSPi1PiTMigsxHAdkrbItHxwYHr4kt1zL7mmcHstgMYT+aiA==", "dependencies": { "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, - "node_modules/postcss-reduce-initial": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.1.2.tgz", - "integrity": "sha512-dE/y2XRaqAi6OvjzD22pjTUQ8eOfc6m/natGHgKFBK9DxFmIm69YmaRVQrGgFlEfc1HePIurY0TmDeROK05rIg==", + "node_modules/postcss-replace-overflow-wrap": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-4.0.0.tgz", + "integrity": "sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw==", + "peerDependencies": { + "postcss": "^8.0.3" + } + }, + "node_modules/postcss-selector-not": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/postcss-selector-not/-/postcss-selector-not-8.0.1.tgz", + "integrity": "sha512-kmVy/5PYVb2UOhy0+LqUYAhKj7DUGDpSWa5LZqlkWJaaAV+dxxsOG3+St0yNLu6vsKD7Dmqx+nWQt0iil89+WA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "dependencies": { - "browserslist": "^4.21.4", - "caniuse-api": "^3.0.0" + "postcss-selector-parser": "^7.0.0" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": ">=18" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4" } }, - "node_modules/postcss-reduce-transforms": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-5.1.0.tgz", - "integrity": "sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ==", + "node_modules/postcss-selector-not/node_modules/postcss-selector-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz", + "integrity": "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==", "dependencies": { - "postcss-value-parser": "^4.2.0" + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" }, "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" + "node": ">=4" } }, "node_modules/postcss-selector-parser": { - "version": "6.0.15", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.15.tgz", - "integrity": "sha512-rEYkQOMUCEMhsKbK66tbEU9QVIxbhN18YiniAwA7XQYTVBqrBy+P2p5JcdqsHgKM2zWylp8d7J6eszocfds5Sw==", + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -13096,46 +15459,46 @@ } }, "node_modules/postcss-sort-media-queries": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/postcss-sort-media-queries/-/postcss-sort-media-queries-4.4.1.tgz", - "integrity": "sha512-QDESFzDDGKgpiIh4GYXsSy6sek2yAwQx1JASl5AxBtU1Lq2JfKBljIPNdil989NcSKRQX1ToiaKphImtBuhXWw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/postcss-sort-media-queries/-/postcss-sort-media-queries-5.2.0.tgz", + "integrity": "sha512-AZ5fDMLD8SldlAYlvi8NIqo0+Z8xnXU2ia0jxmuhxAU+Lqt9K+AlmLNJ/zWEnE9x+Zx3qL3+1K20ATgNOr3fAA==", "dependencies": { - "sort-css-media-queries": "2.1.0" + "sort-css-media-queries": "2.2.0" }, "engines": { - "node": ">=10.0.0" + "node": ">=14.0.0" }, "peerDependencies": { - "postcss": "^8.4.16" + "postcss": "^8.4.23" } }, "node_modules/postcss-svgo": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-5.1.0.tgz", - "integrity": "sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-6.0.3.tgz", + "integrity": "sha512-dlrahRmxP22bX6iKEjOM+c8/1p+81asjKT+V5lrgOH944ryx/OHpclnIbGsKVd3uWOXFLYJwCVf0eEkJGvO96g==", "dependencies": { "postcss-value-parser": "^4.2.0", - "svgo": "^2.7.0" + "svgo": "^3.2.0" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >= 18" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-unique-selectors": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-5.1.1.tgz", - "integrity": "sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA==", + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-6.0.4.tgz", + "integrity": "sha512-K38OCaIrO8+PzpArzkLKB42dSARtC2tmG6PvD4b1o1Q2E9Os8jzfWFfSy/rixsHwohtsDdFtAWGjFVFUdwYaMg==", "dependencies": { - "postcss-selector-parser": "^6.0.5" + "postcss-selector-parser": "^6.0.16" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-value-parser": { @@ -13144,14 +15507,14 @@ "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" }, "node_modules/postcss-zindex": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-zindex/-/postcss-zindex-5.1.0.tgz", - "integrity": "sha512-fgFMf0OtVSBR1va1JNHYgMxYk73yhn/qb4uQDq1DLGYolz8gHCyr/sesEuGUaYs58E3ZJRcpoGuPVoB7Meiq9A==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-zindex/-/postcss-zindex-6.0.2.tgz", + "integrity": "sha512-5BxW9l1evPB/4ZIc+2GobEBoKC+h8gPGCMi+jxsYvd2x0mjq7wazk6DrP71pStqxE9Foxh5TVnonbWpFZzXaYg==", "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/pretty-error": { @@ -13172,9 +15535,9 @@ } }, "node_modules/prism-react-renderer": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/prism-react-renderer/-/prism-react-renderer-2.3.1.tgz", - "integrity": "sha512-Rdf+HzBLR7KYjzpJ1rSoxT9ioO85nZngQEoFIhL07XhtJHlCU3SOz0GJ6+qvMyQe0Se+BV3qpe6Yd/NmQF5Juw==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/prism-react-renderer/-/prism-react-renderer-2.4.1.tgz", + "integrity": "sha512-ey8Ls/+Di31eqzUxC46h8MksNuGx/n0AAC8uKpwFau4RPDYLuE3EXTp8N8G2vX2N7UC/+IXeNUnlWBGGcAG+Ig==", "dependencies": { "@types/prismjs": "^1.26.0", "clsx": "^2.0.0" @@ -13219,9 +15582,12 @@ } }, "node_modules/property-information": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.4.1.tgz", - "integrity": "sha512-OHYtXfu5aI2sS2LWFSN5rgJjrQ4pCy8i1jubJLe2QvMF8JJ++HXTUIVWFLfXJoaOfvYYjk2SN8J2wFUWIGXT4w==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-5.6.0.tgz", + "integrity": "sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==", + "dependencies": { + "xtend": "^4.0.0" + }, "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -13253,9 +15619,12 @@ } }, "node_modules/punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==" + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "engines": { + "node": ">=6" + } }, "node_modules/pupa": { "version": "3.1.0", @@ -13361,6 +15730,17 @@ "node": ">= 0.8" } }, + "node_modules/raw-body/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/rc": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", @@ -13384,9 +15764,9 @@ } }, "node_modules/react": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", - "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", "dependencies": { "loose-envify": "^1.1.0" }, @@ -13444,9 +15824,9 @@ } }, "node_modules/react-dev-utils/node_modules/loader-utils": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.1.tgz", - "integrity": "sha512-ZvFw1KWS3GVyYBYb7qkmRM/WwL2TQQBxgCK62rlvm4WpVQ23Nb4tYjApUlfjrEGvOs7KHEsmyUn75OHZrJMWPw==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.3.1.tgz", + "integrity": "sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg==", "engines": { "node": ">= 12.13.0" } @@ -13513,15 +15893,15 @@ } }, "node_modules/react-dom": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", - "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", "dependencies": { "loose-envify": "^1.1.0", - "scheduler": "^0.23.0" + "scheduler": "^0.23.2" }, "peerDependencies": { - "react": "^18.2.0" + "react": "^18.3.1" } }, "node_modules/react-error-overlay": { @@ -13556,9 +15936,9 @@ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, "node_modules/react-json-view-lite": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/react-json-view-lite/-/react-json-view-lite-1.2.1.tgz", - "integrity": "sha512-Itc0g86fytOmKZoIoJyGgvNqohWSbh3NXIKNgH6W6FT9PC1ck4xas1tT3Rr/b3UlFXyA9Jjaw9QSXdZy2JwGMQ==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/react-json-view-lite/-/react-json-view-lite-1.5.0.tgz", + "integrity": "sha512-nWqA1E4jKPklL2jvHWs6s+7Na0qNgw9HCP6xehdQJeg6nPBTFZgGwyko9Q0oj+jQWKTTVRS30u0toM5wiuL3iw==", "engines": { "node": ">=14" }, @@ -13568,12 +15948,11 @@ }, "node_modules/react-loadable": { "name": "@docusaurus/react-loadable", - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/react-loadable/-/react-loadable-5.5.2.tgz", - "integrity": "sha512-A3dYjdBGuy0IGT+wyLIGIKLRE+sAk1iNk0f1HjNDysO7u8lhL4N3VEm+FAubmJbAztn94F7MxBTPmnixbiyFdQ==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@docusaurus/react-loadable/-/react-loadable-6.0.0.tgz", + "integrity": "sha512-YMMxTUQV/QFSnbgrP3tjDzLHRg7vsbMn8e9HAa8o/1iXoiomo48b7sk/kkmWEuWNDPJVlKSJRB6Y2fHqdJk+SQ==", "dependencies": { - "@types/react": "*", - "prop-types": "^15.6.2" + "@types/react": "*" }, "peerDependencies": { "react": "*" @@ -13682,6 +16061,66 @@ "node": ">= 0.10" } }, + "node_modules/recma-build-jsx": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/recma-build-jsx/-/recma-build-jsx-1.0.0.tgz", + "integrity": "sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew==", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-util-build-jsx": "^3.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/recma-jsx": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/recma-jsx/-/recma-jsx-1.0.0.tgz", + "integrity": "sha512-5vwkv65qWwYxg+Atz95acp8DMu1JDSqdGkA2Of1j6rCreyFUE/gp15fC8MnGEuG1W68UKjM6x6+YTWIh7hZM/Q==", + "dependencies": { + "acorn-jsx": "^5.0.0", + "estree-util-to-js": "^2.0.0", + "recma-parse": "^1.0.0", + "recma-stringify": "^1.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/recma-parse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/recma-parse/-/recma-parse-1.0.0.tgz", + "integrity": "sha512-OYLsIGBB5Y5wjnSnQW6t3Xg7q3fQ7FWbw/vcXtORTnyaSFscOtABg+7Pnz6YZ6c27fG1/aN8CjfwoUEUIdwqWQ==", + "dependencies": { + "@types/estree": "^1.0.0", + "esast-util-from-js": "^2.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/recma-stringify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/recma-stringify/-/recma-stringify-1.0.0.tgz", + "integrity": "sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g==", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-util-to-js": "^2.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/recursive-readdir": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", @@ -13699,9 +16138,9 @@ "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==" }, "node_modules/regenerate-unicode-properties": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz", - "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.0.tgz", + "integrity": "sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==", "dependencies": { "regenerate": "^1.4.2" }, @@ -13718,230 +16157,95 @@ "version": "0.15.2", "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", - "dependencies": { - "@babel/runtime": "^7.8.4" - } - }, - "node_modules/regexpu-core": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", - "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", - "dependencies": { - "@babel/regjsgen": "^0.8.0", - "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^10.1.0", - "regjsparser": "^0.9.1", - "unicode-match-property-ecmascript": "^2.0.0", - "unicode-match-property-value-ecmascript": "^2.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/registry-auth-token": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-5.0.2.tgz", - "integrity": "sha512-o/3ikDxtXaA59BmZuZrJZDJv8NMDGSj+6j6XaeBmHw8eY1i1qd9+6H+LjVvQXx3HN6aRCGa1cUdJ9RaJZUugnQ==", - "dependencies": { - "@pnpm/npm-conf": "^2.1.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/registry-url": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-6.0.1.tgz", - "integrity": "sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q==", - "dependencies": { - "rc": "1.2.8" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/regjsparser": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", - "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", - "dependencies": { - "jsesc": "~0.5.0" - }, - "bin": { - "regjsparser": "bin/parser" - } - }, - "node_modules/regjsparser/node_modules/jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", - "bin": { - "jsesc": "bin/jsesc" - } - }, - "node_modules/rehype-parse": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/rehype-parse/-/rehype-parse-7.0.1.tgz", - "integrity": "sha512-fOiR9a9xH+Le19i4fGzIEowAbwG7idy2Jzs4mOrFWBSJ0sNUgy0ev871dwWnbOo371SjgjG4pwzrbgSVrKxecw==", - "dependencies": { - "hast-util-from-parse5": "^6.0.0", - "parse5": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/rehype-parse/node_modules/@types/hast": { - "version": "2.3.10", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.10.tgz", - "integrity": "sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==", - "dependencies": { - "@types/unist": "^2" - } - }, - "node_modules/rehype-parse/node_modules/@types/unist": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" - }, - "node_modules/rehype-parse/node_modules/comma-separated-tokens": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz", - "integrity": "sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/rehype-parse/node_modules/hast-util-from-parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-6.0.1.tgz", - "integrity": "sha512-jeJUWiN5pSxW12Rh01smtVkZgZr33wBokLzKLwinYOUfSzm1Nl/c3GUGebDyOKjdsRgMvoVbV0VpAcpjF4NrJA==", - "dependencies": { - "@types/parse5": "^5.0.0", - "hastscript": "^6.0.0", - "property-information": "^5.0.0", - "vfile": "^4.0.0", - "vfile-location": "^3.2.0", - "web-namespaces": "^1.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/rehype-parse/node_modules/hast-util-parse-selector": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz", - "integrity": "sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/rehype-parse/node_modules/hastscript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-6.0.0.tgz", - "integrity": "sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==", - "dependencies": { - "@types/hast": "^2.0.0", - "comma-separated-tokens": "^1.0.0", - "hast-util-parse-selector": "^2.0.0", - "property-information": "^5.0.0", - "space-separated-tokens": "^1.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/rehype-parse/node_modules/parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" + "dependencies": { + "@babel/runtime": "^7.8.4" + } }, - "node_modules/rehype-parse/node_modules/property-information": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/property-information/-/property-information-5.6.0.tgz", - "integrity": "sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==", + "node_modules/regexpu-core": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.2.0.tgz", + "integrity": "sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA==", "dependencies": { - "xtend": "^4.0.0" + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.2.0", + "regjsgen": "^0.8.0", + "regjsparser": "^0.12.0", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.1.0" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "engines": { + "node": ">=4" } }, - "node_modules/rehype-parse/node_modules/space-separated-tokens": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz", - "integrity": "sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "node_modules/registry-auth-token": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-5.0.3.tgz", + "integrity": "sha512-1bpc9IyC+e+CNFRaWyn77tk4xGG4PPUyfakSmA6F6cvUDjrm58dfyJ3II+9yb10EDkHoy1LaPSmHaWLOH3m6HA==", + "dependencies": { + "@pnpm/npm-conf": "^2.1.0" + }, + "engines": { + "node": ">=14" } }, - "node_modules/rehype-parse/node_modules/unist-util-stringify-position": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", - "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==", + "node_modules/registry-url": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-6.0.1.tgz", + "integrity": "sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q==", "dependencies": { - "@types/unist": "^2.0.2" + "rc": "1.2.8" + }, + "engines": { + "node": ">=12" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/rehype-parse/node_modules/vfile": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.2.1.tgz", - "integrity": "sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==", + "node_modules/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==" + }, + "node_modules/regjsparser": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.12.0.tgz", + "integrity": "sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==", "dependencies": { - "@types/unist": "^2.0.0", - "is-buffer": "^2.0.0", - "unist-util-stringify-position": "^2.0.0", - "vfile-message": "^2.0.0" + "jsesc": "~3.0.2" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "bin": { + "regjsparser": "bin/parser" } }, - "node_modules/rehype-parse/node_modules/vfile-location": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-3.2.0.tgz", - "integrity": "sha512-aLEIZKv/oxuCDZ8lkJGhuhztf/BW4M+iHdCwglA/eWc+vtuRFJj8EtgceYFX4LRjOhCAAiNHsKGssC6onJ+jbA==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "node_modules/regjsparser/node_modules/jsesc": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" } }, - "node_modules/rehype-parse/node_modules/vfile-message": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz", - "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==", + "node_modules/rehype-parse": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/rehype-parse/-/rehype-parse-7.0.1.tgz", + "integrity": "sha512-fOiR9a9xH+Le19i4fGzIEowAbwG7idy2Jzs4mOrFWBSJ0sNUgy0ev871dwWnbOo371SjgjG4pwzrbgSVrKxecw==", "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-stringify-position": "^2.0.0" + "hast-util-from-parse5": "^6.0.0", + "parse5": "^6.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/rehype-parse/node_modules/web-namespaces": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-1.1.4.tgz", - "integrity": "sha512-wYxSGajtmoP4WxfejAPIr4l0fVh+jeMXZb08wNc0tMg6xsfZXj3cECqIK0G7ZAqUq0PP8WlMDtaOGVBTAWztNw==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } + "node_modules/rehype-parse/node_modules/parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" }, "node_modules/rehype-raw": { "version": "7.0.0", @@ -13957,6 +16261,20 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/rehype-recma": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/rehype-recma/-/rehype-recma-1.0.0.tgz", + "integrity": "sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw==", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/hast": "^3.0.0", + "hast-util-to-estree": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/relateurl": { "version": "0.2.7", "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", @@ -14028,9 +16346,9 @@ } }, "node_modules/remark-mdx": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-3.0.1.tgz", - "integrity": "sha512-3Pz3yPQ5Rht2pM5R+0J2MrGoBSrzf+tJG94N+t/ilfdh8YLyyKYtidAYwTveB20BoHAcwIopOUqhcmh2F7hGYA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-3.1.0.tgz", + "integrity": "sha512-Ngl/H3YXyBV9RcRNdlYsZujAmhsxwzxpDzpDEhFBVAGthS4GDgnctpDjgFl/ULx5UEDzqtW1cyBSNKqYYrqLBA==", "dependencies": { "mdast-util-mdx": "^3.0.0", "micromark-extension-mdxjs": "^3.0.0" @@ -14056,9 +16374,9 @@ } }, "node_modules/remark-rehype": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.0.tgz", - "integrity": "sha512-z3tJrAs2kIs1AqIIy6pzHmAHlF1hWQ+OdY4/hv+Wxe35EhyLKcajL33iUEn3ScxtFox9nUvRufR/Zre8Q08H/g==", + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.1.tgz", + "integrity": "sha512-g/osARvjkBXb6Wo0XvAeXQohVta8i84ACbenPpoSsxTOQH/Ae0/RGP4WZgnMH5pMLpsj4FG7OHmcIcXxpza8eQ==", "dependencies": { "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", @@ -14208,11 +16526,11 @@ "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" }, "node_modules/resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "version": "1.22.9", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.9.tgz", + "integrity": "sha512-QxrmX1DzraFIi9PxdG5VkRfRwIgjwyud+z/iBwfRRrVmHc+P9Q7u2lSSpQ6bjr2gy5lrqIiU9vb6iAeGf2400A==", "dependencies": { - "is-core-module": "^2.13.0", + "is-core-module": "^2.16.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, @@ -14276,6 +16594,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", "dependencies": { "glob": "^7.1.3" }, @@ -14291,15 +16610,26 @@ "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz", "integrity": "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==" }, + "node_modules/roughjs": { + "version": "4.6.6", + "resolved": "https://registry.npmjs.org/roughjs/-/roughjs-4.6.6.tgz", + "integrity": "sha512-ZUz/69+SYpFN/g/lUlo2FXcIjRkSu3nDarreVdGGndHEBJ6cXPdKguS8JGxwj5HA5xIbVKSmLgr5b3AWxtRfvQ==", + "dependencies": { + "hachure-fill": "^0.5.2", + "path-data-parser": "^0.1.0", + "points-on-curve": "^0.2.0", + "points-on-path": "^0.2.1" + } + }, "node_modules/rtl-detect": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/rtl-detect/-/rtl-detect-1.1.2.tgz", "integrity": "sha512-PGMBq03+TTG/p/cRB7HCLKJ1MgDIi07+QU1faSjiYRfmY5UsAttV9Hs08jDAHVwcOwmVLcSJkpwyfXszVjWfIQ==" }, "node_modules/rtlcss": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/rtlcss/-/rtlcss-4.1.1.tgz", - "integrity": "sha512-/oVHgBtnPNcggP2aVXQjSy6N1mMAfHg4GSag0QtZBlD5bdDgAHwr4pydqJGd+SUCu9260+Pjqbjwtvu7EMH1KQ==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/rtlcss/-/rtlcss-4.3.0.tgz", + "integrity": "sha512-FI+pHEn7Wc4NqKXMXFM+VAYKEj/mRIcW4h24YVwVtyjI+EqGrLc2Hx/Ny0lrZ21cBWU2goLy36eqMcNj3AQJig==", "dependencies": { "escalade": "^3.1.1", "picocolors": "^1.0.0", @@ -14340,17 +16670,6 @@ "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==" }, - "node_modules/sade": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", - "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==", - "dependencies": { - "mri": "^1.1.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -14376,22 +16695,22 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "node_modules/sax": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.3.0.tgz", - "integrity": "sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==" + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", + "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==" }, "node_modules/scheduler": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", - "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", "dependencies": { "loose-envify": "^1.1.0" } }, "node_modules/schema-utils": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", - "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.0.tgz", + "integrity": "sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==", "dependencies": { "@types/json-schema": "^7.0.9", "ajv": "^8.9.0", @@ -14399,7 +16718,7 @@ "ajv-keywords": "^5.1.0" }, "engines": { - "node": ">= 12.13.0" + "node": ">= 10.13.0" }, "funding": { "type": "opencollective", @@ -14407,9 +16726,9 @@ } }, "node_modules/search-insights": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/search-insights/-/search-insights-2.13.0.tgz", - "integrity": "sha512-Orrsjf9trHHxFRuo9/rzm0KIWmgzE8RMlZMzuhZOJ01Rnz3D0YBAe+V6473t6/H6c7irs6Lt48brULAiRWb3Vw==", + "version": "2.17.3", + "resolved": "https://registry.npmjs.org/search-insights/-/search-insights-2.17.3.tgz", + "integrity": "sha512-RQPdCYTa8A68uM2jwxoY842xDhvx3E5LFL1LxvxCNMev4o5mLuokczhzjAgGwUZBAmOKZknArSxLKmXtIi2AxQ==", "peer": true }, "node_modules/section-matter": { @@ -14442,12 +16761,9 @@ } }, "node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dependencies": { - "lru-cache": "^6.0.0" - }, + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "bin": { "semver": "bin/semver.js" }, @@ -14469,22 +16785,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/semver/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, "node_modules/send": { "version": "0.19.0", "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", @@ -14529,11 +16829,6 @@ "node": ">= 0.8" } }, - "node_modules/send/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, "node_modules/send/node_modules/range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", @@ -14551,24 +16846,23 @@ } }, "node_modules/serve-handler": { - "version": "6.1.5", - "resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.5.tgz", - "integrity": "sha512-ijPFle6Hwe8zfmBxJdE+5fta53fdIY0lHISJvuikXB3VYFafRjMRpOffSPvCYsbKyBA7pvy9oYr/BT1O3EArlg==", + "version": "6.1.6", + "resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.6.tgz", + "integrity": "sha512-x5RL9Y2p5+Sh3D38Fh9i/iQ5ZK+e4xuXRd/pGbM4D13tgo/MGwbttUk8emytcr1YYzBYs+apnUngBDFYfpjPuQ==", "dependencies": { "bytes": "3.0.0", "content-disposition": "0.5.2", - "fast-url-parser": "1.1.3", "mime-types": "2.1.18", "minimatch": "3.1.2", "path-is-inside": "1.0.2", - "path-to-regexp": "2.2.1", + "path-to-regexp": "3.3.0", "range-parser": "1.2.0" } }, "node_modules/serve-handler/node_modules/path-to-regexp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-2.2.1.tgz", - "integrity": "sha512-gu9bD6Ta5bwGrrU8muHzVOBFFREpp2iRkVfhBJahwJ6p6Xw20SjT0MxLnwkjOibQmGSYhiUnf2FLe7k+jcFmGQ==" + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-3.3.0.tgz", + "integrity": "sha512-qyCH421YQPS2WFDxDjftfc1ZR5WKQzVzqsp4n9M2kQhVOo/ByahFoUNJfl58kOcEGfQ//7weFTDhm+ss8Ecxgw==" }, "node_modules/serve-index": { "version": "1.9.1", @@ -14711,9 +17005,12 @@ } }, "node_modules/shell-quote": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", - "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.2.tgz", + "integrity": "sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA==", + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -14826,9 +17123,9 @@ "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==" }, "node_modules/sitemap": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/sitemap/-/sitemap-7.1.1.tgz", - "integrity": "sha512-mK3aFtjz4VdJN0igpIJrinf3EO8U8mxOPsTBzSsy06UtjZQJ3YY3o3Xa7zSc5nMqcMrRwlChHZ18Kxg0caiPBg==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/sitemap/-/sitemap-7.1.2.tgz", + "integrity": "sha512-ARCqzHJ0p4gWt+j7NlU5eDlIO9+Rkr/JhPFZKKQ1l5GCus7rJH4UdrlVAh0xC/gDS/Qir2UMxqYNHtsKr2rpCw==", "dependencies": { "@types/node": "^17.0.5", "@types/sax": "^1.2.1", @@ -14867,6 +17164,15 @@ "node": ">=8" } }, + "node_modules/snake-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", + "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==", + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, "node_modules/sockjs": { "version": "0.3.24", "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", @@ -14877,10 +17183,18 @@ "websocket-driver": "^0.7.4" } }, + "node_modules/sockjs/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/sort-css-media-queries": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/sort-css-media-queries/-/sort-css-media-queries-2.1.0.tgz", - "integrity": "sha512-IeWvo8NkNiY2vVYdPa27MCQiR0MN0M80johAYFVxWWXQ44KU84WNxjslwBHmc/7ZL2ccwkM7/e6S5aiKZXm7jA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/sort-css-media-queries/-/sort-css-media-queries-2.2.0.tgz", + "integrity": "sha512-0xtkGhWCC9MGt/EzgnvbbbKhqWjl1+/rncmhTh5qCpbYguXh6S/qwePfv/JQ8jePXXmqingylxoC49pCkSPIbA==", "engines": { "node": ">= 6.3.0" } @@ -14894,9 +17208,9 @@ } }, "node_modules/source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", "engines": { "node": ">=0.10.0" } @@ -14919,9 +17233,9 @@ } }, "node_modules/space-separated-tokens": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", - "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz", + "integrity": "sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -14971,12 +17285,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/stable": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", - "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", - "deprecated": "Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility" - }, "node_modules/statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", @@ -14986,9 +17294,9 @@ } }, "node_modules/std-env": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.7.0.tgz", - "integrity": "sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==" + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.8.0.tgz", + "integrity": "sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w==" }, "node_modules/string_decoder": { "version": "1.3.0", @@ -15015,9 +17323,9 @@ } }, "node_modules/string-width/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", "engines": { "node": ">=12" }, @@ -15040,9 +17348,9 @@ } }, "node_modules/stringify-entities": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.3.tgz", - "integrity": "sha512-BP9nNHMhhfcMbiuQKCqMjhDP5yBCAxsPu4pHFFzJ6Alo9dZgY4VLDPutXqIjpRiMoKdp7Av85Gr73Q5uH9k7+g==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", + "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", "dependencies": { "character-entities-html4": "^2.0.0", "character-entities-legacy": "^3.0.0" @@ -15104,32 +17412,32 @@ } }, "node_modules/style-to-object": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.4.4.tgz", - "integrity": "sha512-HYNoHZa2GorYNyqiCaBgsxvcJIn7OHq6inEga+E6Ke3m5JkoqpQbnFssk4jwe+K7AhGa2fcha4wSOf1Kn01dMg==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.8.tgz", + "integrity": "sha512-xT47I/Eo0rwJmaXC4oilDGDWLohVhR6o/xAQcPQN8q6QBuZVL8qMYL85kLmST5cPjAorwvqIA4qXTRQoYHaL6g==", "dependencies": { - "inline-style-parser": "0.1.1" + "inline-style-parser": "0.2.4" } }, "node_modules/stylehacks": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.1.tgz", - "integrity": "sha512-sBpcd5Hx7G6seo7b1LkpttvTz7ikD0LlH5RmdcBNb6fFR0Fl7LQwHDFr300q4cwUqi+IYrFGmsIHieMBfnN/Bw==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-6.1.1.tgz", + "integrity": "sha512-gSTTEQ670cJNoaeIp9KX6lZmm8LJ3jPB5yJmX8Zq/wQxOsAFXV3qjWzHas3YYk1qesuVIyYWWUpZ0vSE/dTSGg==", "dependencies": { - "browserslist": "^4.21.4", - "postcss-selector-parser": "^6.0.4" + "browserslist": "^4.23.0", + "postcss-selector-parser": "^6.0.16" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/stylis": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.1.tgz", - "integrity": "sha512-EQepAV+wMsIaGVGX1RECzgrcqRRU/0sYOHkeLsZ3fzHaHXZy4DaOOX0vOlGQdlsjkh3mFHAIlVimpwAs4dslyQ==" + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.4.tgz", + "integrity": "sha512-osIBl6BGUmSfDkyH2mB7EFvCJntXDrLhKjHTRj/rK6xLH0yuPrHULDRQzKokSOD4VoorhtKpfcfW1GAntu8now==" }, "node_modules/supports-color": { "version": "7.2.0", @@ -15147,106 +17455,47 @@ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/svg-parser": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz", - "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==" - }, - "node_modules/svgo": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz", - "integrity": "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==", - "dependencies": { - "@trysound/sax": "0.2.0", - "commander": "^7.2.0", - "css-select": "^4.1.3", - "css-tree": "^1.1.3", - "csso": "^4.2.0", - "picocolors": "^1.0.0", - "stable": "^0.1.8" - }, - "bin": { - "svgo": "bin/svgo" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/svgo/node_modules/commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "engines": { - "node": ">= 10" - } - }, - "node_modules/svgo/node_modules/css-select": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", - "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^6.0.1", - "domhandler": "^4.3.1", - "domutils": "^2.8.0", - "nth-check": "^2.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/svgo/node_modules/dom-serializer": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", - "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", - "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.0", - "entities": "^2.0.0" - }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" - } - }, - "node_modules/svgo/node_modules/domhandler": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", - "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", - "dependencies": { - "domelementtype": "^2.2.0" - }, - "engines": { - "node": ">= 4" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/svgo/node_modules/domutils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", - "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "node_modules/svg-parser": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz", + "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==" + }, + "node_modules/svgo": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.3.2.tgz", + "integrity": "sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw==", "dependencies": { - "dom-serializer": "^1.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.2.0" + "@trysound/sax": "0.2.0", + "commander": "^7.2.0", + "css-select": "^5.1.0", + "css-tree": "^2.3.1", + "css-what": "^6.1.0", + "csso": "^5.0.5", + "picocolors": "^1.0.0" + }, + "bin": { + "svgo": "bin/svgo" + }, + "engines": { + "node": ">=14.0.0" }, "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" + "type": "opencollective", + "url": "https://opencollective.com/svgo" } }, - "node_modules/svgo/node_modules/entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" + "node_modules/svgo/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "engines": { + "node": ">= 10" } }, "node_modules/tapable": { @@ -15258,9 +17507,9 @@ } }, "node_modules/terser": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.27.0.tgz", - "integrity": "sha512-bi1HRwVRskAjheeYl291n3JC4GgO/Ty4z1nVs5AAsmonJulGxpSektecnNedrwK9C7vpvVtcX3cw00VSLt7U2A==", + "version": "5.37.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.37.0.tgz", + "integrity": "sha512-B8wRRkmre4ERucLM/uXx4MOV5cbnOlVAqUst+1+iLKPI0dOgFO28f84ptoQt9HEI537PMzfYa/d+GEPKTRXmYA==", "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.8.2", @@ -15275,15 +17524,15 @@ } }, "node_modules/terser-webpack-plugin": { - "version": "5.3.10", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", - "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", + "version": "5.3.11", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.11.tgz", + "integrity": "sha512-RVCsMfuD0+cTt3EwX8hSl2Ks56EbFHWmhluwcqoPKtBnfjiT6olaq7PRIRfhyU8nnC2MrnDrBLfrD/RGE+cVXQ==", "dependencies": { - "@jridgewell/trace-mapping": "^0.3.20", + "@jridgewell/trace-mapping": "^0.3.25", "jest-worker": "^27.4.5", - "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.1", - "terser": "^5.26.0" + "schema-utils": "^4.3.0", + "serialize-javascript": "^6.0.2", + "terser": "^5.31.1" }, "engines": { "node": ">= 10.13.0" @@ -15307,29 +17556,6 @@ } } }, - "node_modules/terser-webpack-plugin/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/terser-webpack-plugin/node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "peerDependencies": { - "ajv": "^6.9.1" - } - }, "node_modules/terser-webpack-plugin/node_modules/jest-worker": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", @@ -15343,28 +17569,6 @@ "node": ">= 10.13.0" } }, - "node_modules/terser-webpack-plugin/node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "node_modules/terser-webpack-plugin/node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, "node_modules/terser-webpack-plugin/node_modules/supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", @@ -15395,22 +17599,19 @@ "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==" }, "node_modules/tiny-invariant": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.1.tgz", - "integrity": "sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==" + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", + "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==" }, "node_modules/tiny-warning": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "engines": { - "node": ">=4" - } + "node_modules/tinyexec": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.1.tgz", + "integrity": "sha512-WiCJLEECkO18gwqIp6+hJg0//p23HXp4S+gGtAKu3mI2F2/sXC4FvHvXvB0zJVVaTPhx1/tOwdbRsa1sOBIKqQ==" }, "node_modules/to-regex-range": { "version": "5.0.1", @@ -15437,9 +17638,9 @@ } }, "node_modules/to-vfile/node_modules/@types/unist": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==" }, "node_modules/to-vfile/node_modules/unist-util-stringify-position": { "version": "2.0.3", @@ -15524,9 +17725,9 @@ } }, "node_modules/tslib": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" }, "node_modules/type-fest": { "version": "2.19.0", @@ -15590,15 +17791,20 @@ "node": ">=14.17" } }, + "node_modules/ufo": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.4.tgz", + "integrity": "sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==" + }, "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==" }, "node_modules/unicode-canonical-property-names-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", - "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", + "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==", "engines": { "node": ">=4" } @@ -15624,9 +17830,9 @@ } }, "node_modules/unicode-match-property-value-ecmascript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", - "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.0.tgz", + "integrity": "sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg==", "engines": { "node": ">=4" } @@ -15640,9 +17846,9 @@ } }, "node_modules/unified": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.4.tgz", - "integrity": "sha512-apMPnyLjAX+ty4OrNap7yumyVAMlKx5IWU2wlzzUdYJO9A8f1p9m/gywF/GM2ZDFcjQPrx59Mc90KwmxsoklxQ==", + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", + "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==", "dependencies": { "@types/unist": "^3.0.0", "bail": "^2.0.0", @@ -15683,7 +17889,7 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/unist-util-find-after/node_modules/unist-util-is": { + "node_modules/unist-util-is": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz", "integrity": "sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==", @@ -15692,18 +17898,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/unist-util-is": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", - "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, "node_modules/unist-util-position": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", @@ -15728,19 +17922,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/unist-util-remove-position": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-5.0.0.tgz", - "integrity": "sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-visit": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, "node_modules/unist-util-stringify-position": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", @@ -15780,6 +17961,30 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/unist-util-visit-parents/node_modules/unist-util-is": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", + "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit/node_modules/unist-util-is": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", + "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/universalify": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", @@ -15903,14 +18108,6 @@ "punycode": "^2.1.0" } }, - "node_modules/uri-js/node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "engines": { - "node": ">=6" - } - }, "node_modules/url-loader": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-4.1.1.tgz", @@ -16028,38 +18225,17 @@ } }, "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], "bin": { "uuid": "dist/bin/uuid" } }, - "node_modules/uvu": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/uvu/-/uvu-0.5.6.tgz", - "integrity": "sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==", - "dependencies": { - "dequal": "^2.0.0", - "diff": "^5.0.0", - "kleur": "^4.0.3", - "sade": "^1.7.3" - }, - "bin": { - "uvu": "bin.js" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/uvu/node_modules/kleur": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", - "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", - "engines": { - "node": ">=6" - } - }, "node_modules/value-equal": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz", @@ -16074,12 +18250,11 @@ } }, "node_modules/vfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.1.tgz", - "integrity": "sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", + "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", "dependencies": { "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0", "vfile-message": "^4.0.0" }, "funding": { @@ -16088,13 +18263,9 @@ } }, "node_modules/vfile-location": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-5.0.2.tgz", - "integrity": "sha512-NXPYyxyBSH7zB5U6+3uDdd6Nybz6o6/od9rk8bp9H8GR3L+cm/fC0uUTbqBmUTnMCUDslAGBOIKNfvvb+gGlDg==", - "dependencies": { - "@types/unist": "^3.0.0", - "vfile": "^6.0.0" - }, + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-3.2.0.tgz", + "integrity": "sha512-aLEIZKv/oxuCDZ8lkJGhuhztf/BW4M+iHdCwglA/eWc+vtuRFJj8EtgceYFX4LRjOhCAAiNHsKGssC6onJ+jbA==", "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" @@ -16113,6 +18284,49 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/vscode-jsonrpc": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0.tgz", + "integrity": "sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/vscode-languageserver": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-9.0.1.tgz", + "integrity": "sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g==", + "dependencies": { + "vscode-languageserver-protocol": "3.17.5" + }, + "bin": { + "installServerIntoExtension": "bin/installServerIntoExtension" + } + }, + "node_modules/vscode-languageserver-protocol": { + "version": "3.17.5", + "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.5.tgz", + "integrity": "sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==", + "dependencies": { + "vscode-jsonrpc": "8.2.0", + "vscode-languageserver-types": "3.17.5" + } + }, + "node_modules/vscode-languageserver-textdocument": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.12.tgz", + "integrity": "sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==" + }, + "node_modules/vscode-languageserver-types": { + "version": "3.17.5", + "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz", + "integrity": "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==" + }, + "node_modules/vscode-uri": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.8.tgz", + "integrity": "sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==" + }, "node_modules/watchpack": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz", @@ -16134,19 +18348,14 @@ } }, "node_modules/web-namespaces": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", - "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-1.1.4.tgz", + "integrity": "sha512-wYxSGajtmoP4WxfejAPIr4l0fVh+jeMXZb08wNc0tMg6xsfZXj3cECqIK0G7ZAqUq0PP8WlMDtaOGVBTAWztNw==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/web-worker": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.3.0.tgz", - "integrity": "sha512-BSR9wyRsy/KOValMgd5kMyr3JzpdeoR9KVId8u5GVlTTAtNChlsE4yTxeY7zMdNSyOmoKBv8NH2qeRY9Tg+IaA==" - }, "node_modules/webpack": { "version": "5.97.1", "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.97.1.tgz", @@ -16193,9 +18402,9 @@ } }, "node_modules/webpack-bundle-analyzer": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.10.1.tgz", - "integrity": "sha512-s3P7pgexgT/HTUSYgxJyn28A+99mmLq4HsJepMPzu0R8ImJc52QNqaFYW1Z2z2uIb1/J3eYgaAWVpaC+v/1aAQ==", + "version": "4.10.2", + "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.10.2.tgz", + "integrity": "sha512-vJptkMm9pk5si4Bv922ZbKLV8UTT4zib4FPgXMhgzUny0bfDDkLXAVQs3ly3fS4/TN9ROFtb0NFrm04UXFE/Vw==", "dependencies": { "@discoveryjs/json-ext": "0.5.7", "acorn": "^8.0.4", @@ -16205,7 +18414,6 @@ "escape-string-regexp": "^4.0.0", "gzip-size": "^6.0.0", "html-escaper": "^2.0.2", - "is-plain-object": "^5.0.0", "opener": "^1.5.2", "picocolors": "^1.0.0", "sirv": "^2.0.3", @@ -16276,9 +18484,9 @@ } }, "node_modules/webpack-dev-server": { - "version": "4.15.1", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.1.tgz", - "integrity": "sha512-5hbAst3h3C3L8w6W4P96L5vaV0PxSmJhxZvWKYIdgxOQm8pNZ5dEOmmSLBVpP85ReeyRt6AS1QJNyo/oFFPeVA==", + "version": "4.15.2", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.2.tgz", + "integrity": "sha512-0XavAZbNJ5sDrCbkpWL8mia0o5WPOd2YGtxrEiZkBK9FjLppIUK2TgxK6qGD2P3hUXTJNNPVibrerKcx5WkR1g==", "dependencies": { "@types/bonjour": "^3.5.9", "@types/connect-history-api-fallback": "^1.3.5", @@ -16308,7 +18516,7 @@ "serve-index": "^1.9.1", "sockjs": "^0.3.24", "spdy": "^4.0.2", - "webpack-dev-middleware": "^5.3.1", + "webpack-dev-middleware": "^5.3.4", "ws": "^8.13.0" }, "bin": { @@ -16334,9 +18542,9 @@ } }, "node_modules/webpack-dev-server/node_modules/ws": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz", - "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", "engines": { "node": ">=10.0.0" }, @@ -16354,16 +18562,16 @@ } }, "node_modules/webpack-merge": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", - "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-6.0.1.tgz", + "integrity": "sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg==", "dependencies": { "clone-deep": "^4.0.1", "flat": "^5.0.2", - "wildcard": "^2.0.0" + "wildcard": "^2.0.1" }, "engines": { - "node": ">=10.0.0" + "node": ">=18.0.0" } }, "node_modules/webpack-sources": { @@ -16439,22 +18647,72 @@ } }, "node_modules/webpackbar": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/webpackbar/-/webpackbar-5.0.2.tgz", - "integrity": "sha512-BmFJo7veBDgQzfWXl/wwYXr/VFus0614qZ8i9znqcl9fnEdiVkdbi0TedLQ6xAK92HZHDJ0QmyQ0fmuZPAgCYQ==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/webpackbar/-/webpackbar-6.0.1.tgz", + "integrity": "sha512-TnErZpmuKdwWBdMoexjio3KKX6ZtoKHRVvLIU0A47R0VVBDtx3ZyOJDktgYixhoJokZTYTt1Z37OkO9pnGJa9Q==", "dependencies": { - "chalk": "^4.1.0", - "consola": "^2.15.3", + "ansi-escapes": "^4.3.2", + "chalk": "^4.1.2", + "consola": "^3.2.3", + "figures": "^3.2.0", + "markdown-table": "^2.0.0", "pretty-time": "^1.1.0", - "std-env": "^3.0.1" + "std-env": "^3.7.0", + "wrap-ansi": "^7.0.0" }, "engines": { - "node": ">=12" + "node": ">=14.21.3" }, "peerDependencies": { "webpack": "3 || 4 || 5" } }, + "node_modules/webpackbar/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/webpackbar/node_modules/markdown-table": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-2.0.0.tgz", + "integrity": "sha512-Ezda85ToJUBhM6WGaG6veasyym+Tbs3cMAw/ZhOPqXiYsr0jgocBV3j3nx+4lk47plLlIqjwuTm/ywVI+zjJ/A==", + "dependencies": { + "repeat-string": "^1.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/webpackbar/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/webpackbar/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/websocket-driver": { "version": "0.7.4", "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", @@ -16552,9 +18810,9 @@ } }, "node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", "engines": { "node": ">=12" }, @@ -16604,9 +18862,9 @@ } }, "node_modules/ws": { - "version": "7.5.9", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", - "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", "engines": { "node": ">=8.3.0" }, @@ -16667,9 +18925,9 @@ } }, "node_modules/yocto-queue": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", - "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.1.1.tgz", + "integrity": "sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==", "engines": { "node": ">=12.20" }, @@ -16678,9 +18936,9 @@ } }, "node_modules/zwitch": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", - "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-1.0.5.tgz", + "integrity": "sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" diff --git a/documentation/package.json b/documentation/package.json index f07c8f83..deae512d 100644 --- a/documentation/package.json +++ b/documentation/package.json @@ -16,18 +16,18 @@ }, "dependencies": { "@docusaurus/core": "^3.1.1", - "@docusaurus/preset-classic": "^3.1.1", - "@docusaurus/theme-mermaid": "^3.1.1", - "@mdx-js/react": "^3.0.0", - "clsx": "^2.0.0", - "docusaurus-lunr-search": "^3.3.2", - "prism-react-renderer": "^2.3.0", - "react": "^18.0.0", - "react-dom": "^18.0.0" + "@docusaurus/preset-classic": "^3.6.3", + "@docusaurus/theme-mermaid": "^3.6.3", + "@mdx-js/react": "^3.1.0", + "clsx": "^2.1.1", + "docusaurus-lunr-search": "^3.5.0", + "prism-react-renderer": "^2.4.1", + "react": "^18.3.1", + "react-dom": "^18.3.1" }, "devDependencies": { "@docusaurus/module-type-aliases": "^3.1.1", - "@docusaurus/tsconfig": "^3.1.1", + "@docusaurus/tsconfig": "^3.6.3", "@docusaurus/types": "^3.1.1", "typescript": "~5.2.2" }, From f25dfc5b44f6420c39bedeb3c30b988f41682a44 Mon Sep 17 00:00:00 2001 From: dylanhitt Date: Sat, 14 Dec 2024 09:40:56 -0500 Subject: [PATCH 072/138] chore: cleanup some status codes and godoc Co-authored-by: ccoVeille <3875889+ccoVeille@users.noreply.github.com> --- option.go | 2 +- option/option.go | 2 +- option_test.go | 12 ++++++------ server.go | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/option.go b/option.go index e7e647a3..28e51258 100644 --- a/option.go +++ b/option.go @@ -294,7 +294,7 @@ func OptionDeprecated() func(*BaseRoute) { // AddError adds an error to the route. // It replaces any existing error previously set with the same code. // Required: should only supply one type to `errorType` -// Deprecated: Use `OptionAddResponse` instead +// Deprecated: Use [OptionAddResponse] instead func OptionAddError(code int, description string, errorType ...any) func(*BaseRoute) { var responseSchema SchemaTag return func(r *BaseRoute) { diff --git a/option/option.go b/option/option.go index 53199ddc..c3ade403 100644 --- a/option/option.go +++ b/option/option.go @@ -146,7 +146,7 @@ var OperationID = fuego.OptionOperationID var Deprecated = fuego.OptionDeprecated // AddError adds an error to the route. -// Deprecated: Use `AddResponse` instead. +// Deprecated: Use [AddResponse] instead. var AddError = fuego.OptionAddError // AddResponse adds a response to a route by status code diff --git a/option_test.go b/option_test.go index 6f93670f..382becde 100644 --- a/option_test.go +++ b/option_test.go @@ -394,7 +394,7 @@ func TestAddError(t *testing.T) { t.Run("Declare an error for the route", func(t *testing.T) { s := fuego.NewServer() - route := fuego.Get(s, "/test", helloWorld, fuego.OptionAddError(409, "Conflict: Pet with the same name already exists")) + route := fuego.Get(s, "/test", helloWorld, fuego.OptionAddError(http.StatusConflict, "Conflict: Pet with the same name already exists")) t.Log("route.Operation.Responses", route.Operation.Responses) require.Equal(t, 5, route.Operation.Responses.Len()) // 200, 400, 409, 500, default @@ -407,7 +407,7 @@ func TestAddError(t *testing.T) { s := fuego.NewServer() require.Panics(t, func() { - fuego.Get(s, "/test", helloWorld, fuego.OptionAddError(409, "err", Resp{}, Resp{})) + fuego.Get(s, "/test", helloWorld, fuego.OptionAddError(http.StatusConflict, "err", Resp{}, Resp{})) }) }) } @@ -416,7 +416,7 @@ func TestAddResponse(t *testing.T) { t.Run("base", func(t *testing.T) { s := fuego.NewServer() route := fuego.Get(s, "/test", helloWorld, fuego.OptionAddResponse( - 409, + http.StatusConflict, "Conflict: Pet with the same name already exists", fuego.Response{ ContentTypes: []string{"application/json"}, @@ -434,7 +434,7 @@ func TestAddResponse(t *testing.T) { t.Run("no content types provided", func(t *testing.T) { s := fuego.NewServer() route := fuego.Get(s, "/test", helloWorld, fuego.OptionAddResponse( - 409, + http.StatusConflict, "Conflict: Pet with the same name already exists", fuego.Response{ Type: fuego.HTTPError{}, @@ -451,7 +451,7 @@ func TestAddResponse(t *testing.T) { t.Run("should override 200", func(t *testing.T) { s := fuego.NewServer() route := fuego.Get(s, "/test", helloWorld, fuego.OptionAddResponse( - 200, + http.StatusOK, "set 200", fuego.Response{ Type: fuego.HTTPError{}, @@ -473,7 +473,7 @@ func TestAddResponse(t *testing.T) { require.Panics(t, func() { fuego.Get(s, "/test", helloWorld, fuego.OptionAddResponse( - 409, + http.StatusConflict, "Conflict: Pet with the same name already exists", fuego.Response{}, )) diff --git a/server.go b/server.go index be12884d..c791fc75 100644 --- a/server.go +++ b/server.go @@ -315,7 +315,7 @@ func WithDisallowUnknownFields(b bool) func(*Server) { // If not specified, the default port is 9999. // If you want to use a different address, use [WithAddr] instead. // -// Deprecated: Please use fuego.WithAddr(addr string) +// Deprecated: Please use [WithAddr] func WithPort(port int) func(*Server) { return func(s *Server) { s.Server.Addr = fmt.Sprintf("localhost:%d", port) } } From 79f6d66a219dcfc32a0852f70232801d334345eb Mon Sep 17 00:00:00 2001 From: dylanhitt Date: Sat, 14 Dec 2024 09:55:45 -0500 Subject: [PATCH 073/138] chore: increase dial timeout in tls tests --- serve_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/serve_test.go b/serve_test.go index 8f11a599..967c0199 100644 --- a/serve_test.go +++ b/serve_test.go @@ -514,7 +514,7 @@ func TestServer_RunTLS(t *testing.T) { }() // wait for the server to start - conn, err := net.DialTimeout("tcp", s.Server.Addr, 2*time.Second) + conn, err := net.DialTimeout("tcp", s.Server.Addr, 5*time.Second) if err != nil { t.Fatal(err) } From a256a7c444c31f08cbab140c15e244cee3f467f1 Mon Sep 17 00:00:00 2001 From: Ewen Quimerc'h <46993939+EwenQuim@users.noreply.github.com> Date: Sat, 14 Dec 2024 16:46:58 +0100 Subject: [PATCH 074/138] Description option : override + default description contains the list of middlewares (#275) * Refactored the Description/AddDescription to a clearer system * New more explicit OverrideDescription option * Tests for the description option with middlewares * Make tag order deterministic * Update option.go Co-authored-by: ccoVeille <3875889+ccoVeille@users.noreply.github.com> * Makes overrideDescription private in BaseRoute * Moved the operation ID generation to a method on the BaseRoute struct. * Generate description is in OpenAPI registration, not in mux registration --------- Co-authored-by: ccoVeille <3875889+ccoVeille@users.noreply.github.com> --- examples/full-app-gourmet/views/views.go | 4 +- examples/petstore/controllers/middlewares.go | 11 ++++ examples/petstore/controllers/pets.go | 9 ++- .../lib/testdata/doc/openapi.golden.json | 28 ++++----- mux.go | 63 ++++++++++++------- mux_test.go | 6 +- openapi.go | 21 ++++++- openapi_operations_test.go | 2 +- option.go | 16 ++++- option/option.go | 7 +++ option_test.go | 53 ++++++++++++++-- 11 files changed, 167 insertions(+), 53 deletions(-) create mode 100644 examples/petstore/controllers/middlewares.go diff --git a/examples/full-app-gourmet/views/views.go b/examples/full-app-gourmet/views/views.go index d583f907..50a3e793 100644 --- a/examples/full-app-gourmet/views/views.go +++ b/examples/full-app-gourmet/views/views.go @@ -67,6 +67,8 @@ func (rs Resource) Routes(s *fuego.Server) { fuego.Get(adminRoutes, "/ingredients/create", rs.adminIngredientCreationPage) fuego.All(adminRoutes, "/ingredients/{id}", rs.adminOneIngredient) - fuego.Post(adminRoutes, "/ingredients/new", rs.adminCreateIngredient) + fuego.Post(adminRoutes, "/ingredients/new", rs.adminCreateIngredient, + option.Description("Create a new ingredient"), + ) fuego.Get(adminRoutes, "/users", rs.adminRecipes) } diff --git a/examples/petstore/controllers/middlewares.go b/examples/petstore/controllers/middlewares.go new file mode 100644 index 00000000..99deb7be --- /dev/null +++ b/examples/petstore/controllers/middlewares.go @@ -0,0 +1,11 @@ +package controller + +import "net/http" + +func dummyMiddleware(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + // do something before + next.ServeHTTP(w, r) + // do something after + }) +} diff --git a/examples/petstore/controllers/pets.go b/examples/petstore/controllers/pets.go index 72a2d0d2..734a8031 100644 --- a/examples/petstore/controllers/pets.go +++ b/examples/petstore/controllers/pets.go @@ -47,13 +47,18 @@ func (rs PetsResources) Routes(s *fuego.Server) { option.Description("Get all pets"), ) - fuego.Get(petsGroup, "/by-age", rs.getAllPetsByAge, option.Description("Returns an array of pets grouped by age")) + fuego.Get(petsGroup, "/by-age", rs.getAllPetsByAge, + option.Description("Returns an array of pets grouped by age"), + option.Middleware(dummyMiddleware), + ) fuego.Post(petsGroup, "/", rs.postPets, option.DefaultStatusCode(201), option.AddResponse(409, "Conflict: Pet with the same name already exists", fuego.Response{Type: PetsError{}}), ) fuego.Get(petsGroup, "/{id}", rs.getPets, + option.OverrideDescription("Replace description with this sentence."), + option.OperationID("getPet"), option.Path("id", "Pet ID", param.Example("example", "123")), ) fuego.Get(petsGroup, "/by-name/{name...}", rs.getPetByName) @@ -77,14 +82,12 @@ func (rs PetsResources) Routes(s *fuego.Server) { if err := json.NewEncoder(w).Encode(pets); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } - }, option.AddResponse(http.StatusOK, "all the pets", fuego.Response{ Type: []models.Pets{}, ContentTypes: []string{"application/json"}, }, )) - } func (rs PetsResources) getAllPets(c fuego.ContextNoBody) ([]models.Pets, error) { diff --git a/examples/petstore/lib/testdata/doc/openapi.golden.json b/examples/petstore/lib/testdata/doc/openapi.golden.json index beb1b056..167c6f2e 100644 --- a/examples/petstore/lib/testdata/doc/openapi.golden.json +++ b/examples/petstore/lib/testdata/doc/openapi.golden.json @@ -152,7 +152,7 @@ "paths": { "/pets/": { "get": { - "description": "controller: `github.com/go-fuego/fuego/examples/petstore/controllers.PetsResources.filterPets`\n\n---\n\nFilter pets", + "description": "#### Controller: \n\n`github.com/go-fuego/fuego/examples/petstore/controllers.PetsResources.filterPets`\n\n---\n\nFilter pets", "operationId": "GET_/pets/", "parameters": [ { @@ -302,7 +302,7 @@ ] }, "post": { - "description": "controller: `github.com/go-fuego/fuego/examples/petstore/controllers.PetsResources.postPets`\n\n---\n\n", + "description": "#### Controller: \n\n`github.com/go-fuego/fuego/examples/petstore/controllers.PetsResources.postPets`\n\n---\n\n", "operationId": "POST_/pets/", "parameters": [ { @@ -395,7 +395,7 @@ }, "/pets/all": { "get": { - "description": "controller: `github.com/go-fuego/fuego/examples/petstore/controllers.PetsResources.getAllPets`\n\n---\n\nGet all pets", + "description": "#### Controller: \n\n`github.com/go-fuego/fuego/examples/petstore/controllers.PetsResources.getAllPets`\n\n---\n\nGet all pets", "operationId": "GET_/pets/all", "parameters": [ { @@ -525,7 +525,7 @@ }, "/pets/by-age": { "get": { - "description": "controller: `github.com/go-fuego/fuego/examples/petstore/controllers.PetsResources.getAllPetsByAge`\n\n---\n\nReturns an array of pets grouped by age", + "description": "#### Controller: \n\n`github.com/go-fuego/fuego/examples/petstore/controllers.PetsResources.getAllPetsByAge`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego/examples/petstore/controllers.dummyMiddleware`\n\n---\n\nReturns an array of pets grouped by age", "operationId": "GET_/pets/by-age", "parameters": [ { @@ -604,7 +604,7 @@ }, "/pets/by-name/{name...}": { "get": { - "description": "controller: `github.com/go-fuego/fuego/examples/petstore/controllers.PetsResources.getPetByName`\n\n---\n\n", + "description": "#### Controller: \n\n`github.com/go-fuego/fuego/examples/petstore/controllers.PetsResources.getPetByName`\n\n---\n\n", "operationId": "GET_/pets/by-name/:name...", "parameters": [ { @@ -680,7 +680,7 @@ }, "/pets/std/all": { "get": { - "description": "controller: `github.com/go-fuego/fuego/examples/petstore/controllers.PetsResources.Routes.func1`\n\n---\n\n", + "description": "#### Controller: \n\n`github.com/go-fuego/fuego/examples/petstore/controllers.PetsResources.Routes.func1`\n\n---\n\n", "operationId": "GET_/pets/std/all", "parameters": [ { @@ -739,7 +739,7 @@ }, "/pets/{id}": { "delete": { - "description": "controller: `github.com/go-fuego/fuego/examples/petstore/controllers.PetsResources.deletePets`\n\n---\n\n", + "description": "#### Controller: \n\n`github.com/go-fuego/fuego/examples/petstore/controllers.PetsResources.deletePets`\n\n---\n\n", "operationId": "DELETE_/pets/:id", "parameters": [ { @@ -812,8 +812,8 @@ ] }, "get": { - "description": "controller: `github.com/go-fuego/fuego/examples/petstore/controllers.PetsResources.getPets`\n\n---\n\n", - "operationId": "GET_/pets/:id", + "description": "Replace description with this sentence.", + "operationId": "getPet", "parameters": [ { "in": "header", @@ -891,7 +891,7 @@ ] }, "put": { - "description": "controller: `github.com/go-fuego/fuego/examples/petstore/controllers.PetsResources.putPets`\n\n---\n\n", + "description": "#### Controller: \n\n`github.com/go-fuego/fuego/examples/petstore/controllers.PetsResources.putPets`\n\n---\n\n", "operationId": "PUT_/pets/:id", "parameters": [ { @@ -977,7 +977,7 @@ }, "/pets/{id}/json": { "put": { - "description": "controller: `github.com/go-fuego/fuego/examples/petstore/controllers.PetsResources.putPets`\n\n---\n\n", + "description": "#### Controller: \n\n`github.com/go-fuego/fuego/examples/petstore/controllers.PetsResources.putPets`\n\n---\n\n", "operationId": "PUT_/pets/:id/json", "parameters": [ { @@ -1070,13 +1070,13 @@ ], "tags": [ { - "name": "pets" + "name": "my-tag" }, { - "name": "std" + "name": "pets" }, { - "name": "my-tag" + "name": "std" } ] } \ No newline at end of file diff --git a/mux.go b/mux.go index 2cbc51b7..7b348708 100644 --- a/mux.go +++ b/mux.go @@ -60,6 +60,19 @@ type BaseRoute struct { Hidden bool // If true, the route will not be documented in the OpenAPI spec DefaultStatusCode int // Default status code for the response OpenAPI *OpenAPI // Ref to the whole OpenAPI spec + + overrideDescription bool // Override the default description +} + +func (r *BaseRoute) GenerateDefaultDescription() { + if r.overrideDescription { + return + } + r.Operation.Description = DefaultDescription(r.FullName, r.Middlewares) + r.Operation.Description +} + +func (r *BaseRoute) GenerateDefaultOperationID() { + r.Operation.OperationID = r.Method + "_" + strings.ReplaceAll(strings.ReplaceAll(r.Path, "{", ":"), "}", "") } // Capture all methods (GET, POST, PUT, PATCH, DELETE) and register a controller. @@ -93,41 +106,26 @@ func Register[T, B any](s *Server, route Route[T, B], controller http.Handler, o o(&route.BaseRoute) } route.Handler = controller + route.Path = s.basePath + route.Path - fullPath := s.basePath + route.Path + fullPath := route.Path if route.Method != "" { fullPath = route.Method + " " + fullPath } slog.Debug("registering controller " + fullPath) - allMiddlewares := append(s.middlewares, route.Middlewares...) - s.Mux.Handle(fullPath, withMiddlewares(route.Handler, allMiddlewares...)) + route.Middlewares = append(s.middlewares, route.Middlewares...) + s.Mux.Handle(fullPath, withMiddlewares(route.Handler, route.Middlewares...)) if s.DisableOpenapi || route.Hidden || route.Method == "" { return &route } - route.Path = s.basePath + route.Path - err := route.RegisterOpenAPIOperation(s.OpenAPI) if err != nil { slog.Warn("error documenting openapi operation", "error", err) } - if route.FullName == "" { - route.FullName = route.Path - } - - if route.Operation.Summary == "" { - route.Operation.Summary = route.NameFromNamespace(camelToHuman) - } - - route.Operation.Description = "controller: `" + route.FullName + "`\n\n---\n\n" + route.Operation.Description - - if route.Operation.OperationID == "" { - route.Operation.OperationID = route.Method + "_" + strings.ReplaceAll(strings.ReplaceAll(route.Path, "{", ":"), "}", "") - } - return &route } @@ -180,7 +178,7 @@ func registerFuegoController[T, B any, Contexted ctx[B]](s *Server, method, path Path: path, Params: make(map[string]OpenAPIParam), FullName: FuncName(controller), - Operation: openapi3.NewOperation(), + Operation: &openapi3.Operation{}, OpenAPI: s.OpenAPI, } @@ -199,8 +197,10 @@ func registerStdController(s *Server, method, path string, controller func(http. route := BaseRoute{ Method: method, Path: path, + Params: make(map[string]OpenAPIParam), FullName: FuncName(controller), - Operation: openapi3.NewOperation(), + Operation: &openapi3.Operation{}, + Handler: http.HandlerFunc(controller), OpenAPI: s.OpenAPI, } @@ -253,3 +253,24 @@ func camelToHuman(s string) string { } return result.String() } + +// DefaultDescription returns a default .md description for a controller +func DefaultDescription[T any](handler string, middlewares []T) string { + description := "#### Controller: \n\n`" + + handler + "`" + + if len(middlewares) > 0 { + description += "\n\n#### Middlewares:\n" + + for i, fn := range middlewares { + description += "\n- `" + FuncName(fn) + "`" + + if i == 4 { + description += "\n- more middleware..." + break + } + } + } + + return description + "\n\n---\n\n" +} diff --git a/mux_test.go b/mux_test.go index 0d73a66e..cbd719f3 100644 --- a/mux_test.go +++ b/mux_test.go @@ -402,21 +402,21 @@ func TestRegister(t *testing.T) { Operation: &openapi3.Operation{ Tags: []string{"my-tag"}, Summary: "my-summary", - Description: "my-description", + Description: "my-description\n", OperationID: "my-operation-id", }, }, }, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {}), OptionOperationID("new-operation-id"), OptionSummary("new-summary"), - OptionDescription("new-description"), + OptionOverrideDescription("new-description"), OptionTags("new-tag"), ) require.NotNil(t, route) require.Equal(t, []string{"my-tag", "new-tag"}, route.Operation.Tags) require.Equal(t, "new-summary", route.Operation.Summary) - require.Equal(t, "controller: `/test`\n\n---\n\nnew-description", route.Operation.Description) + require.Equal(t, "new-description", route.Operation.Description) require.Equal(t, "new-operation-id", route.Operation.OperationID) }) } diff --git a/openapi.go b/openapi.go index 83cbd280..7611efa5 100644 --- a/openapi.go +++ b/openapi.go @@ -89,6 +89,11 @@ func declareAllTagsFromOperations(s *Server) { } } } + + // Make sure tags are sorted + slices.SortFunc(s.OpenAPI.Description().Tags, func(a, b *openapi3.Tag) int { + return strings.Compare(a.Name, b.Name) + }) } // OutputOpenAPISpec takes the OpenAPI spec and outputs it to a JSON file and/or serves it on a URL. @@ -209,6 +214,20 @@ func RegisterOpenAPIOperation[T, B any](openapi *OpenAPI, route Route[T, B]) (*o route.Operation = openapi3.NewOperation() } + if route.FullName == "" { + route.FullName = route.Path + } + + route.GenerateDefaultDescription() + + if route.Operation.Summary == "" { + route.Operation.Summary = route.NameFromNamespace(camelToHuman) + } + + if route.Operation.OperationID == "" { + route.GenerateDefaultOperationID() + } + // Request Body if route.Operation.RequestBody == nil { bodyTag := SchemaTagFromType(openapi, *new(B)) @@ -263,7 +282,7 @@ func RegisterOpenAPIOperation[T, B any](openapi *OpenAPI, route Route[T, B]) (*o for _, params := range route.Operation.Parameters { if params.Value.In == "path" { if !strings.Contains(route.Path, "{"+params.Value.Name) { - return nil, fmt.Errorf("path parameter '%s' is not declared in the path", params.Value.Name) + panic(fmt.Errorf("path parameter '%s' is not declared in the path", params.Value.Name)) } } } diff --git a/openapi_operations_test.go b/openapi_operations_test.go index c03e129f..ec88d614 100644 --- a/openapi_operations_test.go +++ b/openapi_operations_test.go @@ -16,7 +16,7 @@ func TestTags(t *testing.T) { ) require.Equal(t, []string{"my-tag"}, route.Operation.Tags) - require.Equal(t, "controller: `github.com/go-fuego/fuego.testController`\n\n---\n\nmy description", route.Operation.Description) + require.Equal(t, "#### Controller: \n\n`github.com/go-fuego/fuego.testController`\n\n---\n\nmy description", route.Operation.Description) require.Equal(t, "my summary", route.Operation.Summary) require.Equal(t, true, route.Operation.Deprecated) } diff --git a/option.go b/option.go index 28e51258..5695968e 100644 --- a/option.go +++ b/option.go @@ -258,10 +258,10 @@ func OptionSummary(summary string) func(*BaseRoute) { } } -// Description sets the description to the route. +// Description adds a description to the route. // By default, the description is set by Fuego with some info, // like the controller function name and the package name. -// If you want to add a description, please use [AddDescription] instead. +// If you want to override Fuego's description, please use [OptionOverrideDescription] instead. func OptionDescription(description string) func(*BaseRoute) { return func(r *BaseRoute) { r.Operation.Description = description @@ -273,7 +273,17 @@ func OptionDescription(description string) func(*BaseRoute) { // like the controller function name and the package name. func OptionAddDescription(description string) func(*BaseRoute) { return func(r *BaseRoute) { - r.Operation.Description += "\n\n" + description + r.Operation.Description += description + } +} + +// OptionOverrideDescription overrides the default description set by Fuego. +// By default, the description is set by Fuego with some info, +// like the controller function name and the package name. +func OptionOverrideDescription(description string) func(*BaseRoute) { + return func(r *BaseRoute) { + r.overrideDescription = true + r.Operation.Description = description } } diff --git a/option/option.go b/option/option.go index c3ade403..3dd1db8e 100644 --- a/option/option.go +++ b/option/option.go @@ -105,8 +105,15 @@ var Description = fuego.OptionDescription // AddDescription adds a description to the route. // By default, the description is set by Fuego with some info, // like the controller function name and the package name. +// +// Deprecated: Use [Description] instead. var AddDescription = fuego.OptionAddDescription +// OverrideDescription overrides the default description set by Fuego. +// By default, the description is set by Fuego with some info, +// like the controller function name and the package name. +var OverrideDescription = fuego.OptionOverrideDescription + // Security configures security requirements to the route. // // Single Scheme (AND Logic): diff --git a/option_test.go b/option_test.go index 382becde..fecd57df 100644 --- a/option_test.go +++ b/option_test.go @@ -11,6 +11,7 @@ import ( "github.com/thejerf/slogassert" "github.com/go-fuego/fuego" + "github.com/go-fuego/fuego/option" "github.com/go-fuego/fuego/param" ) @@ -239,7 +240,7 @@ func TestOpenAPI(t *testing.T) { ) require.Equal(t, "test summary", route.Operation.Summary) - require.Equal(t, "controller: `github.com/go-fuego/fuego_test.helloWorld`\n\n---\n\ntest description", route.Operation.Description) + require.Equal(t, "#### Controller: \n\n`github.com/go-fuego/fuego_test.helloWorld`\n\n---\n\ntest description", route.Operation.Description) require.Equal(t, []string{"first-tag", "second-tag"}, route.Operation.Tags) require.True(t, route.Operation.Deprecated) }) @@ -778,16 +779,56 @@ func TestSecurity(t *testing.T) { }) } -func TestOptionAddDescription(t *testing.T) { - t.Run("Declare a description for the route with multiple descriptions", func(t *testing.T) { +func TestOptionDescription(t *testing.T) { + t.Run("Declare a description for the route", func(t *testing.T) { s := fuego.NewServer() route := fuego.Get(s, "/test", helloWorld, - fuego.OptionDescription("test description"), - fuego.OptionAddDescription("another description"), + option.Description("test description"), + ) + + require.Equal(t, "#### Controller: \n\n`github.com/go-fuego/fuego_test.helloWorld`\n\n---\n\ntest description", route.Operation.Description) + }) + + t.Run("Override Fuego's description for the route", func(t *testing.T) { + s := fuego.NewServer() + + route := fuego.Get(s, "/test", helloWorld, + option.OverrideDescription("another description"), + ) + + require.Equal(t, "another description", route.Operation.Description) + }) + + t.Run("Add description to the route, route middleware is included", func(t *testing.T) { + s := fuego.NewServer() + + route := fuego.Get(s, "/test", helloWorld, + option.Middleware(dummyMiddleware), + option.Description("another description"), + ) + + require.Equal(t, "#### Controller: \n\n`github.com/go-fuego/fuego_test.helloWorld`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego_test.dummyMiddleware`\n\n---\n\nanother description", route.Operation.Description) + }) + + t.Run("Add description to the route, route middleware is included", func(t *testing.T) { + s := fuego.NewServer() + + fuego.Use(s, dummyMiddleware) + + group := fuego.Group(s, "/group", option.Middleware(dummyMiddleware)) + + fuego.Use(group, dummyMiddleware) + + route := fuego.Get(s, "/test", helloWorld, + option.Middleware(dummyMiddleware), + option.Description("another description"), + option.Middleware(dummyMiddleware), // After the description + option.Middleware(dummyMiddleware), // 6th middleware + option.Middleware(dummyMiddleware), // 7th middleware, should not be included ) - require.Equal(t, "controller: `github.com/go-fuego/fuego_test.helloWorld`\n\n---\n\ntest description\n\nanother description", route.Operation.Description) + require.Equal(t, "#### Controller: \n\n`github.com/go-fuego/fuego_test.helloWorld`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego_test.dummyMiddleware`\n- `github.com/go-fuego/fuego_test.dummyMiddleware`\n- `github.com/go-fuego/fuego_test.dummyMiddleware`\n- `github.com/go-fuego/fuego_test.dummyMiddleware`\n- `github.com/go-fuego/fuego_test.dummyMiddleware`\n- more middleware...\n\n---\n\nanother description", route.Operation.Description) }) } From f0da94ddb4a802da519b0b46c9bfe72de0dc9c7a Mon Sep 17 00:00:00 2001 From: rizerkrof <34008166+rizerkrof@users.noreply.github.com> Date: Mon, 16 Dec 2024 23:10:34 +0100 Subject: [PATCH 075/138] chore: add precise fuego cli build path to git ignore --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 6bc00644..0226c18e 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,4 @@ coverage.out recipe.db bin go.work.sum -fuego \ No newline at end of file +/cmd/fuego/fuego \ No newline at end of file From 4091c3752e3395a2f0e282db443519c884df4108 Mon Sep 17 00:00:00 2001 From: rizerkrof <34008166+rizerkrof@users.noreply.github.com> Date: Mon, 16 Dec 2024 23:10:40 +0100 Subject: [PATCH 076/138] refactor(cli): change template entity keys --- cmd/fuego/commands/controller.go | 18 +++--- cmd/fuego/templates/controller/controller.go | 64 ++++++++++---------- 2 files changed, 41 insertions(+), 41 deletions(-) diff --git a/cmd/fuego/commands/controller.go b/cmd/fuego/commands/controller.go index 82c03b7c..02617b68 100644 --- a/cmd/fuego/commands/controller.go +++ b/cmd/fuego/commands/controller.go @@ -18,26 +18,26 @@ func Controller() *cli.Command { Usage: "creates a new controller file", Aliases: []string{"c"}, Action: func(cCtx *cli.Context) error { - controllerName := cCtx.Args().First() + entityName := cCtx.Args().First() - if controllerName == "" { - controllerName = "newController" + if entityName == "" { + entityName = "newEntity" fmt.Println("Note: You can add a controller name as an argument. Example: `fuego controller books`") } - _, err := createController(controllerName) + _, err := createController(entityName) if err != nil { return err } - fmt.Printf("🔥 Controller %s created successfully\n", controllerName) + fmt.Printf("🔥 Controller %s created successfully\n", entityName) return nil }, } } // createController creates a new controller file -func createController(controllerName string) (string, error) { +func createController(entityName string) (string, error) { controllerDir := "./controller/" if _, err := os.Stat(controllerDir); os.IsNotExist(err) { err = os.Mkdir(controllerDir, 0o755) @@ -54,10 +54,10 @@ func createController(controllerName string) (string, error) { t := language.English titler := cases.Title(t) - newContent := strings.ReplaceAll(string(templateContent), "newController", controllerName) - newContent = strings.ReplaceAll(newContent, "NewController", titler.String(controllerName)) + newContent := strings.ReplaceAll(string(templateContent), "newEntity", entityName) + newContent = strings.ReplaceAll(newContent, "NewEntity", titler.String(entityName)) - controllerPath := fmt.Sprintf("%s%s.go", controllerDir, controllerName) + controllerPath := fmt.Sprintf("%s%s.go", controllerDir, entityName) err = os.WriteFile(controllerPath, []byte(newContent), 0o644) if err != nil { diff --git a/cmd/fuego/templates/controller/controller.go b/cmd/fuego/templates/controller/controller.go index 9c636818..1f8b1ab7 100644 --- a/cmd/fuego/templates/controller/controller.go +++ b/cmd/fuego/templates/controller/controller.go @@ -4,83 +4,83 @@ import ( "github.com/go-fuego/fuego" ) -type NewControllerResources struct { +type NewEntityResources struct { // TODO add resources - NewControllerService NewControllerService + NewEntityService NewEntityService } -type NewController struct { +type NewEntity struct { ID string `json:"id"` Name string `json:"name"` } -type NewControllerCreate struct { +type NewEntityCreate struct { Name string `json:"name"` } -type NewControllerUpdate struct { +type NewEntityUpdate struct { Name string `json:"name"` } -func (rs NewControllerResources) Routes(s *fuego.Server) { - newControllerGroup := fuego.Group(s, "/newController") +func (rs NewEntityResources) Routes(s *fuego.Server) { + newEntityGroup := fuego.Group(s, "/newEntity") - fuego.Get(newControllerGroup, "/", rs.getAllNewController) - fuego.Post(newControllerGroup, "/", rs.postNewController) + fuego.Get(newEntityGroup, "/", rs.getAllNewEntity) + fuego.Post(newEntityGroup, "/", rs.postNewEntity) - fuego.Get(newControllerGroup, "/{id}", rs.getNewController) - fuego.Put(newControllerGroup, "/{id}", rs.putNewController) - fuego.Delete(newControllerGroup, "/{id}", rs.deleteNewController) + fuego.Get(newEntityGroup, "/{id}", rs.getNewEntity) + fuego.Put(newEntityGroup, "/{id}", rs.putNewEntity) + fuego.Delete(newEntityGroup, "/{id}", rs.deleteNewEntity) } -func (rs NewControllerResources) getAllNewController(c fuego.ContextNoBody) ([]NewController, error) { - return rs.NewControllerService.GetAllNewController() +func (rs NewEntityResources) getAllNewEntity(c fuego.ContextNoBody) ([]NewEntity, error) { + return rs.NewEntityService.GetAllNewEntity() } -func (rs NewControllerResources) postNewController(c *fuego.ContextWithBody[NewControllerCreate]) (NewController, error) { +func (rs NewEntityResources) postNewEntity(c *fuego.ContextWithBody[NewEntityCreate]) (NewEntity, error) { body, err := c.Body() if err != nil { - return NewController{}, err + return NewEntity{}, err } - new, err := rs.NewControllerService.CreateNewController(body) + new, err := rs.NewEntityService.CreateNewEntity(body) if err != nil { - return NewController{}, err + return NewEntity{}, err } return new, nil } -func (rs NewControllerResources) getNewController(c fuego.ContextNoBody) (NewController, error) { +func (rs NewEntityResources) getNewEntity(c fuego.ContextNoBody) (NewEntity, error) { id := c.PathParam("id") - return rs.NewControllerService.GetNewController(id) + return rs.NewEntityService.GetNewEntity(id) } -func (rs NewControllerResources) putNewController(c *fuego.ContextWithBody[NewControllerUpdate]) (NewController, error) { +func (rs NewEntityResources) putNewEntity(c *fuego.ContextWithBody[NewEntityUpdate]) (NewEntity, error) { id := c.PathParam("id") body, err := c.Body() if err != nil { - return NewController{}, err + return NewEntity{}, err } - new, err := rs.NewControllerService.UpdateNewController(id, body) + new, err := rs.NewEntityService.UpdateNewEntity(id, body) if err != nil { - return NewController{}, err + return NewEntity{}, err } return new, nil } -func (rs NewControllerResources) deleteNewController(c *fuego.ContextNoBody) (any, error) { - return rs.NewControllerService.DeleteNewController(c.PathParam("id")) +func (rs NewEntityResources) deleteNewEntity(c *fuego.ContextNoBody) (any, error) { + return rs.NewEntityService.DeleteNewEntity(c.PathParam("id")) } -type NewControllerService interface { - GetNewController(id string) (NewController, error) - CreateNewController(NewControllerCreate) (NewController, error) - GetAllNewController() ([]NewController, error) - UpdateNewController(id string, input NewControllerUpdate) (NewController, error) - DeleteNewController(id string) (any, error) +type NewEntityService interface { + GetNewEntity(id string) (NewEntity, error) + CreateNewEntity(NewEntityCreate) (NewEntity, error) + GetAllNewEntity() ([]NewEntity, error) + UpdateNewEntity(id string, input NewEntityUpdate) (NewEntity, error) + DeleteNewEntity(id string) (any, error) } From 2214f8e4a31816b4ae30180392187811451a5ab8 Mon Sep 17 00:00:00 2001 From: rizerkrof <34008166+rizerkrof@users.noreply.github.com> Date: Mon, 16 Dec 2024 23:45:58 +0100 Subject: [PATCH 077/138] refactor(cli): split controller and entity files --- cmd/fuego/commands/controller.go | 13 ++++++++---- cmd/fuego/commands/controller_test.go | 2 +- cmd/fuego/templates/controller/controller.go | 21 ------------------- cmd/fuego/templates/controller/entity.go | 22 ++++++++++++++++++++ 4 files changed, 32 insertions(+), 26 deletions(-) create mode 100644 cmd/fuego/templates/controller/entity.go diff --git a/cmd/fuego/commands/controller.go b/cmd/fuego/commands/controller.go index 02617b68..d500b764 100644 --- a/cmd/fuego/commands/controller.go +++ b/cmd/fuego/commands/controller.go @@ -25,7 +25,12 @@ func Controller() *cli.Command { fmt.Println("Note: You can add a controller name as an argument. Example: `fuego controller books`") } - _, err := createController(entityName) + _, err := createControllerFile(entityName, "entity.go", entityName+".go") + if err != nil { + return err + } + + _, err = createControllerFile(entityName, "controller.go", entityName+"Controller.go") if err != nil { return err } @@ -37,7 +42,7 @@ func Controller() *cli.Command { } // createController creates a new controller file -func createController(entityName string) (string, error) { +func createControllerFile(entityName, controllerTemplateFileName, outputFileName string) (string, error) { controllerDir := "./controller/" if _, err := os.Stat(controllerDir); os.IsNotExist(err) { err = os.Mkdir(controllerDir, 0o755) @@ -46,7 +51,7 @@ func createController(entityName string) (string, error) { } } - templateContent, err := templates.FS.ReadFile("controller/controller.go") + templateContent, err := templates.FS.ReadFile("controller/" + controllerTemplateFileName) if err != nil { return "", err } @@ -57,7 +62,7 @@ func createController(entityName string) (string, error) { newContent := strings.ReplaceAll(string(templateContent), "newEntity", entityName) newContent = strings.ReplaceAll(newContent, "NewEntity", titler.String(entityName)) - controllerPath := fmt.Sprintf("%s%s.go", controllerDir, entityName) + controllerPath := fmt.Sprintf("%s%s", controllerDir, outputFileName) err = os.WriteFile(controllerPath, []byte(newContent), 0o644) if err != nil { diff --git a/cmd/fuego/commands/controller_test.go b/cmd/fuego/commands/controller_test.go index 111d9423..70653e45 100644 --- a/cmd/fuego/commands/controller_test.go +++ b/cmd/fuego/commands/controller_test.go @@ -8,7 +8,7 @@ import ( ) func TestCreateController(t *testing.T) { - res, err := createController("books") + res, err := createControllerFile("books", "controller.go", "booksController.go") require.NoError(t, err) require.Contains(t, res, "package controller") require.Contains(t, res, `fuego.Get(booksGroup, "/{id}", rs.getBooks)`) diff --git a/cmd/fuego/templates/controller/controller.go b/cmd/fuego/templates/controller/controller.go index 1f8b1ab7..f51db68e 100644 --- a/cmd/fuego/templates/controller/controller.go +++ b/cmd/fuego/templates/controller/controller.go @@ -9,19 +9,6 @@ type NewEntityResources struct { NewEntityService NewEntityService } -type NewEntity struct { - ID string `json:"id"` - Name string `json:"name"` -} - -type NewEntityCreate struct { - Name string `json:"name"` -} - -type NewEntityUpdate struct { - Name string `json:"name"` -} - func (rs NewEntityResources) Routes(s *fuego.Server) { newEntityGroup := fuego.Group(s, "/newEntity") @@ -76,11 +63,3 @@ func (rs NewEntityResources) putNewEntity(c *fuego.ContextWithBody[NewEntityUpda func (rs NewEntityResources) deleteNewEntity(c *fuego.ContextNoBody) (any, error) { return rs.NewEntityService.DeleteNewEntity(c.PathParam("id")) } - -type NewEntityService interface { - GetNewEntity(id string) (NewEntity, error) - CreateNewEntity(NewEntityCreate) (NewEntity, error) - GetAllNewEntity() ([]NewEntity, error) - UpdateNewEntity(id string, input NewEntityUpdate) (NewEntity, error) - DeleteNewEntity(id string) (any, error) -} diff --git a/cmd/fuego/templates/controller/entity.go b/cmd/fuego/templates/controller/entity.go new file mode 100644 index 00000000..8ece824a --- /dev/null +++ b/cmd/fuego/templates/controller/entity.go @@ -0,0 +1,22 @@ +package controller + +type NewEntity struct { + ID string `json:"id"` + Name string `json:"name"` +} + +type NewEntityCreate struct { + Name string `json:"name"` +} + +type NewEntityUpdate struct { + Name string `json:"name"` +} + +type NewEntityService interface { + GetNewEntity(id string) (NewEntity, error) + CreateNewEntity(NewEntityCreate) (NewEntity, error) + GetAllNewEntity() ([]NewEntity, error) + UpdateNewEntity(id string, input NewEntityUpdate) (NewEntity, error) + DeleteNewEntity(id string) (any, error) +} From dd3ae714de717adbcefc5b8aebc32813a43531c7 Mon Sep 17 00:00:00 2001 From: rizerkrof <34008166+rizerkrof@users.noreply.github.com> Date: Tue, 17 Dec 2024 00:07:18 +0100 Subject: [PATCH 078/138] feat(cli): generate controller using ddd pattern --- cmd/fuego/commands/controller.go | 12 ++++++------ cmd/fuego/commands/controller_test.go | 2 +- .../{controller => newEntity}/controller.go | 2 +- .../templates/{controller => newEntity}/entity.go | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) rename cmd/fuego/templates/{controller => newEntity}/controller.go (98%) rename cmd/fuego/templates/{controller => newEntity}/entity.go (96%) diff --git a/cmd/fuego/commands/controller.go b/cmd/fuego/commands/controller.go index d500b764..36d11123 100644 --- a/cmd/fuego/commands/controller.go +++ b/cmd/fuego/commands/controller.go @@ -25,12 +25,12 @@ func Controller() *cli.Command { fmt.Println("Note: You can add a controller name as an argument. Example: `fuego controller books`") } - _, err := createControllerFile(entityName, "entity.go", entityName+".go") + _, err := createNewEntityDomainFile(entityName, "entity.go", entityName+".go") if err != nil { return err } - _, err = createControllerFile(entityName, "controller.go", entityName+"Controller.go") + _, err = createNewEntityDomainFile(entityName, "controller.go", entityName+"Controller.go") if err != nil { return err } @@ -42,16 +42,16 @@ func Controller() *cli.Command { } // createController creates a new controller file -func createControllerFile(entityName, controllerTemplateFileName, outputFileName string) (string, error) { - controllerDir := "./controller/" +func createNewEntityDomainFile(entityName, controllerTemplateFileName, outputFileName string) (string, error) { + controllerDir := "./domains/" + entityName + "/" if _, err := os.Stat(controllerDir); os.IsNotExist(err) { - err = os.Mkdir(controllerDir, 0o755) + err = os.MkdirAll(controllerDir, 0o755) if err != nil { return "", err } } - templateContent, err := templates.FS.ReadFile("controller/" + controllerTemplateFileName) + templateContent, err := templates.FS.ReadFile("newEntity/" + controllerTemplateFileName) if err != nil { return "", err } diff --git a/cmd/fuego/commands/controller_test.go b/cmd/fuego/commands/controller_test.go index 70653e45..fc30dc5d 100644 --- a/cmd/fuego/commands/controller_test.go +++ b/cmd/fuego/commands/controller_test.go @@ -8,7 +8,7 @@ import ( ) func TestCreateController(t *testing.T) { - res, err := createControllerFile("books", "controller.go", "booksController.go") + res, err := createNewEntityDomainFile("books", "controller.go", "booksController.go") require.NoError(t, err) require.Contains(t, res, "package controller") require.Contains(t, res, `fuego.Get(booksGroup, "/{id}", rs.getBooks)`) diff --git a/cmd/fuego/templates/controller/controller.go b/cmd/fuego/templates/newEntity/controller.go similarity index 98% rename from cmd/fuego/templates/controller/controller.go rename to cmd/fuego/templates/newEntity/controller.go index f51db68e..cc187a9e 100644 --- a/cmd/fuego/templates/controller/controller.go +++ b/cmd/fuego/templates/newEntity/controller.go @@ -1,4 +1,4 @@ -package controller +package newEntity import ( "github.com/go-fuego/fuego" diff --git a/cmd/fuego/templates/controller/entity.go b/cmd/fuego/templates/newEntity/entity.go similarity index 96% rename from cmd/fuego/templates/controller/entity.go rename to cmd/fuego/templates/newEntity/entity.go index 8ece824a..cdba5176 100644 --- a/cmd/fuego/templates/controller/entity.go +++ b/cmd/fuego/templates/newEntity/entity.go @@ -1,4 +1,4 @@ -package controller +package newEntity type NewEntity struct { ID string `json:"id"` From 92d75cf46d5cb6b3e4d8328436c966569ceac2e0 Mon Sep 17 00:00:00 2001 From: rizerkrof <34008166+rizerkrof@users.noreply.github.com> Date: Tue, 17 Dec 2024 00:13:11 +0100 Subject: [PATCH 079/138] feat(cli): add service generation --- cmd/fuego/commands/service.go | 38 ++++++++++ cmd/fuego/main.go | 1 + cmd/fuego/templates/newEntity/service.go | 90 ++++++++++++++++++++++++ 3 files changed, 129 insertions(+) create mode 100644 cmd/fuego/commands/service.go create mode 100644 cmd/fuego/templates/newEntity/service.go diff --git a/cmd/fuego/commands/service.go b/cmd/fuego/commands/service.go new file mode 100644 index 00000000..c1133cbc --- /dev/null +++ b/cmd/fuego/commands/service.go @@ -0,0 +1,38 @@ +package commands + +import ( + "fmt" + + "github.com/urfave/cli/v2" +) + +func Service() *cli.Command { + return &cli.Command{ + Name: "service", + Usage: "creates a new service file", + Aliases: []string{"s"}, + Action: serviceCommandAction, + } +} + +func serviceCommandAction(cCtx *cli.Context) error { + entityName := cCtx.Args().First() + + if entityName == "" { + entityName = "newController" + fmt.Println("Note: You can add an entity name as an argument. Example: `fuego service books`") + } + + _, err := createNewEntityDomainFile(entityName, "entity.go", entityName+".go") + if err != nil { + return err + } + + _, err = createNewEntityDomainFile(entityName, "service.go", entityName+"Service.go") + if err != nil { + return err + } + + fmt.Printf("🔥 Service %s created successfully\n", entityName) + return nil +} diff --git a/cmd/fuego/main.go b/cmd/fuego/main.go index d40c7ada..2e0ef6a2 100644 --- a/cmd/fuego/main.go +++ b/cmd/fuego/main.go @@ -20,6 +20,7 @@ func main() { }, Commands: []*cli.Command{ commands.Controller(), + commands.Service(), }, } diff --git a/cmd/fuego/templates/newEntity/service.go b/cmd/fuego/templates/newEntity/service.go new file mode 100644 index 00000000..3a2047fb --- /dev/null +++ b/cmd/fuego/templates/newEntity/service.go @@ -0,0 +1,90 @@ +package newEntity + +import ( + "fmt" + "sync" + "time" + + "github.com/go-fuego/fuego" +) + +type NewEntityServiceImpl struct { + newEntityRepository map[string]NewEntity + mu sync.RWMutex +} + +var _ NewEntityService = &NewEntityServiceImpl{} + +func NewNewEntityService() NewEntityService { + return &NewEntityServiceImpl{ + newEntityRepository: make(map[string]NewEntity), + } +} + +func (bs *NewEntityServiceImpl) GetNewEntity(id string) (NewEntity, error) { + bs.mu.RLock() + defer bs.mu.RUnlock() + + newEntity, exists := bs.newEntityRepository[id] + if !exists { + return NewEntity{}, fuego.NotFoundError{Title: "NewEntity not found with id " + id} + } + + return newEntity, nil +} + +func (bs *NewEntityServiceImpl) CreateNewEntity(input NewEntityCreate) (NewEntity, error) { + bs.mu.Lock() + defer bs.mu.Unlock() + + id := fmt.Sprintf("%d", time.Now().UnixNano()) + newEntity := NewEntity{ + ID: id, + Name: input.Name, + } + + bs.newEntityRepository[id] = newEntity + return newEntity, nil +} + +func (bs *NewEntityServiceImpl) GetAllNewEntity() ([]NewEntity, error) { + bs.mu.RLock() + defer bs.mu.RUnlock() + + allNewEntity := make([]NewEntity, 0, len(bs.newEntityRepository)) + for _, newEntity := range bs.newEntityRepository { + allNewEntity = append(allNewEntity, newEntity) + } + + return allNewEntity, nil +} + +func (bs *NewEntityServiceImpl) UpdateNewEntity(id string, input NewEntityUpdate) (NewEntity, error) { + bs.mu.Lock() + defer bs.mu.Unlock() + + newEntity, exists := bs.newEntityRepository[id] + if !exists { + return NewEntity{}, fuego.NotFoundError{Title: "NewEntity not found with id " + id} + } + + if input.Name != "" { + newEntity.Name = input.Name + } + + bs.newEntityRepository[id] = newEntity + return newEntity, nil +} + +func (bs *NewEntityServiceImpl) DeleteNewEntity(id string) (any, error) { + bs.mu.Lock() + defer bs.mu.Unlock() + + _, exists := bs.newEntityRepository[id] + if !exists { + return nil, fuego.NotFoundError{Title: "NewEntity not found with id " + id} + } + + delete(bs.newEntityRepository, id) + return "deleted", nil +} From 99346b7ea3412d9be04245280eb4d0e5e0e81cfe Mon Sep 17 00:00:00 2001 From: rizerkrof <34008166+rizerkrof@users.noreply.github.com> Date: Tue, 17 Dec 2024 00:21:59 +0100 Subject: [PATCH 080/138] feat(cli): add --with-service flag to generate service and controller --- cmd/fuego/commands/controller.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/cmd/fuego/commands/controller.go b/cmd/fuego/commands/controller.go index 36d11123..b4819467 100644 --- a/cmd/fuego/commands/controller.go +++ b/cmd/fuego/commands/controller.go @@ -38,6 +38,20 @@ func Controller() *cli.Command { fmt.Printf("🔥 Controller %s created successfully\n", entityName) return nil }, + Flags: []cli.Flag{ + &cli.BoolFlag{ + Name: "with-service", + Usage: "enable service file generation", + Value: false, + Action: func(cCtx *cli.Context, shouldGenerateServiceFile bool) error { + if !shouldGenerateServiceFile { + return nil + } + + return serviceCommandAction(cCtx) + }, + }, + }, } } From 5d13e871b0ec060e098c1300f76db090a05fb9d8 Mon Sep 17 00:00:00 2001 From: rizerkrof <34008166+rizerkrof@users.noreply.github.com> Date: Sat, 7 Dec 2024 13:27:32 +0100 Subject: [PATCH 081/138] docs(cli): reference new flag in crud generation doc --- documentation/docs/tutorials/02-crud.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/documentation/docs/tutorials/02-crud.md b/documentation/docs/tutorials/02-crud.md index 74c7b202..b76a36a9 100644 --- a/documentation/docs/tutorials/02-crud.md +++ b/documentation/docs/tutorials/02-crud.md @@ -14,7 +14,13 @@ fuego controller books go run github.com/go-fuego/fuego/cmd/fuego@latest controller books ``` -This generates a controller and a service for the `books` resource. +This generates a controller for the `books` resource. + +:::tip + +Use `fuego controller --with-service books` to generate a simple map based in memory service so you can pass it to the controller resources to quickly interact with your new book entity! + +::: You then have to implement the service interface in the controller to be able to play with data. It's a form of **dependency injection** that we chose to use From fa4c2ab7c42ba930a701d3673900e72b6aae985d Mon Sep 17 00:00:00 2001 From: Ewen Quimerc'h <46993939+EwenQuim@users.noreply.github.com> Date: Tue, 17 Dec 2024 12:00:07 +0100 Subject: [PATCH 082/138] Refactor, mutualize and document Route object (#279) --- .../lib/testdata/doc/openapi.golden.json | 78 ++++++++--------- mux.go | 62 +------------- route.go | 85 +++++++++++++++++++ server_test.go | 20 ++--- 4 files changed, 138 insertions(+), 107 deletions(-) create mode 100644 route.go diff --git a/examples/petstore/lib/testdata/doc/openapi.golden.json b/examples/petstore/lib/testdata/doc/openapi.golden.json index 167c6f2e..44431594 100644 --- a/examples/petstore/lib/testdata/doc/openapi.golden.json +++ b/examples/petstore/lib/testdata/doc/openapi.golden.json @@ -155,13 +155,6 @@ "description": "#### Controller: \n\n`github.com/go-fuego/fuego/examples/petstore/controllers.PetsResources.filterPets`\n\n---\n\nFilter pets", "operationId": "GET_/pets/", "parameters": [ - { - "in": "header", - "name": "Accept", - "schema": { - "type": "string" - } - }, { "description": "header description", "in": "header", @@ -221,6 +214,13 @@ "default": 3, "type": "integer" } + }, + { + "in": "header", + "name": "Accept", + "schema": { + "type": "string" + } } ], "responses": { @@ -306,16 +306,16 @@ "operationId": "POST_/pets/", "parameters": [ { + "description": "header description", "in": "header", - "name": "Accept", + "name": "X-Header", "schema": { "type": "string" } }, { - "description": "header description", "in": "header", - "name": "X-Header", + "name": "Accept", "schema": { "type": "string" } @@ -398,13 +398,6 @@ "description": "#### Controller: \n\n`github.com/go-fuego/fuego/examples/petstore/controllers.PetsResources.getAllPets`\n\n---\n\nGet all pets", "operationId": "GET_/pets/all", "parameters": [ - { - "in": "header", - "name": "Accept", - "schema": { - "type": "string" - } - }, { "description": "header description", "in": "header", @@ -441,6 +434,13 @@ "default": 1, "type": "integer" } + }, + { + "in": "header", + "name": "Accept", + "schema": { + "type": "string" + } } ], "responses": { @@ -529,16 +529,16 @@ "operationId": "GET_/pets/by-age", "parameters": [ { + "description": "header description", "in": "header", - "name": "Accept", + "name": "X-Header", "schema": { "type": "string" } }, { - "description": "header description", "in": "header", - "name": "X-Header", + "name": "Accept", "schema": { "type": "string" } @@ -608,16 +608,16 @@ "operationId": "GET_/pets/by-name/:name...", "parameters": [ { + "description": "header description", "in": "header", - "name": "Accept", + "name": "X-Header", "schema": { "type": "string" } }, { - "description": "header description", "in": "header", - "name": "X-Header", + "name": "Accept", "schema": { "type": "string" } @@ -743,16 +743,16 @@ "operationId": "DELETE_/pets/:id", "parameters": [ { + "description": "header description", "in": "header", - "name": "Accept", + "name": "X-Header", "schema": { "type": "string" } }, { - "description": "header description", "in": "header", - "name": "X-Header", + "name": "Accept", "schema": { "type": "string" } @@ -815,13 +815,6 @@ "description": "Replace description with this sentence.", "operationId": "getPet", "parameters": [ - { - "in": "header", - "name": "Accept", - "schema": { - "type": "string" - } - }, { "description": "header description", "in": "header", @@ -843,6 +836,13 @@ "schema": { "type": "string" } + }, + { + "in": "header", + "name": "Accept", + "schema": { + "type": "string" + } } ], "responses": { @@ -895,16 +895,16 @@ "operationId": "PUT_/pets/:id", "parameters": [ { + "description": "header description", "in": "header", - "name": "Accept", + "name": "X-Header", "schema": { "type": "string" } }, { - "description": "header description", "in": "header", - "name": "X-Header", + "name": "Accept", "schema": { "type": "string" } @@ -981,16 +981,16 @@ "operationId": "PUT_/pets/:id/json", "parameters": [ { + "description": "header description", "in": "header", - "name": "Accept", + "name": "X-Header", "schema": { "type": "string" } }, { - "description": "header description", "in": "header", - "name": "X-Header", + "name": "Accept", "schema": { "type": "string" } diff --git a/mux.go b/mux.go index 7b348708..18b4f642 100644 --- a/mux.go +++ b/mux.go @@ -44,37 +44,6 @@ func Group(s *Server, path string, routeOptions ...func(*BaseRoute)) *Server { return newServer } -type Route[ResponseBody any, RequestBody any] struct { - BaseRoute -} - -type BaseRoute struct { - Operation *openapi3.Operation // GENERATED OpenAPI operation, do not set manually in Register function. You can change it after the route is registered. - Method string // HTTP method (GET, POST, PUT, PATCH, DELETE) - Path string // URL path. Will be prefixed by the base path of the server and the group path if any - Handler http.Handler // handler executed for this route - FullName string // namespace and name of the function to execute - Params map[string]OpenAPIParam - Middlewares []func(http.Handler) http.Handler - AcceptedContentTypes []string // Content types accepted for the request body. If nil, all content types (*/*) are accepted. - Hidden bool // If true, the route will not be documented in the OpenAPI spec - DefaultStatusCode int // Default status code for the response - OpenAPI *OpenAPI // Ref to the whole OpenAPI spec - - overrideDescription bool // Override the default description -} - -func (r *BaseRoute) GenerateDefaultDescription() { - if r.overrideDescription { - return - } - r.Operation.Description = DefaultDescription(r.FullName, r.Middlewares) + r.Operation.Description -} - -func (r *BaseRoute) GenerateDefaultOperationID() { - r.Operation.OperationID = r.Method + "_" + strings.ReplaceAll(strings.ReplaceAll(r.Path, "{", ":"), "}", "") -} - // Capture all methods (GET, POST, PUT, PATCH, DELETE) and register a controller. func All[ReturnType, Body any, Contexted ctx[Body]](s *Server, path string, controller func(Contexted) (ReturnType, error), options ...func(*BaseRoute)) *Route[ReturnType, Body] { return registerFuegoController(s, "", path, controller, options...) @@ -173,42 +142,19 @@ func PatchStd(s *Server, path string, controller func(http.ResponseWriter, *http } func registerFuegoController[T, B any, Contexted ctx[B]](s *Server, method, path string, controller func(Contexted) (T, error), options ...func(*BaseRoute)) *Route[T, B] { - route := BaseRoute{ - Method: method, - Path: path, - Params: make(map[string]OpenAPIParam), - FullName: FuncName(controller), - Operation: &openapi3.Operation{}, - OpenAPI: s.OpenAPI, - } + route := NewRoute[T, B](method, path, controller, s.OpenAPI, append(s.routeOptions, options...)...) acceptHeaderParameter := openapi3.NewHeaderParameter("Accept") acceptHeaderParameter.Schema = openapi3.NewStringSchema().NewRef() route.Operation.AddParameter(acceptHeaderParameter) - for _, o := range append(s.routeOptions, options...) { - o(&route) - } - - return Register(s, Route[T, B]{BaseRoute: route}, HTTPHandler(s, controller, &route)) + return Register(s, route, HTTPHandler(s, controller, &route.BaseRoute)) } func registerStdController(s *Server, method, path string, controller func(http.ResponseWriter, *http.Request), options ...func(*BaseRoute)) *Route[any, any] { - route := BaseRoute{ - Method: method, - Path: path, - Params: make(map[string]OpenAPIParam), - FullName: FuncName(controller), - Operation: &openapi3.Operation{}, - Handler: http.HandlerFunc(controller), - OpenAPI: s.OpenAPI, - } - - for _, o := range append(s.routeOptions, options...) { - o(&route) - } + route := NewRoute[any, any](method, path, controller, s.OpenAPI, append(s.routeOptions, options...)...) - return Register(s, Route[any, any]{BaseRoute: route}, http.HandlerFunc(controller)) + return Register(s, route, http.HandlerFunc(controller)) } func withMiddlewares(controller http.Handler, middlewares ...func(http.Handler) http.Handler) http.Handler { diff --git a/route.go b/route.go new file mode 100644 index 00000000..b891ccb8 --- /dev/null +++ b/route.go @@ -0,0 +1,85 @@ +package fuego + +import ( + "net/http" + "strings" + + "github.com/getkin/kin-openapi/openapi3" +) + +func NewRoute[T, B any](method, path string, handler any, openapi *OpenAPI, options ...func(*BaseRoute)) Route[T, B] { + return Route[T, B]{ + BaseRoute: NewBaseRoute(method, path, handler, openapi, options...), + } +} + +// Route is the main struct for a route in Fuego. +// It contains the OpenAPI operation and other metadata. +// It is a wrapper around BaseRoute, with the addition of the response and request body types. +type Route[ResponseBody any, RequestBody any] struct { + BaseRoute +} + +func NewBaseRoute(method, path string, handler any, openapi *OpenAPI, options ...func(*BaseRoute)) BaseRoute { + baseRoute := BaseRoute{ + Method: method, + Path: path, + Params: make(map[string]OpenAPIParam), + FullName: FuncName(handler), + Operation: openapi3.NewOperation(), + OpenAPI: openapi, + } + + for _, o := range options { + o(&baseRoute) + } + + return baseRoute +} + +// BaseRoute is the base struct for all routes in Fuego. +// It contains the OpenAPI operation and other metadata. +type BaseRoute struct { + // OpenAPI operation + Operation *openapi3.Operation + + // HTTP method (GET, POST, PUT, PATCH, DELETE) + Method string + + // URL path. Will be prefixed by the base path of the server and the group path if any + Path string + + // handler executed for this route + Handler http.Handler + + // namespace and name of the function to execute + FullName string + Params map[string]OpenAPIParam + Middlewares []func(http.Handler) http.Handler + + // Content types accepted for the request body. If nil, all content types (*/*) are accepted. + AcceptedContentTypes []string + + // If true, the route will not be documented in the OpenAPI spec + Hidden bool + + // Default status code for the response + DefaultStatusCode int + + // Ref to the whole OpenAPI spec. Be careful when changing directly its value directly. + OpenAPI *OpenAPI + + // Override the default description + overrideDescription bool +} + +func (r *BaseRoute) GenerateDefaultDescription() { + if r.overrideDescription { + return + } + r.Operation.Description = DefaultDescription(r.FullName, r.Middlewares) + r.Operation.Description +} + +func (r *BaseRoute) GenerateDefaultOperationID() { + r.Operation.OperationID = r.Method + "_" + strings.ReplaceAll(strings.ReplaceAll(r.Path, "{", ":"), "}", "") +} diff --git a/server_test.go b/server_test.go index 671cfc5e..bcaa08e3 100644 --- a/server_test.go +++ b/server_test.go @@ -378,10 +378,10 @@ func TestGroupParams(t *testing.T) { t.Log(document.Paths.Find("/").Get.Parameters[0].Value.Name) require.Len(t, document.Paths.Find("/").Get.Parameters, 1) require.Equal(t, document.Paths.Find("/").Get.Parameters[0].Value.Name, "Accept") - require.Equal(t, document.Paths.Find("/api/test").Get.Parameters[0].Value.Name, "Accept") - require.Equal(t, document.Paths.Find("/api/test").Get.Parameters[1].Value.Name, "X-Test-Header") - require.Equal(t, document.Paths.Find("/api/test2").Get.Parameters[0].Value.Name, "Accept") - require.Equal(t, document.Paths.Find("/api/test2").Get.Parameters[1].Value.Name, "X-Test-Header") + require.Equal(t, document.Paths.Find("/api/test").Get.Parameters[1].Value.Name, "Accept") + require.Equal(t, document.Paths.Find("/api/test").Get.Parameters[0].Value.Name, "X-Test-Header") + require.Equal(t, document.Paths.Find("/api/test2").Get.Parameters[1].Value.Name, "Accept") + require.Equal(t, document.Paths.Find("/api/test2").Get.Parameters[0].Value.Name, "X-Test-Header") } func TestGroupHeaderParams(t *testing.T) { @@ -395,8 +395,8 @@ func TestGroupHeaderParams(t *testing.T) { require.Equal(t, "test-value", route.Operation.Parameters.GetByInAndName("header", "X-Test-Header").Description) document := s.OutputOpenAPISpec() - require.Equal(t, document.Paths.Find("/api/test").Get.Parameters[0].Value.Name, "Accept") - require.Equal(t, document.Paths.Find("/api/test").Get.Parameters[1].Value.Name, "X-Test-Header") + require.Equal(t, document.Paths.Find("/api/test").Get.Parameters[1].Value.Name, "Accept") + require.Equal(t, document.Paths.Find("/api/test").Get.Parameters[0].Value.Name, "X-Test-Header") } func TestGroupCookieParams(t *testing.T) { @@ -410,8 +410,8 @@ func TestGroupCookieParams(t *testing.T) { require.Equal(t, "test-value", route.Operation.Parameters.GetByInAndName("cookie", "X-Test-Cookie").Description) document := s.OutputOpenAPISpec() - require.Equal(t, document.Paths.Find("/api/test").Get.Parameters[0].Value.Name, "Accept") - require.Equal(t, document.Paths.Find("/api/test").Get.Parameters[1].Value.Name, "X-Test-Cookie") + require.Equal(t, document.Paths.Find("/api/test").Get.Parameters[1].Value.Name, "Accept") + require.Equal(t, document.Paths.Find("/api/test").Get.Parameters[0].Value.Name, "X-Test-Cookie") } func TestGroupQueryParam(t *testing.T) { @@ -425,8 +425,8 @@ func TestGroupQueryParam(t *testing.T) { require.Equal(t, "test-value", route.Operation.Parameters.GetByInAndName("query", "X-Test-Query").Description) document := s.OutputOpenAPISpec() - require.Equal(t, document.Paths.Find("/api/test").Get.Parameters[0].Value.Name, "Accept") - require.Equal(t, document.Paths.Find("/api/test").Get.Parameters[1].Value.Name, "X-Test-Query") + require.Equal(t, document.Paths.Find("/api/test").Get.Parameters[1].Value.Name, "Accept") + require.Equal(t, document.Paths.Find("/api/test").Get.Parameters[0].Value.Name, "X-Test-Query") } func TestGroupParamsInChildGroup(t *testing.T) { From a0eba330166a05aa007d9f8fbb991cb7b00bd7d1 Mon Sep 17 00:00:00 2001 From: EwenQuim Date: Tue, 17 Dec 2024 12:20:08 +0100 Subject: [PATCH 083/138] Fixed OptionOverrideDescription documentation --- option.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/option.go b/option.go index 5695968e..faa76009 100644 --- a/option.go +++ b/option.go @@ -258,10 +258,9 @@ func OptionSummary(summary string) func(*BaseRoute) { } } -// Description adds a description to the route. +// OptionOverrideDescription overrides the default description set by Fuego. // By default, the description is set by Fuego with some info, // like the controller function name and the package name. -// If you want to override Fuego's description, please use [OptionOverrideDescription] instead. func OptionDescription(description string) func(*BaseRoute) { return func(r *BaseRoute) { r.Operation.Description = description From 637569669d996a5ed51ea34544a10737d45009de Mon Sep 17 00:00:00 2001 From: rizerkrof <34008166+rizerkrof@users.noreply.github.com> Date: Tue, 17 Dec 2024 18:14:36 +0100 Subject: [PATCH 084/138] refactor(cli): simplify return in generated controller func --- cmd/fuego/templates/newEntity/controller.go | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/cmd/fuego/templates/newEntity/controller.go b/cmd/fuego/templates/newEntity/controller.go index cc187a9e..39bf42d9 100644 --- a/cmd/fuego/templates/newEntity/controller.go +++ b/cmd/fuego/templates/newEntity/controller.go @@ -30,12 +30,7 @@ func (rs NewEntityResources) postNewEntity(c *fuego.ContextWithBody[NewEntityCre return NewEntity{}, err } - new, err := rs.NewEntityService.CreateNewEntity(body) - if err != nil { - return NewEntity{}, err - } - - return new, nil + return rs.NewEntityService.CreateNewEntity(body) } func (rs NewEntityResources) getNewEntity(c fuego.ContextNoBody) (NewEntity, error) { @@ -52,12 +47,7 @@ func (rs NewEntityResources) putNewEntity(c *fuego.ContextWithBody[NewEntityUpda return NewEntity{}, err } - new, err := rs.NewEntityService.UpdateNewEntity(id, body) - if err != nil { - return NewEntity{}, err - } - - return new, nil + return rs.NewEntityService.UpdateNewEntity(id, body) } func (rs NewEntityResources) deleteNewEntity(c *fuego.ContextNoBody) (any, error) { From b559a5a0e07c80eb16011da97869b230ff4d9c30 Mon Sep 17 00:00:00 2001 From: dylanhitt Date: Fri, 13 Dec 2024 22:58:06 -0500 Subject: [PATCH 085/138] BREAKING: update WithGlobalResponseType to take --- examples/full-app-gourmet/server/server.go | 2 +- examples/petstore/lib/server.go | 9 + .../lib/testdata/doc/openapi.golden.json | 253 ++++++++++++++++++ examples/petstore/main.go | 4 +- openapi.go | 12 +- openapi_operations.go | 36 +-- openapi_operations_test.go | 117 ++++++-- option.go | 21 +- server.go | 14 +- 9 files changed, 406 insertions(+), 62 deletions(-) diff --git a/examples/full-app-gourmet/server/server.go b/examples/full-app-gourmet/server/server.go index abdf2b82..cf9b8219 100644 --- a/examples/full-app-gourmet/server/server.go +++ b/examples/full-app-gourmet/server/server.go @@ -33,7 +33,7 @@ func (rs Resources) Setup( fuego.WithAutoAuth(controller.LoginFunc), fuego.WithTemplateFS(templates.FS), fuego.WithTemplateGlobs("**/*.html", "**/**/*.html"), - fuego.WithGlobalResponseTypes(http.StatusForbidden, "Forbidden"), + fuego.WithGlobalResponseTypes(http.StatusForbidden, "Forbidden", fuego.Response{Type: fuego.HTTPError{}}), } options = append(serverOptions, options...) diff --git a/examples/petstore/lib/server.go b/examples/petstore/lib/server.go index 7cfcc545..fcd75461 100644 --- a/examples/petstore/lib/server.go +++ b/examples/petstore/lib/server.go @@ -1,12 +1,21 @@ package lib import ( + "net/http" + "github.com/go-fuego/fuego" controller "github.com/go-fuego/fuego/examples/petstore/controllers" "github.com/go-fuego/fuego/examples/petstore/services" ) +type NoContent struct { + Empty string `json:"-"` +} + func NewPetStoreServer(options ...func(*fuego.Server)) *fuego.Server { + options = append(options, fuego.WithGlobalResponseTypes( + http.StatusNoContent, "No Content", fuego.Response{Type: NoContent{}}, + )) s := fuego.NewServer(options...) petsResources := controller.PetsResources{ diff --git a/examples/petstore/lib/testdata/doc/openapi.golden.json b/examples/petstore/lib/testdata/doc/openapi.golden.json index 44431594..b7b0bf7a 100644 --- a/examples/petstore/lib/testdata/doc/openapi.golden.json +++ b/examples/petstore/lib/testdata/doc/openapi.golden.json @@ -51,6 +51,9 @@ }, "type": "object" }, + "NoContent": { + "description": "NoContent schema" + }, "Pets": { "description": "Pets schema", "properties": { @@ -257,6 +260,21 @@ } } }, + "204": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NoContent" + } + }, + "application/xml": { + "schema": { + "$ref": "#/components/schemas/NoContent" + } + } + }, + "description": "No Content" + }, "206": { "description": "OK", "headers": { @@ -278,6 +296,11 @@ "schema": { "$ref": "#/components/schemas/HTTPError" } + }, + "application/xml": { + "schema": { + "$ref": "#/components/schemas/HTTPError" + } } }, "description": "Bad Request _(validation or deserialization error)_" @@ -288,6 +311,11 @@ "schema": { "$ref": "#/components/schemas/HTTPError" } + }, + "application/xml": { + "schema": { + "$ref": "#/components/schemas/HTTPError" + } } }, "description": "Internal Server Error _(panics)_" @@ -348,12 +376,32 @@ }, "description": "Created" }, + "204": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NoContent" + } + }, + "application/xml": { + "schema": { + "$ref": "#/components/schemas/NoContent" + } + } + }, + "description": "No Content" + }, "400": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPError" } + }, + "application/xml": { + "schema": { + "$ref": "#/components/schemas/HTTPError" + } } }, "description": "Bad Request _(validation or deserialization error)_" @@ -379,6 +427,11 @@ "schema": { "$ref": "#/components/schemas/HTTPError" } + }, + "application/xml": { + "schema": { + "$ref": "#/components/schemas/HTTPError" + } } }, "description": "Internal Server Error _(panics)_" @@ -477,6 +530,21 @@ } } }, + "204": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NoContent" + } + }, + "application/xml": { + "schema": { + "$ref": "#/components/schemas/NoContent" + } + } + }, + "description": "No Content" + }, "206": { "description": "OK", "headers": { @@ -498,6 +566,11 @@ "schema": { "$ref": "#/components/schemas/HTTPError" } + }, + "application/xml": { + "schema": { + "$ref": "#/components/schemas/HTTPError" + } } }, "description": "Bad Request _(validation or deserialization error)_" @@ -508,6 +581,11 @@ "schema": { "$ref": "#/components/schemas/HTTPError" } + }, + "application/xml": { + "schema": { + "$ref": "#/components/schemas/HTTPError" + } } }, "description": "Internal Server Error _(panics)_" @@ -572,12 +650,32 @@ }, "description": "OK" }, + "204": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NoContent" + } + }, + "application/xml": { + "schema": { + "$ref": "#/components/schemas/NoContent" + } + } + }, + "description": "No Content" + }, "400": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPError" } + }, + "application/xml": { + "schema": { + "$ref": "#/components/schemas/HTTPError" + } } }, "description": "Bad Request _(validation or deserialization error)_" @@ -588,6 +686,11 @@ "schema": { "$ref": "#/components/schemas/HTTPError" } + }, + "application/xml": { + "schema": { + "$ref": "#/components/schemas/HTTPError" + } } }, "description": "Internal Server Error _(panics)_" @@ -648,12 +751,32 @@ }, "description": "OK" }, + "204": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NoContent" + } + }, + "application/xml": { + "schema": { + "$ref": "#/components/schemas/NoContent" + } + } + }, + "description": "No Content" + }, "400": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPError" } + }, + "application/xml": { + "schema": { + "$ref": "#/components/schemas/HTTPError" + } } }, "description": "Bad Request _(validation or deserialization error)_" @@ -664,6 +787,11 @@ "schema": { "$ref": "#/components/schemas/HTTPError" } + }, + "application/xml": { + "schema": { + "$ref": "#/components/schemas/HTTPError" + } } }, "description": "Internal Server Error _(panics)_" @@ -706,12 +834,32 @@ }, "description": "all the pets" }, + "204": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NoContent" + } + }, + "application/xml": { + "schema": { + "$ref": "#/components/schemas/NoContent" + } + } + }, + "description": "No Content" + }, "400": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPError" } + }, + "application/xml": { + "schema": { + "$ref": "#/components/schemas/HTTPError" + } } }, "description": "Bad Request _(validation or deserialization error)_" @@ -722,6 +870,11 @@ "schema": { "$ref": "#/components/schemas/HTTPError" } + }, + "application/xml": { + "schema": { + "$ref": "#/components/schemas/HTTPError" + } } }, "description": "Internal Server Error _(panics)_" @@ -782,12 +935,32 @@ }, "description": "OK" }, + "204": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NoContent" + } + }, + "application/xml": { + "schema": { + "$ref": "#/components/schemas/NoContent" + } + } + }, + "description": "No Content" + }, "400": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPError" } + }, + "application/xml": { + "schema": { + "$ref": "#/components/schemas/HTTPError" + } } }, "description": "Bad Request _(validation or deserialization error)_" @@ -798,6 +971,11 @@ "schema": { "$ref": "#/components/schemas/HTTPError" } + }, + "application/xml": { + "schema": { + "$ref": "#/components/schemas/HTTPError" + } } }, "description": "Internal Server Error _(panics)_" @@ -861,12 +1039,32 @@ }, "description": "OK" }, + "204": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NoContent" + } + }, + "application/xml": { + "schema": { + "$ref": "#/components/schemas/NoContent" + } + } + }, + "description": "No Content" + }, "400": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPError" } + }, + "application/xml": { + "schema": { + "$ref": "#/components/schemas/HTTPError" + } } }, "description": "Bad Request _(validation or deserialization error)_" @@ -877,6 +1075,11 @@ "schema": { "$ref": "#/components/schemas/HTTPError" } + }, + "application/xml": { + "schema": { + "$ref": "#/components/schemas/HTTPError" + } } }, "description": "Internal Server Error _(panics)_" @@ -945,12 +1148,32 @@ }, "description": "OK" }, + "204": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NoContent" + } + }, + "application/xml": { + "schema": { + "$ref": "#/components/schemas/NoContent" + } + } + }, + "description": "No Content" + }, "400": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPError" } + }, + "application/xml": { + "schema": { + "$ref": "#/components/schemas/HTTPError" + } } }, "description": "Bad Request _(validation or deserialization error)_" @@ -961,6 +1184,11 @@ "schema": { "$ref": "#/components/schemas/HTTPError" } + }, + "application/xml": { + "schema": { + "$ref": "#/components/schemas/HTTPError" + } } }, "description": "Internal Server Error _(panics)_" @@ -1031,12 +1259,32 @@ }, "description": "OK" }, + "204": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NoContent" + } + }, + "application/xml": { + "schema": { + "$ref": "#/components/schemas/NoContent" + } + } + }, + "description": "No Content" + }, "400": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPError" } + }, + "application/xml": { + "schema": { + "$ref": "#/components/schemas/HTTPError" + } } }, "description": "Bad Request _(validation or deserialization error)_" @@ -1047,6 +1295,11 @@ "schema": { "$ref": "#/components/schemas/HTTPError" } + }, + "application/xml": { + "schema": { + "$ref": "#/components/schemas/HTTPError" + } } }, "description": "Internal Server Error _(panics)_" diff --git a/examples/petstore/main.go b/examples/petstore/main.go index 0cfb1405..152d23e8 100644 --- a/examples/petstore/main.go +++ b/examples/petstore/main.go @@ -1,6 +1,8 @@ package main -import "github.com/go-fuego/fuego/examples/petstore/lib" +import ( + "github.com/go-fuego/fuego/examples/petstore/lib" +) func main() { err := lib.NewPetStoreServer().Run() diff --git a/openapi.go b/openapi.go index 7611efa5..5f03249c 100644 --- a/openapi.go +++ b/openapi.go @@ -24,7 +24,7 @@ func NewOpenAPI() *OpenAPI { return &OpenAPI{ description: &desc, generator: openapi3gen.NewGenerator(), - globalOpenAPIResponses: []openAPIError{}, + globalOpenAPIResponses: []openAPIResponse{}, } } @@ -32,7 +32,7 @@ func NewOpenAPI() *OpenAPI { type OpenAPI struct { description *openapi3.T generator *openapi3gen.Generator - globalOpenAPIResponses []openAPIError + globalOpenAPIResponses []openAPIResponse } func (d *OpenAPI) Description() *openapi3.T { @@ -244,7 +244,13 @@ func RegisterOpenAPIOperation[T, B any](openapi *OpenAPI, route Route[T, B]) (*o // Response - globals for _, openAPIGlobalResponse := range openapi.globalOpenAPIResponses { - addResponseIfNotSet(openapi, route.Operation, openAPIGlobalResponse.Code, openAPIGlobalResponse.Description, openAPIGlobalResponse.ErrorType) + addResponseIfNotSet( + openapi, + route.Operation, + openAPIGlobalResponse.Code, + openAPIGlobalResponse.Description, + openAPIGlobalResponse.Response, + ) } // Automatically add non-declared 200 (or other) Response diff --git a/openapi_operations.go b/openapi_operations.go index e35380d6..77a4cc02 100644 --- a/openapi_operations.go +++ b/openapi_operations.go @@ -39,28 +39,32 @@ type OpenAPIParamOption struct { } // Registers a response for the route, only if error for this code is not already set. -func addResponseIfNotSet(openapi *OpenAPI, operation *openapi3.Operation, code int, description string, errorType ...any) { - var responseSchema SchemaTag - - if len(errorType) > 0 { - responseSchema = SchemaTagFromType(openapi, errorType[0]) - } else { - responseSchema = SchemaTagFromType(openapi, HTTPError{}) +func addResponseIfNotSet(openapi *OpenAPI, operation *openapi3.Operation, code int, description string, response Response) { + if operation.Responses.Value(strconv.Itoa(code)) != nil { + return } - content := openapi3.NewContentWithSchemaRef(&responseSchema.SchemaRef, []string{"application/json"}) + operation.AddResponse(code, openapi.buildOpenapi3Response(description, response)) +} - if operation.Responses.Value(strconv.Itoa(code)) == nil { - response := openapi3.NewResponse(). - WithDescription(description). - WithContent(content) +func (o *OpenAPI) buildOpenapi3Response(description string, response Response) *openapi3.Response { + if response.Type == nil { + panic("Type in Response cannot be nil") + } - operation.AddResponse(code, response) + responseSchema := SchemaTagFromType(o, response.Type) + if len(response.ContentTypes) == 0 { + response.ContentTypes = []string{"application/json", "application/xml"} } + + content := openapi3.NewContentWithSchemaRef(&responseSchema.SchemaRef, response.ContentTypes) + return openapi3.NewResponse(). + WithDescription(description). + WithContent(content) } -// openAPIError describes a response error in the OpenAPI spec. -type openAPIError struct { +// openAPIResponse describes a response error in the OpenAPI spec. +type openAPIResponse struct { + Response Code int Description string - ErrorType any } diff --git a/openapi_operations_test.go b/openapi_operations_test.go index ec88d614..c023909a 100644 --- a/openapi_operations_test.go +++ b/openapi_operations_test.go @@ -1,6 +1,7 @@ package fuego import ( + "net/http" "testing" "github.com/stretchr/testify/require" @@ -61,32 +62,110 @@ func TestCustomError(t *testing.T) { require.Equal(t, "My Validation Error", *route.Operation.Responses.Map()["400"].Value.Description) } -func TestCustomErrorGlobalAndOnRoute(t *testing.T) { - type MyGlobalError struct { +func TestWithGlobalResponseType(t *testing.T) { + type MyGlobalResponse struct { Message string } - s := NewServer( - WithGlobalResponseTypes(400, "My Global Error", MyGlobalError{}), - WithGlobalResponseTypes(501, "Another Global Error", MyGlobalError{}), - ) - - type MyLocalError struct { + type MyLocalResponse struct { Message string } + t.Run("base", func(t *testing.T) { + s := NewServer( + WithGlobalResponseTypes(http.StatusNotImplemented, "My Global Error", Response{Type: MyGlobalResponse{}}), + ) + routeGlobal := Get(s, "/test-global", testController) + require.Equal(t, "My Global Error", *routeGlobal.Operation.Responses.Value("501").Value.Description) + }) - routeGlobal := Get(s, "/test-global", testController) - routeCustom := Get(s, "/test-custom", testController, - OptionAddError(400, "My Local Error", MyLocalError{}), - OptionAddError(419, "My Local Teapot"), - ) + t.Run("base with custom contents", func(t *testing.T) { + s := NewServer( + WithGlobalResponseTypes(http.StatusNotImplemented, "My Global Error", Response{ + Type: MyGlobalResponse{}, + ContentTypes: []string{"application/x-yaml"}, + }), + ) + routeGlobal := Get(s, "/test-global", testController) + require.NotNil(t, routeGlobal.Operation.Responses.Value("501").Value.Content.Get("application/x-yaml")) + require.Nil(t, routeGlobal.Operation.Responses.Value("501").Value.Content.Get("application/xml")) + }) - require.Equal(t, "My Global Error", *routeGlobal.Operation.Responses.Value("400").Value.Description, "Overrides Fuego's default 400 error") - require.Equal(t, "Another Global Error", *routeGlobal.Operation.Responses.Value("501").Value.Description) + t.Run("errors with route overrides", func(t *testing.T) { + s := NewServer( + WithGlobalResponseTypes(http.StatusBadRequest, "My Global Error", Response{Type: MyGlobalResponse{}}), + WithGlobalResponseTypes(http.StatusNotImplemented, "Another Global Error", Response{Type: MyGlobalResponse{}}), + ) + + routeGlobal := Get(s, "/test-global", testController) + routeCustom := Get(s, "/test-custom", testController, + OptionAddResponse(http.StatusBadRequest, "My Local Error", Response{Type: MyLocalResponse{}}), + OptionAddError(http.StatusTeapot, "My Local Teapot", Response{Type: HTTPError{}}), + ) - require.Equal(t, "My Local Error", *routeCustom.Operation.Responses.Map()["400"].Value.Description, "Local error overrides global error") - require.Equal(t, "My Local Teapot", *routeCustom.Operation.Responses.Map()["419"].Value.Description) - require.Equal(t, "Internal Server Error _(panics)_", *routeCustom.Operation.Responses.Map()["500"].Value.Description, "Global error set by default by Fuego") - require.Equal(t, "Another Global Error", *routeCustom.Operation.Responses.Map()["501"].Value.Description, "Global error is still available") + require.Equal(t, "My Global Error", *routeGlobal.Operation.Responses.Value("400").Value.Description, "Overrides Fuego's default 400 error") + require.Equal(t, "Another Global Error", *routeGlobal.Operation.Responses.Value("501").Value.Description) + + require.Equal(t, "My Local Error", *routeCustom.Operation.Responses.Map()["400"].Value.Description, "Local error overrides global error") + require.Equal(t, "My Local Teapot", *routeCustom.Operation.Responses.Map()["418"].Value.Description) + require.Equal(t, "Internal Server Error _(panics)_", *routeCustom.Operation.Responses.Map()["500"].Value.Description, "Global error set by default by Fuego") + require.Equal(t, "Another Global Error", *routeCustom.Operation.Responses.Map()["501"].Value.Description, "Global error is still available") + }) + + t.Run("200 responses with overrides", func(t *testing.T) { + s := NewServer( + WithGlobalResponseTypes(http.StatusCreated, "A Global Response", Response{Type: MyGlobalResponse{}}), + WithGlobalResponseTypes(http.StatusAccepted, "My 202 response with content", Response{ + Type: MyGlobalResponse{}, ContentTypes: []string{"application/x-yaml"}, + }), + ) + + t.Run("routeGlobal", func(t *testing.T) { + routeGlobal := Get(s, "/test-global", testController) + require.Equal(t, + "#/components/schemas/ans", + routeGlobal.Operation.Responses.Value("200").Value.Content.Get("application/json").Schema.Ref, + ) + require.Equal(t, + "#/components/schemas/ans", + routeGlobal.Operation.Responses.Value("200").Value.Content.Get("application/xml").Schema.Ref, + ) + require.Equal(t, "A Global Response", *routeGlobal.Operation.Responses.Value("201").Value.Description) + require.Equal(t, "My 202 response with content", *routeGlobal.Operation.Responses.Value("202").Value.Description) + require.Equal(t, + "#/components/schemas/MyGlobalResponse", + routeGlobal.Operation.Responses.Value("202").Value.Content.Get("application/x-yaml").Schema.Ref, + ) + }) + + t.Run("routeCustom", func(t *testing.T) { + routeCustom := Get(s, "/test-custom", testController, + OptionAddResponse(http.StatusOK, "My Local Response", Response{Type: MyLocalResponse{}}), + OptionAddResponse(http.StatusNoContent, "My No Content", Response{Type: struct{}{}}), + ) + require.Equal(t, + "#/components/schemas/MyLocalResponse", + routeCustom.Operation.Responses.Value("200").Value.Content.Get("application/json").Schema.Ref, + ) + require.Equal(t, + "#/components/schemas/MyLocalResponse", + routeCustom.Operation.Responses.Value("200").Value.Content.Get("application/xml").Schema.Ref, + ) + require.Equal(t, "My No Content", *routeCustom.Operation.Responses.Value("204").Value.Description) + require.Equal(t, "My 202 response with content", *routeCustom.Operation.Responses.Value("202").Value.Description) + require.Equal(t, + "#/components/schemas/MyGlobalResponse", + routeCustom.Operation.Responses.Value("202").Value.Content.Get("application/x-yaml").Schema.Ref, + ) + }) + }) + + t.Run("should be fatal", func(t *testing.T) { + s := NewServer( + WithGlobalResponseTypes(http.StatusNotImplemented, "My Global Error", Response{}), + ) + require.Panics(t, func() { + Get(s, "/test-global", testController) + }) + }) } func TestCookieParams(t *testing.T) { diff --git a/option.go b/option.go index faa76009..b3b97cfc 100644 --- a/option.go +++ b/option.go @@ -343,26 +343,15 @@ type Response struct { // Required: Response.Type must be set // Optional: Response.ContentTypes will default to `application/json` and `application/xml` if not set func OptionAddResponse(code int, description string, response Response) func(*BaseRoute) { - var responseSchema SchemaTag return func(r *BaseRoute) { - if response.Type == nil { - panic("Type in Response cannot be nil") - } - - responseSchema = SchemaTagFromType(r.OpenAPI, response.Type) - if len(response.ContentTypes) == 0 { - response.ContentTypes = []string{"application/json", "application/xml"} - } - - content := openapi3.NewContentWithSchemaRef(&responseSchema.SchemaRef, response.ContentTypes) - response := openapi3.NewResponse(). - WithDescription(description). - WithContent(content) - if r.Operation.Responses == nil { r.Operation.Responses = openapi3.NewResponses() } - r.Operation.Responses.Set(strconv.Itoa(code), &openapi3.ResponseRef{Value: response}) + r.Operation.Responses.Set( + strconv.Itoa(code), &openapi3.ResponseRef{ + Value: r.OpenAPI.buildOpenapi3Response(description, response), + }, + ) } } diff --git a/server.go b/server.go index c791fc75..f5065456 100644 --- a/server.go +++ b/server.go @@ -127,8 +127,8 @@ func NewServer(options ...func(*Server)) *Server { // Options set if not provided options = append(options, - WithGlobalResponseTypes(http.StatusBadRequest, "Bad Request _(validation or deserialization error)_", HTTPError{}), - WithGlobalResponseTypes(http.StatusInternalServerError, "Internal Server Error _(panics)_", HTTPError{}), + WithGlobalResponseTypes(http.StatusBadRequest, "Bad Request _(validation or deserialization error)_", Response{Type: HTTPError{}}), + WithGlobalResponseTypes(http.StatusInternalServerError, "Internal Server Error _(panics)_", Response{Type: HTTPError{}}), ) for _, option := range options { @@ -195,18 +195,20 @@ func WithCorsMiddleware(corsMiddleware func(http.Handler) http.Handler) func(*Se } // WithGlobalResponseTypes adds default response types to the server. -// Useful for adding global error types. // For example: // // app := fuego.NewServer( // fuego.WithGlobalResponseTypes(400, "Bad Request _(validation or deserialization error)_", HTTPError{}), // fuego.WithGlobalResponseTypes(401, "Unauthorized _(authentication error)_", HTTPError{}), // fuego.WithGlobalResponseTypes(500, "Internal Server Error _(panics)_", HTTPError{}), +// fuego.WithGlobalResponseTypes(204, "No Content", Empty{}), // ) -func WithGlobalResponseTypes(code int, description string, errorType ...any) func(*Server) { - errorType = append(errorType, HTTPError{}) +func WithGlobalResponseTypes(code int, description string, response Response) func(*Server) { return func(c *Server) { - c.OpenAPI.globalOpenAPIResponses = append(c.OpenAPI.globalOpenAPIResponses, openAPIError{code, description, errorType[0]}) + c.OpenAPI.globalOpenAPIResponses = append( + c.OpenAPI.globalOpenAPIResponses, + openAPIResponse{Code: code, Description: description, Response: response}, + ) } } From ce91d5b91dfbb2668f9038568225a77dba2895c2 Mon Sep 17 00:00:00 2001 From: dylanhitt Date: Mon, 16 Dec 2024 13:42:10 -0500 Subject: [PATCH 086/138] fix: set default globalresponse types in default options --- server.go | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/server.go b/server.go index f5065456..901ac09a 100644 --- a/server.go +++ b/server.go @@ -122,14 +122,10 @@ func NewServer(options ...func(*Server)) *Server { WithSerializer(Send), WithErrorSerializer(SendError), WithErrorHandler(ErrorHandler), - } - options = append(defaultOptions[:], options...) - - // Options set if not provided - options = append(options, WithGlobalResponseTypes(http.StatusBadRequest, "Bad Request _(validation or deserialization error)_", Response{Type: HTTPError{}}), WithGlobalResponseTypes(http.StatusInternalServerError, "Internal Server Error _(panics)_", Response{Type: HTTPError{}}), - ) + } + options = append(defaultOptions[:], options...) for _, option := range options { option(s) @@ -205,10 +201,9 @@ func WithCorsMiddleware(corsMiddleware func(http.Handler) http.Handler) func(*Se // ) func WithGlobalResponseTypes(code int, description string, response Response) func(*Server) { return func(c *Server) { - c.OpenAPI.globalOpenAPIResponses = append( - c.OpenAPI.globalOpenAPIResponses, - openAPIResponse{Code: code, Description: description, Response: response}, - ) + WithRouteOptions( + OptionAddResponse(code, description, response), + )(c) } } From c2115623fc2ab6942eba59ddc6ff7233dd4fb23b Mon Sep 17 00:00:00 2001 From: dylanhitt Date: Mon, 16 Dec 2024 13:49:12 -0500 Subject: [PATCH 087/138] chore: use AddResponse over AddError in test --- openapi_operations_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openapi_operations_test.go b/openapi_operations_test.go index c023909a..c5711a6f 100644 --- a/openapi_operations_test.go +++ b/openapi_operations_test.go @@ -98,7 +98,7 @@ func TestWithGlobalResponseType(t *testing.T) { routeGlobal := Get(s, "/test-global", testController) routeCustom := Get(s, "/test-custom", testController, OptionAddResponse(http.StatusBadRequest, "My Local Error", Response{Type: MyLocalResponse{}}), - OptionAddError(http.StatusTeapot, "My Local Teapot", Response{Type: HTTPError{}}), + OptionAddResponse(http.StatusTeapot, "My Local Teapot", Response{Type: HTTPError{}}), ) require.Equal(t, "My Global Error", *routeGlobal.Operation.Responses.Value("400").Value.Description, "Overrides Fuego's default 400 error") From 03893c20ec274d1d987b8766ecd49b56400ee295 Mon Sep 17 00:00:00 2001 From: dylanhitt Date: Mon, 16 Dec 2024 13:53:41 -0500 Subject: [PATCH 088/138] chore: increase time eventually time on can run server --- serve_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/serve_test.go b/serve_test.go index 967c0199..209ab156 100644 --- a/serve_test.go +++ b/serve_test.go @@ -446,7 +446,7 @@ func TestServer_Run(t *testing.T) { s.Mux.ServeHTTP(w, req) return w.Body.String() == `OK` - }, 5*time.Millisecond, 500*time.Microsecond) + }, 5*time.Second, 500*time.Millisecond) }) } From 5150da1b46feaed24b20eba48e7a28aa2b6e74aa Mon Sep 17 00:00:00 2001 From: dylanhitt Date: Tue, 17 Dec 2024 14:55:48 -0500 Subject: [PATCH 089/138] chore: deprecate --- examples/petstore/lib/server.go | 5 +++-- server.go | 9 ++++++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/examples/petstore/lib/server.go b/examples/petstore/lib/server.go index fcd75461..4326afc3 100644 --- a/examples/petstore/lib/server.go +++ b/examples/petstore/lib/server.go @@ -6,6 +6,7 @@ import ( "github.com/go-fuego/fuego" controller "github.com/go-fuego/fuego/examples/petstore/controllers" "github.com/go-fuego/fuego/examples/petstore/services" + "github.com/go-fuego/fuego/option" ) type NoContent struct { @@ -13,8 +14,8 @@ type NoContent struct { } func NewPetStoreServer(options ...func(*fuego.Server)) *fuego.Server { - options = append(options, fuego.WithGlobalResponseTypes( - http.StatusNoContent, "No Content", fuego.Response{Type: NoContent{}}, + options = append(options, fuego.WithRouteOptions( + option.AddResponse(http.StatusNoContent, "No Content", fuego.Response{Type: NoContent{}}), )) s := fuego.NewServer(options...) diff --git a/server.go b/server.go index 901ac09a..8b979724 100644 --- a/server.go +++ b/server.go @@ -122,11 +122,12 @@ func NewServer(options ...func(*Server)) *Server { WithSerializer(Send), WithErrorSerializer(SendError), WithErrorHandler(ErrorHandler), - WithGlobalResponseTypes(http.StatusBadRequest, "Bad Request _(validation or deserialization error)_", Response{Type: HTTPError{}}), - WithGlobalResponseTypes(http.StatusInternalServerError, "Internal Server Error _(panics)_", Response{Type: HTTPError{}}), + WithRouteOptions( + OptionAddResponse(http.StatusBadRequest, "Bad Request _(validation or deserialization error)_", Response{Type: HTTPError{}}), + OptionAddResponse(http.StatusInternalServerError, "Internal Server Error _(panics)_", Response{Type: HTTPError{}}), + ), } options = append(defaultOptions[:], options...) - for _, option := range options { option(s) } @@ -199,6 +200,8 @@ func WithCorsMiddleware(corsMiddleware func(http.Handler) http.Handler) func(*Se // fuego.WithGlobalResponseTypes(500, "Internal Server Error _(panics)_", HTTPError{}), // fuego.WithGlobalResponseTypes(204, "No Content", Empty{}), // ) +// +// Deprecated: Please use [OptionAddResponse] with [WithRouteOptions] func WithGlobalResponseTypes(code int, description string, response Response) func(*Server) { return func(c *Server) { WithRouteOptions( From f9c9cd11d98244598ef267cd533210c19980d89f Mon Sep 17 00:00:00 2001 From: Ewen Quimerc'h <46993939+EwenQuim@users.noreply.github.com> Date: Wed, 18 Dec 2024 09:37:12 +0100 Subject: [PATCH 090/138] Set status code before returning when no data is sent from controller (#282) --- option_test.go | 39 +++++++++++++++++++++++++++++++++++++-- serve.go | 8 ++++---- 2 files changed, 41 insertions(+), 6 deletions(-) diff --git a/option_test.go b/option_test.go index fecd57df..5201b3eb 100644 --- a/option_test.go +++ b/option_test.go @@ -1,6 +1,7 @@ package fuego_test import ( + "errors" "log/slog" "net/http" "net/http/httptest" @@ -837,7 +838,7 @@ func TestDefaultStatusCode(t *testing.T) { s := fuego.NewServer() route := fuego.Post(s, "/test", helloWorld, - fuego.OptionDefaultStatusCode(201), + option.DefaultStatusCode(201), ) r := httptest.NewRequest(http.MethodPost, "/test", nil) @@ -858,7 +859,7 @@ func TestDefaultStatusCode(t *testing.T) { c.SetStatus(200) return "hello world", nil }, - fuego.OptionDefaultStatusCode(201), + option.DefaultStatusCode(201), ) r := httptest.NewRequest(http.MethodPost, "/test", nil) @@ -871,4 +872,38 @@ func TestDefaultStatusCode(t *testing.T) { require.Equal(t, 201, route.DefaultStatusCode, "default status code should not be changed") require.NotNil(t, route.Operation.Responses.Value("201").Value, "default status is still in the spec even if code is not used") }) + + t.Run("can return 204 when no data is being sent", func(t *testing.T) { + s := fuego.NewServer() + + fuego.Get(s, "/", func(_ fuego.ContextNoBody) (any, error) { + return nil, nil + }, + option.DefaultStatusCode(204), + ) + + r := httptest.NewRequest("GET", "/", nil) + w := httptest.NewRecorder() + + s.Mux.ServeHTTP(w, r) + + require.Equal(t, 204, w.Code) + }) + + t.Run("must return 500 when an error is being sent, even with no body", func(t *testing.T) { + s := fuego.NewServer() + + fuego.Get(s, "/", func(_ fuego.ContextNoBody) (any, error) { + return nil, errors.New("error") + }, + option.DefaultStatusCode(204), + ) + + r := httptest.NewRequest("GET", "/", nil) + w := httptest.NewRecorder() + + s.Mux.ServeHTTP(w, r) + + require.Equal(t, 500, w.Code) + }) } diff --git a/serve.go b/serve.go index 4354ddfe..c6a03979 100644 --- a/serve.go +++ b/serve.go @@ -139,14 +139,14 @@ func HTTPHandler[ReturnType, Body any, Contextable ctx[Body]](s *Server, control } w.Header().Add("Server-Timing", Timing{"controller", time.Since(timeController), ""}.String()) - if reflect.TypeOf(ans) == nil { - return - } - if route.DefaultStatusCode != 0 { w.WriteHeader(route.DefaultStatusCode) } + if reflect.TypeOf(ans) == nil { + return + } + // TRANSFORM OUT timeTransformOut := time.Now() ans, err = transformOut(r.Context(), ans) From 1fe64f2272a5b92a58cdeb89b137e0e50df949fa Mon Sep 17 00:00:00 2001 From: Ewen Quimerc'h <46993939+EwenQuim@users.noreply.github.com> Date: Wed, 18 Dec 2024 11:33:58 +0100 Subject: [PATCH 091/138] Removes unused generator field from the Server struct (#283) --- server.go | 7 ------- 1 file changed, 7 deletions(-) diff --git a/server.go b/server.go index 8b979724..221bc6e6 100644 --- a/server.go +++ b/server.go @@ -11,7 +11,6 @@ import ( "time" "github.com/getkin/kin-openapi/openapi3" - "github.com/getkin/kin-openapi/openapi3gen" "github.com/go-playground/validator/v10" "github.com/golang-jwt/jwt/v5" ) @@ -80,8 +79,6 @@ type Server struct { OpenAPIConfig OpenAPIConfig - openAPIGenerator *openapi3gen.Generator - isTLS bool } @@ -108,10 +105,6 @@ func NewServer(options ...func(*Server)) *Server { OpenAPIConfig: defaultOpenAPIConfig, - openAPIGenerator: openapi3gen.NewGenerator( - openapi3gen.UseAllExportedFields(), - ), - Security: NewSecurity(), } From 06c6de059d6a4c5f5d32e8df2b6faff6b5b68901 Mon Sep 17 00:00:00 2001 From: EwenQuim Date: Wed, 18 Dec 2024 18:56:43 +0100 Subject: [PATCH 092/138] Attach tags computing to the OpenAPI struct --- openapi.go | 49 +++++++++++++++++++++++++------------------------ 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/openapi.go b/openapi.go index 5f03249c..5bf95723 100644 --- a/openapi.go +++ b/openapi.go @@ -35,12 +35,32 @@ type OpenAPI struct { globalOpenAPIResponses []openAPIResponse } -func (d *OpenAPI) Description() *openapi3.T { - return d.description +func (openAPI *OpenAPI) Description() *openapi3.T { + return openAPI.description } -func (d *OpenAPI) Generator() *openapi3gen.Generator { - return d.generator +func (openAPI *OpenAPI) Generator() *openapi3gen.Generator { + return openAPI.generator +} + +// Compute the tags to declare at the root of the OpenAPI spec from the tags declared in the operations. +func (openAPI *OpenAPI) computeTags() { + for _, pathItem := range openAPI.Description().Paths.Map() { + for _, op := range pathItem.Operations() { + for _, tag := range op.Tags { + if openAPI.Description().Tags.Get(tag) == nil { + openAPI.Description().Tags = append(openAPI.Description().Tags, &openapi3.Tag{ + Name: tag, + }) + } + } + } + } + + // Make sure tags are sorted + slices.SortFunc(openAPI.Description().Tags, func(a, b *openapi3.Tag) int { + return strings.Compare(a.Name, b.Name) + }) } func NewOpenApiSpec() openapi3.T { @@ -77,25 +97,6 @@ func (s *Server) Show() *Server { return s } -func declareAllTagsFromOperations(s *Server) { - for _, pathItem := range s.OpenAPI.Description().Paths.Map() { - for _, op := range pathItem.Operations() { - for _, tag := range op.Tags { - if s.OpenAPI.Description().Tags.Get(tag) == nil { - s.OpenAPI.Description().Tags = append(s.OpenAPI.Description().Tags, &openapi3.Tag{ - Name: tag, - }) - } - } - } - } - - // Make sure tags are sorted - slices.SortFunc(s.OpenAPI.Description().Tags, func(a, b *openapi3.Tag) int { - return strings.Compare(a.Name, b.Name) - }) -} - // OutputOpenAPISpec takes the OpenAPI spec and outputs it to a JSON file and/or serves it on a URL. // Also serves a Swagger UI. // To modify its behavior, use the [WithOpenAPIConfig] option. @@ -105,7 +106,7 @@ func (s *Server) OutputOpenAPISpec() openapi3.T { Description: "local server", }) - declareAllTagsFromOperations(s) + s.OpenAPI.computeTags() // Validate err := s.OpenAPI.Description().Validate(context.Background()) From 16158a8011d5f6fd9ba27db7b3f22e6ff5728564 Mon Sep 17 00:00:00 2001 From: EwenQuim Date: Wed, 18 Dec 2024 23:01:28 +0100 Subject: [PATCH 093/138] BREAKING CHANGE: Remove pointer from ContextWithBody and ContextWithBody We're changing Fuego's signature from generic type constrained by the interface --- README.md | 4 +- cmd/fuego/commands/controller_test.go | 2 +- cmd/fuego/templates/newEntity/controller.go | 6 +- ctx.go | 120 +++++++++--------- ctx_test.go | 52 ++++---- documentation/docs/guides/controllers.md | 16 +-- documentation/docs/guides/serialization.md | 2 +- documentation/docs/tutorials/02-crud.md | 10 +- examples/basic/main.go | 2 +- examples/custom-errors/main.go | 2 +- .../full-app-gourmet/controller/dosing.go | 2 +- .../full-app-gourmet/controller/ingredient.go | 2 +- .../full-app-gourmet/controller/recipe.go | 2 +- examples/full-app-gourmet/controller/users.go | 2 +- .../views/admin.ingredient.go | 6 +- .../full-app-gourmet/views/admin.recipe.go | 10 +- examples/full-app-gourmet/views/recipe.go | 2 +- .../full-app-gourmet/views/recipe_test.go | 2 +- examples/petstore/controllers/pets.go | 6 +- .../lib/testdata/doc/openapi.golden.json | 2 +- html_test.go | 2 +- middleware/cache/cache_test.go | 2 +- mux.go | 14 +- mux_test.go | 56 ++++---- openapi_description.go | 4 +- openapi_test.go | 30 ++--- option_test.go | 16 +-- security.go | 4 +- serve.go | 61 +++------ serve_test.go | 74 ++++------- server.go | 2 +- server_test.go | 8 +- validate_params.go | 2 +- 33 files changed, 238 insertions(+), 289 deletions(-) diff --git a/README.md b/README.md index 6c3abd10..0ee30f35 100644 --- a/README.md +++ b/README.md @@ -110,7 +110,7 @@ func main() { s.Run() } -func myController(c *fuego.ContextWithBody[MyInput]) (MyOutput, error) { +func myController(c fuego.ContextWithBody[MyInput]) (MyOutput, error) { body, err := c.Body() if err != nil { return MyOutput{}, err @@ -257,7 +257,7 @@ func main() { fuego.Use(s, chiMiddleware.Compress(5, "text/html", "text/css")) // Fuego 🔥 handler with automatic OpenAPI generation, validation, (de)serialization and error handling - fuego.Post(s, "/", func(c *fuego.ContextWithBody[Received]) (MyResponse, error) { + fuego.Post(s, "/", func(c fuego.ContextWithBody[Received]) (MyResponse, error) { data, err := c.Body() if err != nil { return MyResponse{}, err diff --git a/cmd/fuego/commands/controller_test.go b/cmd/fuego/commands/controller_test.go index fc30dc5d..9cb4a575 100644 --- a/cmd/fuego/commands/controller_test.go +++ b/cmd/fuego/commands/controller_test.go @@ -12,7 +12,7 @@ func TestCreateController(t *testing.T) { require.NoError(t, err) require.Contains(t, res, "package controller") require.Contains(t, res, `fuego.Get(booksGroup, "/{id}", rs.getBooks)`) - require.Contains(t, res, `func (rs BooksResources) postBooks(c *fuego.ContextWithBody[BooksCreate]) (Books, error)`) + require.Contains(t, res, `func (rs BooksResources) postBooks(c fuego.ContextWithBody[BooksCreate]) (Books, error)`) require.FileExists(t, "./controller/books.go") os.Remove("./controller/books.go") } diff --git a/cmd/fuego/templates/newEntity/controller.go b/cmd/fuego/templates/newEntity/controller.go index 39bf42d9..c2fa7331 100644 --- a/cmd/fuego/templates/newEntity/controller.go +++ b/cmd/fuego/templates/newEntity/controller.go @@ -24,7 +24,7 @@ func (rs NewEntityResources) getAllNewEntity(c fuego.ContextNoBody) ([]NewEntity return rs.NewEntityService.GetAllNewEntity() } -func (rs NewEntityResources) postNewEntity(c *fuego.ContextWithBody[NewEntityCreate]) (NewEntity, error) { +func (rs NewEntityResources) postNewEntity(c fuego.ContextWithBody[NewEntityCreate]) (NewEntity, error) { body, err := c.Body() if err != nil { return NewEntity{}, err @@ -39,7 +39,7 @@ func (rs NewEntityResources) getNewEntity(c fuego.ContextNoBody) (NewEntity, err return rs.NewEntityService.GetNewEntity(id) } -func (rs NewEntityResources) putNewEntity(c *fuego.ContextWithBody[NewEntityUpdate]) (NewEntity, error) { +func (rs NewEntityResources) putNewEntity(c fuego.ContextWithBody[NewEntityUpdate]) (NewEntity, error) { id := c.PathParam("id") body, err := c.Body() @@ -50,6 +50,6 @@ func (rs NewEntityResources) putNewEntity(c *fuego.ContextWithBody[NewEntityUpda return rs.NewEntityService.UpdateNewEntity(id, body) } -func (rs NewEntityResources) deleteNewEntity(c *fuego.ContextNoBody) (any, error) { +func (rs NewEntityResources) deleteNewEntity(c fuego.ContextNoBody) (any, error) { return rs.NewEntityService.DeleteNewEntity(c.PathParam("id")) } diff --git a/ctx.go b/ctx.go index 63c1e90b..57e06a0c 100644 --- a/ctx.go +++ b/ctx.go @@ -18,10 +18,13 @@ const ( maxBodySize = 1048576 ) +type ContextNoBody = ContextWithBody[any] + // ctx is the context of the request. // It contains the request body, the path parameters, the query parameters, and the HTTP request. // Please do not use a pointer type as parameter. -type ctx[B any] interface { +type ContextWithBody[B any] interface { + context.Context // Body returns the body of the request. // If (*B) implements [InTransformer], it will be transformed after deserialization. // It caches the result, so it can be called multiple times. @@ -91,34 +94,44 @@ type ctx[B any] interface { Redirect(code int, url string) (any, error) } -// NewContext returns a new context. It is used internally by Fuego. You probably want to use Ctx[B] instead. -func NewContext[B any](w http.ResponseWriter, r *http.Request, options readOptions) *ContextWithBody[B] { - c := &ContextWithBody[B]{ - ContextNoBody: ContextNoBody{ - Res: w, - Req: r, - readOptions: readOptions{ - DisallowUnknownFields: options.DisallowUnknownFields, - MaxBodySize: options.MaxBodySize, - }, - urlValues: r.URL.Query(), - }, +// NewContextWithBody returns a new context. It is used internally by Fuego. You probably want to use Ctx[B] instead. +func NewContextWithBody[B any](w http.ResponseWriter, r *http.Request, options readOptions) ContextWithBody[B] { + c := &contextWithBodyImpl[B]{ + contextNoBodyImpl: NewContextNoBody(w, r, options), } return c } +func NewContextNoBody(w http.ResponseWriter, r *http.Request, options readOptions) contextNoBodyImpl { + c := contextNoBodyImpl{ + Res: w, + Req: r, + readOptions: readOptions{ + DisallowUnknownFields: options.DisallowUnknownFields, + MaxBodySize: options.MaxBodySize, + }, + urlValues: r.URL.Query(), + } + return c +} + // ContextWithBody is the same as fuego.ContextNoBody, but // has a Body. The Body type parameter represents the expected data type // from http.Request.Body. Please do not use a pointer as a type parameter. -type ContextWithBody[Body any] struct { +type contextWithBodyImpl[Body any] struct { body *Body // Cache the body in request context, because it is not possible to read an HTTP request body multiple times. - ContextNoBody + contextNoBodyImpl } +var ( + _ ContextWithBody[any] = &contextWithBodyImpl[any]{} // Check that ContextWithBody implements Ctx. + _ ContextWithBody[string] = &contextWithBodyImpl[string]{} // Check that ContextWithBody implements Ctx. +) + // ContextNoBody is used when the controller does not have a body. // It is used as a base context for other Context types. -type ContextNoBody struct { +type contextNoBodyImpl struct { Req *http.Request Res http.ResponseWriter @@ -132,16 +145,16 @@ type ContextNoBody struct { } var ( - _ ctx[any] = ContextNoBody{} // Check that ContextNoBody implements Ctx. - _ context.Context = ContextNoBody{} // Check that ContextNoBody implements context.Context. + _ ContextWithBody[any] = contextNoBodyImpl{} // Check that ContextNoBody implements Ctx. + _ context.Context = contextNoBodyImpl{} // Check that ContextNoBody implements context.Context. ) -func (c ContextNoBody) Body() (any, error) { +func (c contextNoBodyImpl) Body() (any, error) { slog.Warn("this method should not be called. It probably happened because you passed the context to another controller.") return body[map[string]any](c) } -func (c ContextNoBody) MustBody() any { +func (c contextNoBodyImpl) MustBody() any { b, err := c.Body() if err != nil { panic(err) @@ -151,7 +164,7 @@ func (c ContextNoBody) MustBody() any { // SetStatus sets the status code of the response. // Alias to http.ResponseWriter.WriteHeader. -func (c ContextNoBody) SetStatus(code int) { +func (c contextNoBodyImpl) SetStatus(code int) { c.Res.WriteHeader(code) } @@ -162,72 +175,65 @@ type readOptions struct { LogBody bool } -var ( - _ ctx[any] = &ContextWithBody[any]{} // Check that ContextWithBody[any] implements Ctx. - _ ctx[string] = &ContextWithBody[string]{} // Check that ContextWithBody[string] implements Ctx. - _ ctx[any] = &ContextNoBody{} // Check that ContextNoBody implements Ctx. - _ ctx[any] = ContextNoBody{} // Check that ContextNoBody implements Ctx. -) - -func (c ContextNoBody) Redirect(code int, url string) (any, error) { +func (c contextNoBodyImpl) Redirect(code int, url string) (any, error) { http.Redirect(c.Res, c.Req, url, code) return nil, nil } // ContextNoBody implements the context interface via [net/http.Request.Context] -func (c ContextNoBody) Deadline() (deadline time.Time, ok bool) { +func (c contextNoBodyImpl) Deadline() (deadline time.Time, ok bool) { return c.Req.Context().Deadline() } // ContextNoBody implements the context interface via [net/http.Request.Context] -func (c ContextNoBody) Done() <-chan struct{} { +func (c contextNoBodyImpl) Done() <-chan struct{} { return c.Req.Context().Done() } // ContextNoBody implements the context interface via [net/http.Request.Context] -func (c ContextNoBody) Err() error { +func (c contextNoBodyImpl) Err() error { return c.Req.Context().Err() } // ContextNoBody implements the context interface via [net/http.Request.Context] -func (c ContextNoBody) Value(key any) any { +func (c contextNoBodyImpl) Value(key any) any { return c.Req.Context().Value(key) } // ContextNoBody implements the context interface via [net/http.Request.Context] -func (c ContextNoBody) Context() context.Context { +func (c contextNoBodyImpl) Context() context.Context { return c.Req.Context() } // Get request header -func (c ContextNoBody) Header(key string) string { +func (c contextNoBodyImpl) Header(key string) string { return c.Request().Header.Get(key) } // Has request header -func (c ContextNoBody) HasHeader(key string) bool { +func (c contextNoBodyImpl) HasHeader(key string) bool { return c.Header(key) != "" } // Sets response header -func (c ContextNoBody) SetHeader(key, value string) { +func (c contextNoBodyImpl) SetHeader(key, value string) { c.Response().Header().Set(key, value) } // Get request cookie -func (c ContextNoBody) Cookie(name string) (*http.Cookie, error) { +func (c contextNoBodyImpl) Cookie(name string) (*http.Cookie, error) { return c.Request().Cookie(name) } // Has request cookie -func (c ContextNoBody) HasCookie(name string) bool { +func (c contextNoBodyImpl) HasCookie(name string) bool { _, err := c.Cookie(name) return err == nil } // Sets response cookie -func (c ContextNoBody) SetCookie(cookie http.Cookie) { +func (c contextNoBodyImpl) SetCookie(cookie http.Cookie) { http.SetCookie(c.Response(), &cookie) } @@ -239,7 +245,7 @@ func (c ContextNoBody) SetCookie(cookie http.Cookie) { // that the templates will be parsed only once, removing // the need to parse the templates on each request but also preventing // to dynamically use new templates. -func (c ContextNoBody) Render(templateToExecute string, data any, layoutsGlobs ...string) (CtxRenderer, error) { +func (c contextNoBodyImpl) Render(templateToExecute string, data any, layoutsGlobs ...string) (CtxRenderer, error) { return &StdRenderer{ templateToExecute: templateToExecute, templates: c.templates, @@ -250,7 +256,7 @@ func (c ContextNoBody) Render(templateToExecute string, data any, layoutsGlobs . } // PathParams returns the path parameters of the request. -func (c ContextNoBody) PathParam(name string) string { +func (c contextNoBodyImpl) PathParam(name string) string { return c.Req.PathValue(name) } @@ -274,12 +280,12 @@ func (e QueryParamInvalidTypeError) Error() string { } // QueryParams returns the query parameters of the request. It is a shortcut for c.Req.URL.Query(). -func (c ContextNoBody) QueryParams() url.Values { +func (c contextNoBodyImpl) QueryParams() url.Values { return c.urlValues } // QueryParamsArr returns an slice of string from the given query parameter. -func (c ContextNoBody) QueryParamArr(name string) []string { +func (c contextNoBodyImpl) QueryParamArr(name string) []string { _, ok := c.params[name] if !ok { slog.Warn("query parameter not expected in OpenAPI spec", "param", name) @@ -295,7 +301,7 @@ func (c ContextNoBody) QueryParamArr(name string) []string { // fuego.Get(s, "/test", myController, // option.Query("name", "Name", param.Default("hey")) // ) -func (c ContextNoBody) QueryParam(name string) string { +func (c contextNoBodyImpl) QueryParam(name string) string { _, ok := c.params[name] if !ok { slog.Warn("query parameter not expected in OpenAPI spec", "param", name, "expected_one_of", c.params) @@ -308,7 +314,7 @@ func (c ContextNoBody) QueryParam(name string) string { return c.urlValues.Get(name) } -func (c ContextNoBody) QueryParamIntErr(name string) (int, error) { +func (c contextNoBodyImpl) QueryParamIntErr(name string) (int, error) { param := c.QueryParam(name) if param == "" { defaultValue, ok := c.params[name].Default.(int) @@ -342,7 +348,7 @@ func (c ContextNoBody) QueryParamIntErr(name string) (int, error) { // // and the query parameter does not exist, it will return 1. // If the query parameter does not exist and there is no default value, or if it is not an int, it returns 0. -func (c ContextNoBody) QueryParamInt(name string) int { +func (c contextNoBodyImpl) QueryParamInt(name string) int { param, err := c.QueryParamIntErr(name) if err != nil { return 0 @@ -361,7 +367,7 @@ func (c ContextNoBody) QueryParamInt(name string) int { // // and the query parameter does not exist in the HTTP request, it will return true. // Accepted values are defined as [strconv.ParseBool] -func (c ContextNoBody) QueryParamBoolErr(name string) (bool, error) { +func (c contextNoBodyImpl) QueryParamBoolErr(name string) (bool, error) { param := c.QueryParam(name) if param == "" { defaultValue, ok := c.params[name].Default.(bool) @@ -394,7 +400,7 @@ func (c ContextNoBody) QueryParamBoolErr(name string) (bool, error) { // ) // // and the query parameter does not exist in the HTTP request, it will return true. -func (c ContextNoBody) QueryParamBool(name string) bool { +func (c contextNoBodyImpl) QueryParamBool(name string) bool { param, err := c.QueryParamBoolErr(name) if err != nil { return false @@ -403,26 +409,26 @@ func (c ContextNoBody) QueryParamBool(name string) bool { return param } -func (c ContextNoBody) MainLang() string { +func (c contextNoBodyImpl) MainLang() string { return strings.Split(c.MainLocale(), "-")[0] } -func (c ContextNoBody) MainLocale() string { +func (c contextNoBodyImpl) MainLocale() string { return strings.Split(c.Req.Header.Get("Accept-Language"), ",")[0] } // Request returns the HTTP request. -func (c ContextNoBody) Request() *http.Request { +func (c contextNoBodyImpl) Request() *http.Request { return c.Req } // Response returns the HTTP response writer. -func (c ContextNoBody) Response() http.ResponseWriter { +func (c contextNoBodyImpl) Response() http.ResponseWriter { return c.Res } // MustBody works like Body, but panics if there is an error. -func (c *ContextWithBody[B]) MustBody() B { +func (c *contextWithBodyImpl[B]) MustBody() B { b, err := c.Body() if err != nil { panic(err) @@ -435,17 +441,17 @@ func (c *ContextWithBody[B]) MustBody() B { // It caches the result, so it can be called multiple times. // The reason the body is cached is that it is impossible to read an HTTP request body multiple times, not because of performance. // For decoding, it uses the Content-Type header. If it is not set, defaults to application/json. -func (c *ContextWithBody[B]) Body() (B, error) { +func (c *contextWithBodyImpl[B]) Body() (B, error) { if c.body != nil { return *c.body, nil } - body, err := body[B](c.ContextNoBody) + body, err := body[B](c.contextNoBodyImpl) c.body = &body return body, err } -func body[B any](c ContextNoBody) (B, error) { +func body[B any](c contextNoBodyImpl) (B, error) { // Limit the size of the request body. if c.readOptions.MaxBodySize != 0 { c.Req.Body = http.MaxBytesReader(nil, c.Req.Body, c.readOptions.MaxBodySize) diff --git a/ctx_test.go b/ctx_test.go index 4a9d824f..7943c407 100644 --- a/ctx_test.go +++ b/ctx_test.go @@ -46,7 +46,7 @@ func TestContext_QueryParam(t *testing.T) { r := httptest.NewRequest("GET", "http://example.com/foo/123?id=456&other=hello&boo=true&name=jhon&name=doe", nil) w := httptest.NewRecorder() - c := NewContext[any](w, r, readOptions{}) + c := NewContextWithBody[any](w, r, readOptions{}) t.Run("string", func(t *testing.T) { param := c.QueryParam("other") @@ -124,7 +124,7 @@ func TestContext_QueryParams(t *testing.T) { r := httptest.NewRequest("GET", "http://example.com/foo/123?id=456&other=hello", nil) w := httptest.NewRecorder() - c := NewContext[any](w, r, readOptions{}) + c := NewContextWithBody[any](w, r, readOptions{}) params := c.QueryParams() require.NotEmpty(t, params) @@ -168,7 +168,7 @@ func TestContext_Body(t *testing.T) { w := httptest.NewRecorder() r := httptest.NewRequest("GET", "http://example.com/foo", a) - c := NewContext[testStruct](w, r, readOptions{}) + c := NewContextWithBody[testStruct](w, r, readOptions{}) body, err := c.Body() require.NoError(t, err) @@ -185,7 +185,7 @@ func TestContext_Body(t *testing.T) { r := httptest.NewRequest("GET", "http://example.com/foo", a) r.Header.Add("Content-Type", "application/json") - c := NewContext[testStruct](w, r, readOptions{}) + c := NewContextWithBody[testStruct](w, r, readOptions{}) body, err := c.Body() require.NoError(t, err) @@ -199,7 +199,7 @@ func TestContext_Body(t *testing.T) { w := httptest.NewRecorder() r := httptest.NewRequest("GET", "http://example.com/foo", a) - c := NewContext[testStruct](w, r, readOptions{}) + c := NewContextWithBody[testStruct](w, r, readOptions{}) body, err := c.Body() require.NoError(t, err) @@ -219,7 +219,7 @@ func TestContext_Body(t *testing.T) { } reqBody := strings.NewReader(`{"name":"John","age":30}`) - c := NewContext[testStruct]( + c := NewContextWithBody[testStruct]( httptest.NewRecorder(), httptest.NewRequest("GET", "http://example.com/foo", reqBody), readOptions{}) @@ -237,7 +237,7 @@ func TestContext_Body(t *testing.T) { } reqBody := strings.NewReader(`{"name":"VeryLongName","age":12}`) - c := NewContext[testStruct]( + c := NewContextWithBody[testStruct]( httptest.NewRecorder(), httptest.NewRequest("GET", "http://example.com/foo", reqBody), readOptions{}) @@ -250,7 +250,7 @@ func TestContext_Body(t *testing.T) { t.Run("can transform JSON body with custom method", func(t *testing.T) { reqBody := strings.NewReader(`{"name":"John","age":30}`) - c := NewContext[testStructInTransformer]( + c := NewContextWithBody[testStructInTransformer]( httptest.NewRecorder(), httptest.NewRequest("GET", "http://example.com/foo", reqBody), readOptions{}) @@ -263,7 +263,7 @@ func TestContext_Body(t *testing.T) { t.Run("can transform JSON body with custom method returning error", func(t *testing.T) { reqBody := strings.NewReader(`{"name":"John","age":30}`) - c := NewContext[testStructInTransformerWithError]( + c := NewContextWithBody[testStructInTransformerWithError]( httptest.NewRecorder(), httptest.NewRequest("GET", "http://example.com/foo", reqBody), readOptions{}) @@ -283,7 +283,7 @@ func TestContext_Body(t *testing.T) { r := httptest.NewRequest("GET", "http://example.com/foo", a) r.Header.Add("Content-Type", "application/octet-stream") - c := NewContext[[]byte](w, r, readOptions{}) + c := NewContextWithBody[[]byte](w, r, readOptions{}) body, err := c.Body() require.NoError(t, err) require.Equal(t, []byte(`image`), body) @@ -298,7 +298,7 @@ func TestContext_Body(t *testing.T) { r := httptest.NewRequest("GET", "http://example.com/foo", a) r.Header.Add("Content-Type", "application/octet-stream") - c := NewContext[*struct{}](w, r, readOptions{}) + c := NewContextWithBody[*struct{}](w, r, readOptions{}) body, err := c.Body() require.Error(t, err) require.ErrorContains(t, err, "use []byte as the body type") @@ -317,7 +317,7 @@ func TestContext_Body(t *testing.T) { r := httptest.NewRequest("GET", "http://example.com/foo", a) r.Header.Add("Content-Type", "application/xml") - c := NewContext[testStruct](w, r, readOptions{}) + c := NewContextWithBody[testStruct](w, r, readOptions{}) body, err := c.Body() require.NoError(t, err) @@ -335,7 +335,7 @@ age: 30 r := httptest.NewRequest("GET", "http://example.com/foo", a) r.Header.Add("Content-Type", "application/x-yaml") - c := NewContext[testStruct](w, r, readOptions{}) + c := NewContextWithBody[testStruct](w, r, readOptions{}) body, err := c.Body() require.NoError(t, err) @@ -345,7 +345,7 @@ age: 30 t.Run("unparsable because restricted to 1 byte", func(t *testing.T) { reqBody := strings.NewReader(`{"name":"John","age":30}`) - c := NewContext[testStructInTransformerWithError]( + c := NewContextWithBody[testStructInTransformerWithError]( httptest.NewRecorder(), httptest.NewRequest("GET", "http://example.com/foo", reqBody), readOptions{ @@ -367,7 +367,7 @@ age: 30 r := httptest.NewRequest("GET", "http://example.com/foo", a) r.Header.Set("Content-Type", "text/plain") - c := NewContext[string](w, r, readOptions{}) + c := NewContextWithBody[string](w, r, readOptions{}) _, err := c.Body() require.NoError(t, err) @@ -386,7 +386,7 @@ func FuzzContext_Body(f *testing.F) { r := httptest.NewRequest("GET", "http://example.com/foo", a) r.Header.Set("Content-Type", "application/x-www-form-urlencoded") - c := NewContext[testStruct](w, r, readOptions{}) + c := NewContextWithBody[testStruct](w, r, readOptions{}) _, err := c.Body() require.NoError(t, err) @@ -397,7 +397,7 @@ func BenchmarkContext_Body(b *testing.B) { b.Run("valid JSON body", func(b *testing.B) { for i := range b.N { reqBody := strings.NewReader(`{"name":"John","age":30}`) - c := NewContext[testStruct]( + c := NewContextWithBody[testStruct]( httptest.NewRecorder(), httptest.NewRequest("GET", "http://example.com/foo", reqBody), readOptions{}) @@ -413,7 +413,7 @@ func BenchmarkContext_Body(b *testing.B) { // See [Body] for more information. b.Run("valid JSON body cache", func(b *testing.B) { reqBody := strings.NewReader(`{"name":"John","age":30}`) - c := NewContext[testStruct]( + c := NewContextWithBody[testStruct]( httptest.NewRecorder(), httptest.NewRequest("GET", "http://example.com/foo", reqBody), readOptions{}) @@ -428,7 +428,7 @@ func BenchmarkContext_Body(b *testing.B) { b.Run("invalid JSON body", func(b *testing.B) { for range b.N { reqBody := strings.NewReader(`{"name":"John","age":30}`) - c := NewContext[testStruct]( + c := NewContextWithBody[testStruct]( httptest.NewRecorder(), httptest.NewRequest("GET", "http://example.com/foo", reqBody), readOptions{}) @@ -442,7 +442,7 @@ func BenchmarkContext_Body(b *testing.B) { b.Run("string body", func(b *testing.B) { for range b.N { reqBody := strings.NewReader(`{"name":"John","age":30}`) - c := NewContext[testStruct]( + c := NewContextWithBody[testStruct]( httptest.NewRecorder(), httptest.NewRequest("GET", "http://example.com/foo", reqBody), readOptions{}) @@ -463,7 +463,7 @@ func TestContext_MustBody(t *testing.T) { w := httptest.NewRecorder() r := httptest.NewRequest("GET", "http://example.com/foo", a) - c := NewContext[testStruct](w, r, readOptions{}) + c := NewContextWithBody[testStruct](w, r, readOptions{}) body := c.MustBody() require.Equal(t, "John", body.Name) @@ -477,7 +477,7 @@ func TestContext_MustBody(t *testing.T) { } reqBody := strings.NewReader(`{"name":"VeryLongName","age":12}`) - c := NewContext[testStruct]( + c := NewContextWithBody[testStruct]( httptest.NewRecorder(), httptest.NewRequest("GET", "http://example.com/foo", reqBody), readOptions{}) @@ -492,7 +492,7 @@ func TestMainLang(t *testing.T) { r := httptest.NewRequest("GET", "/", nil) r.Header.Set("Accept-Language", "fr-CH, fr;q=0.9, en;q=0.8, de;q=0.7, *;q=0.5") - c := NewContext[any](httptest.NewRecorder(), r, readOptions{}) + c := NewContextWithBody[any](httptest.NewRecorder(), r, readOptions{}) require.Equal(t, c.MainLang(), "fr") require.Equal(t, c.MainLocale(), "fr-CH") } @@ -500,7 +500,7 @@ func TestMainLang(t *testing.T) { func TestContextNoBody_Body(t *testing.T) { body := `{"name":"John","age":30}` r := httptest.NewRequest("GET", "/", strings.NewReader(body)) - ctx := ContextNoBody{ + ctx := contextNoBodyImpl{ Req: r, Res: httptest.NewRecorder(), } @@ -516,7 +516,7 @@ func TestContextNoBody_MustBody(t *testing.T) { t.Run("can read JSON body", func(t *testing.T) { body := `{"name":"John","age":30}` r := httptest.NewRequest("GET", "/", strings.NewReader(body)) - ctx := ContextNoBody{ + ctx := contextNoBodyImpl{ Req: r, Res: httptest.NewRecorder(), } @@ -530,7 +530,7 @@ func TestContextNoBody_MustBody(t *testing.T) { t.Run("cannot read invalid JSON body", func(t *testing.T) { body := `{"name":"John","age":30` r := httptest.NewRequest("GET", "/", strings.NewReader(body)) - ctx := ContextNoBody{ + ctx := contextNoBodyImpl{ Req: r, Res: httptest.NewRecorder(), } diff --git a/documentation/docs/guides/controllers.md b/documentation/docs/guides/controllers.md index 6ef64143..798d64c8 100644 --- a/documentation/docs/guides/controllers.md +++ b/documentation/docs/guides/controllers.md @@ -7,13 +7,13 @@ Controllers are the main way to interact with the application. They are responsi ### Returning JSON ```go -func (c *fuego.ContextNoBody) (MyResponse, error) +func (c fuego.ContextNoBody) (MyResponse, error) ``` Used when the request does not have a body. The response will be automatically serialized to JSON. ```go -func (c *fuego.ContextWithBody[MyInput]) (MyResponse, error) +func (c fuego.ContextWithBody[MyInput]) (MyResponse, error) ``` Used when the request has a body. @@ -22,7 +22,7 @@ Fuego will automatically parse the body and validate it using the input struct. ### Returning HTML ```go -func (c *fuego.ContextNoBody) (fuego.HTML, error) +func (c fuego.ContextNoBody) (fuego.HTML, error) ``` Some special interface return types are used by Fuego to return special responses. @@ -42,7 +42,7 @@ type MyResponse struct { Message string `json:"message"` } -func MyController(c *fuego.ContextWithBody[MyInput]) (MyResponse, error) { +func MyController(c fuego.ContextWithBody[MyInput]) (MyResponse, error) { body, err := c.Body() if err != nil { return MyResponse{}, err @@ -61,7 +61,7 @@ You can always go further in the request and response by using the underlying ne ### Get request header ```go -func MyController(c *fuego.ContextNoBody) (MyResponse, error) { +func MyController(c fuego.ContextNoBody) (MyResponse, error) { value := c.Header("X-My-Header") return MyResponse{}, nil } @@ -70,7 +70,7 @@ func MyController(c *fuego.ContextNoBody) (MyResponse, error) { ### Set response header ```go -func MyController(c *fuego.ContextNoBody) (MyResponse, error) { +func MyController(c fuego.ContextNoBody) (MyResponse, error) { c.SetHeader("X-My-Header", "value") return MyResponse{}, nil } @@ -81,7 +81,7 @@ func MyController(c *fuego.ContextNoBody) (MyResponse, error) { ### Get request cookie ```go -func MyController(c *fuego.ContextNoBody) (MyResponse, error) { +func MyController(c fuego.ContextNoBody) (MyResponse, error) { value := c.Cookie("my-cookie") return MyResponse{}, nil } @@ -90,7 +90,7 @@ func MyController(c *fuego.ContextNoBody) (MyResponse, error) { ### Set response cookie ```go -func MyController(c *fuego.ContextNoBody) (MyResponse, error) { +func MyController(c fuego.ContextNoBody) (MyResponse, error) { c.SetCookie("my-cookie", "value") return MyResponse{}, nil } diff --git a/documentation/docs/guides/serialization.md b/documentation/docs/guides/serialization.md index 0af9f404..a02b1c9f 100644 --- a/documentation/docs/guides/serialization.md +++ b/documentation/docs/guides/serialization.md @@ -61,7 +61,7 @@ If you just want to read the body of the request as a byte slice, you can use th Don't forget to set the request `Content-Type` header to `application/octet-stream`. ```go -fuego.Put(s, "/blob", func(c *fuego.ContextWithBody[[]byte]) (any, error) { +fuego.Put(s, "/blob", func(c fuego.ContextWithBody[[]byte]) (any, error) { body, err := c.Body() if err != nil { return nil, err diff --git a/documentation/docs/tutorials/02-crud.md b/documentation/docs/tutorials/02-crud.md index b76a36a9..7ef372ef 100644 --- a/documentation/docs/tutorials/02-crud.md +++ b/documentation/docs/tutorials/02-crud.md @@ -175,27 +175,27 @@ type BookToCreate struct { Title string `json:"title"` } -func GetBooks(c *fuego.ContextNoBody) ([]Book, error) { +func GetBooks(c fuego.ContextNoBody) ([]Book, error) { // Your code here return nil, nil } -func CreateBook(c *fuego.ContextWithBody[BookToCreate]) (Book, error) { +func CreateBook(c fuego.ContextWithBody[BookToCreate]) (Book, error) { // Your code here return Book{}, nil } -func GetBook(c *fuego.ContextNoBody) (Book, error) { +func GetBook(c fuego.ContextNoBody) (Book, error) { // Your code here return Book{}, nil } -func UpdateBook(c *fuego.ContextWithBody[Book]) (Book, error) { +func UpdateBook(c fuego.ContextWithBody[Book]) (Book, error) { // Your code here return Book{}, nil } -func DeleteBook(c *fuego.ContextNoBody) (any, error) { +func DeleteBook(c fuego.ContextNoBody) (any, error) { // Your code here return nil, nil } diff --git a/examples/basic/main.go b/examples/basic/main.go index 84833dc8..6fb235d9 100644 --- a/examples/basic/main.go +++ b/examples/basic/main.go @@ -31,7 +31,7 @@ func main() { fuego.Use(s, chiMiddleware.Compress(5, "text/html", "text/css")) // Fuego 🔥 handler with automatic OpenAPI generation, validation, (de)serialization and error handling - fuego.Post(s, "/", func(c *fuego.ContextWithBody[Received]) (MyResponse, error) { + fuego.Post(s, "/", func(c fuego.ContextWithBody[Received]) (MyResponse, error) { data, err := c.Body() if err != nil { return MyResponse{}, err diff --git a/examples/custom-errors/main.go b/examples/custom-errors/main.go index a088d891..aeeee7d4 100644 --- a/examples/custom-errors/main.go +++ b/examples/custom-errors/main.go @@ -38,7 +38,7 @@ func main() { fuego.Use(s, cors.Default().Handler) fuego.Use(s, chiMiddleware.Compress(5, "text/html", "text/css")) - fuego.Get(s, "/custom-err", func(c *fuego.ContextNoBody) (string, error) { + fuego.Get(s, "/custom-err", func(c fuego.ContextNoBody) (string, error) { return "hello", MyError{Err: errors.New("my error")} }, option.AddError(http.StatusTeapot, "my custom teapot error", MyError{}), diff --git a/examples/full-app-gourmet/controller/dosing.go b/examples/full-app-gourmet/controller/dosing.go index 3cb79843..31c5f291 100644 --- a/examples/full-app-gourmet/controller/dosing.go +++ b/examples/full-app-gourmet/controller/dosing.go @@ -16,7 +16,7 @@ func (rs dosingResource) MountRoutes(s *fuego.Server) { fuego.Post(dosingGroup, "/new", rs.newDosing) } -func (rs dosingResource) newDosing(c *fuego.ContextWithBody[store.CreateDosingParams]) (store.Dosing, error) { +func (rs dosingResource) newDosing(c fuego.ContextWithBody[store.CreateDosingParams]) (store.Dosing, error) { body, err := c.Body() if err != nil { return store.Dosing{}, err diff --git a/examples/full-app-gourmet/controller/ingredient.go b/examples/full-app-gourmet/controller/ingredient.go index a3c26891..113e9f43 100644 --- a/examples/full-app-gourmet/controller/ingredient.go +++ b/examples/full-app-gourmet/controller/ingredient.go @@ -40,7 +40,7 @@ func (ci *CreateIngredient) InTransform(context.Context) error { return nil } -func (rs ingredientResource) newIngredient(c *fuego.ContextWithBody[CreateIngredient]) (store.Ingredient, error) { +func (rs ingredientResource) newIngredient(c fuego.ContextWithBody[CreateIngredient]) (store.Ingredient, error) { body, err := c.Body() if err != nil { return store.Ingredient{}, err diff --git a/examples/full-app-gourmet/controller/recipe.go b/examples/full-app-gourmet/controller/recipe.go index aef8abb1..213c522a 100644 --- a/examples/full-app-gourmet/controller/recipe.go +++ b/examples/full-app-gourmet/controller/recipe.go @@ -49,7 +49,7 @@ func (rs recipeResource) getAllRecipes(c fuego.ContextNoBody) ([]store.Recipe, e return recipes, nil } -func (rs recipeResource) newRecipe(c *fuego.ContextWithBody[store.CreateRecipeParams]) (store.Recipe, error) { +func (rs recipeResource) newRecipe(c fuego.ContextWithBody[store.CreateRecipeParams]) (store.Recipe, error) { body, err := c.Body() if err != nil { return store.Recipe{}, err diff --git a/examples/full-app-gourmet/controller/users.go b/examples/full-app-gourmet/controller/users.go index d510851c..a51fb0bd 100644 --- a/examples/full-app-gourmet/controller/users.go +++ b/examples/full-app-gourmet/controller/users.go @@ -28,7 +28,7 @@ type TokenResponse struct { } // Custom login controller -func (rs Resource) login(c *fuego.ContextWithBody[LoginPayload]) (TokenResponse, error) { +func (rs Resource) login(c fuego.ContextWithBody[LoginPayload]) (TokenResponse, error) { body, err := c.Body() if err != nil { return TokenResponse{}, err diff --git a/examples/full-app-gourmet/views/admin.ingredient.go b/examples/full-app-gourmet/views/admin.ingredient.go index 19cd1dd4..e94e1775 100644 --- a/examples/full-app-gourmet/views/admin.ingredient.go +++ b/examples/full-app-gourmet/views/admin.ingredient.go @@ -12,7 +12,7 @@ import ( "github.com/go-fuego/fuego/examples/full-app-gourmet/templa/components" ) -func (rs Resource) adminOneIngredient(c *fuego.ContextWithBody[store.UpdateIngredientParams]) (any, error) { +func (rs Resource) adminOneIngredient(c fuego.ContextWithBody[store.UpdateIngredientParams]) (any, error) { id := c.PathParam("id") if c.Request().Method == "PUT" { @@ -42,11 +42,11 @@ func (rs Resource) adminOneIngredient(c *fuego.ContextWithBody[store.UpdateIngre return admin.IngredientPage(ingredient), nil } -func (rs Resource) adminIngredientCreationPage(c *fuego.ContextWithBody[store.CreateIngredientParams]) (any, error) { +func (rs Resource) adminIngredientCreationPage(c fuego.ContextWithBody[store.CreateIngredientParams]) (any, error) { return admin.IngredientNew(), nil } -func (rs Resource) adminCreateIngredient(c *fuego.ContextWithBody[store.CreateIngredientParams]) (any, error) { +func (rs Resource) adminCreateIngredient(c fuego.ContextWithBody[store.CreateIngredientParams]) (any, error) { createIngredientArgs, err := c.Body() if err != nil { return nil, err diff --git a/examples/full-app-gourmet/views/admin.recipe.go b/examples/full-app-gourmet/views/admin.recipe.go index 4dc92bce..53c4b343 100644 --- a/examples/full-app-gourmet/views/admin.recipe.go +++ b/examples/full-app-gourmet/views/admin.recipe.go @@ -49,7 +49,7 @@ func (rs Resource) adminRecipes(c fuego.ContextNoBody) (fuego.Templ, error) { return admin.RecipeList(recipes, searchParams), nil } -func (rs Resource) adminOneRecipe(c *fuego.ContextWithBody[store.UpdateRecipeParams]) (any, error) { +func (rs Resource) adminOneRecipe(c fuego.ContextWithBody[store.UpdateRecipeParams]) (any, error) { id := c.Request().PathValue("id") if c.Request().Method == "PUT" { @@ -95,7 +95,7 @@ func (rs Resource) adminOneRecipe(c *fuego.ContextWithBody[store.UpdateRecipePar }), nil } -func (rs Resource) editRecipe(c *fuego.ContextWithBody[store.UpdateRecipeParams]) (any, error) { +func (rs Resource) editRecipe(c fuego.ContextWithBody[store.UpdateRecipeParams]) (any, error) { updateRecipeArgs, err := c.Body() if err != nil { return "", err @@ -111,7 +111,7 @@ func (rs Resource) editRecipe(c *fuego.ContextWithBody[store.UpdateRecipeParams] return c.Redirect(http.StatusMovedPermanently, "/admin/recipes") } -func (rs Resource) adminAddRecipes(c *fuego.ContextWithBody[store.CreateRecipeParams]) (any, error) { +func (rs Resource) adminAddRecipes(c fuego.ContextWithBody[store.CreateRecipeParams]) (any, error) { body, err := c.Body() if err != nil { return "", err @@ -125,11 +125,11 @@ func (rs Resource) adminAddRecipes(c *fuego.ContextWithBody[store.CreateRecipePa return c.Redirect(http.StatusSeeOther, "/admin/recipes/"+r.ID) } -func (rs Resource) adminCreateRecipePage(c *fuego.ContextNoBody) (fuego.Templ, error) { +func (rs Resource) adminCreateRecipePage(c fuego.ContextNoBody) (fuego.Templ, error) { return admin.RecipeNew(), nil } -func (rs Resource) adminAddDosing(c *fuego.ContextWithBody[store.CreateDosingParams]) (any, error) { +func (rs Resource) adminAddDosing(c fuego.ContextWithBody[store.CreateDosingParams]) (any, error) { body, err := c.Body() if err != nil { return "", err diff --git a/examples/full-app-gourmet/views/recipe.go b/examples/full-app-gourmet/views/recipe.go index 5982e858..9128312e 100644 --- a/examples/full-app-gourmet/views/recipe.go +++ b/examples/full-app-gourmet/views/recipe.go @@ -245,7 +245,7 @@ func (rs Resource) showRecipesList(c fuego.ContextNoBody) (fuego.CtxRenderer, er return c.Render("partials/recipes-list.partial.html", recipes) } -func (rs Resource) addRecipe(c *fuego.ContextWithBody[store.CreateRecipeParams]) (fuego.CtxRenderer, error) { +func (rs Resource) addRecipe(c fuego.ContextWithBody[store.CreateRecipeParams]) (fuego.CtxRenderer, error) { body, err := c.Body() if err != nil { return nil, err diff --git a/examples/full-app-gourmet/views/recipe_test.go b/examples/full-app-gourmet/views/recipe_test.go index 5f89643e..3d7f19f1 100644 --- a/examples/full-app-gourmet/views/recipe_test.go +++ b/examples/full-app-gourmet/views/recipe_test.go @@ -111,7 +111,7 @@ func TestShowRecipesOpenAPITypes(t *testing.T) { B string } - route := fuego.Get(s, "/data", func(*fuego.ContextNoBody) (*fuego.DataOrTemplate[MyStruct], error) { + route := fuego.Get(s, "/data", func(fuego.ContextNoBody) (*fuego.DataOrTemplate[MyStruct], error) { entity := MyStruct{} return &fuego.DataOrTemplate[MyStruct]{ diff --git a/examples/petstore/controllers/pets.go b/examples/petstore/controllers/pets.go index 734a8031..cb12dd59 100644 --- a/examples/petstore/controllers/pets.go +++ b/examples/petstore/controllers/pets.go @@ -108,7 +108,7 @@ func (rs PetsResources) getAllPetsByAge(c fuego.ContextNoBody) ([][]models.Pets, return rs.PetsService.GetAllPetsByAge() } -func (rs PetsResources) postPets(c *fuego.ContextWithBody[models.PetsCreate]) (models.Pets, error) { +func (rs PetsResources) postPets(c fuego.ContextWithBody[models.PetsCreate]) (models.Pets, error) { body, err := c.Body() if err != nil { return models.Pets{}, err @@ -129,7 +129,7 @@ func (rs PetsResources) getPetByName(c fuego.ContextNoBody) (models.Pets, error) return rs.PetsService.GetPetByName(name) } -func (rs PetsResources) putPets(c *fuego.ContextWithBody[models.PetsUpdate]) (models.Pets, error) { +func (rs PetsResources) putPets(c fuego.ContextWithBody[models.PetsUpdate]) (models.Pets, error) { id := c.PathParam("id") body, err := c.Body() @@ -140,7 +140,7 @@ func (rs PetsResources) putPets(c *fuego.ContextWithBody[models.PetsUpdate]) (mo return rs.PetsService.UpdatePets(id, body) } -func (rs PetsResources) deletePets(c *fuego.ContextNoBody) (any, error) { +func (rs PetsResources) deletePets(c fuego.ContextNoBody) (any, error) { return rs.PetsService.DeletePets(c.PathParam("id")) } diff --git a/examples/petstore/lib/testdata/doc/openapi.golden.json b/examples/petstore/lib/testdata/doc/openapi.golden.json index b7b0bf7a..9fbabd97 100644 --- a/examples/petstore/lib/testdata/doc/openapi.golden.json +++ b/examples/petstore/lib/testdata/doc/openapi.golden.json @@ -147,7 +147,7 @@ } }, "info": { - "description": "\nThis is the autogenerated OpenAPI documentation for your [Fuego](https://github.com/go-fuego/fuego) API.\n\nBelow is a Fuego Cheatsheet to help you get started. Don't hesitate to check the [Fuego documentation](https://go-fuego.github.io/fuego) for more details.\n\nHappy coding! 🔥\n\n## Usage\n\n### Route registration\n\n```go\nfunc main() {\n\t// Create a new server\n\ts := fuego.NewServer()\n\n\t// Register some routes\n\tfuego.Post(s, \"/hello\", myController)\n\tfuego.Get(s, \"/myPath\", otherController)\n\tfuego.Put(s, \"/hello\", thirdController)\n\n\tadminRoutes := fuego.Group(s, \"/admin\")\n\tfuego.Use(adminRoutes, myMiddleware) // This middleware (for authentication, etc...) will be available for routes starting by /admin/*, \n\tfuego.Get(adminRoutes, \"/hello\", groupController) // This route will be available at /admin/hello\n\n\t// Start the server\n\ts.Start()\n}\n```\n\n### Basic controller\n\n```go\ntype MyBody struct {\n\tName string `json:\"name\" validate:\"required,max=30\"`\n}\n\ntype MyResponse struct {\n\tAnswer string `json:\"answer\"`\n}\n\nfunc hello(ctx *fuego.ContextWithBody[MyBody]) (*MyResponse, error) {\n\tbody, err := ctx.Body()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn \u0026MyResponse{Answer: \"Hello \" + body.Name}, nil\n}\n```\n\n### Add openAPI information to the route\n\n```go\nimport (\n\t\"github.com/go-fuego/fuego\"\n\t\"github.com/go-fuego/fuego/option\"\n\t\"github.com/go-fuego/fuego/param\"\n)\n\nfunc main() {\n\ts := fuego.NewServer()\n\n\t// Custom OpenAPI options\n\tfuego.Post(s, \"/\", myController\n\t\toption.Description(\"This route does something...\"),\n\t\toption.Summary(\"This is my summary\"),\n\t\toption.Tags(\"MyTag\"), // A tag is set by default according to the return type (can be deactivated)\n\t\toption.Deprecated(), // Marks the route as deprecated in the OpenAPI spec\n\n\t\toption.Query(\"name\", \"Declares a query parameter with default value\", param.Default(\"Carmack\")),\n\t\toption.Header(\"Authorization\", \"Bearer token\", param.Required()),\n\t\toptionPagination,\n\t\toptionCustomBehavior,\n\t)\n\n\ts.Run()\n}\n\nvar optionPagination = option.Group(\n\toption.QueryInt(\"page\", \"Page number\", param.Default(1), param.Example(\"1st page\", 1), param.Example(\"42nd page\", 42)),\n\toption.QueryInt(\"perPage\", \"Number of items per page\"),\n)\n\nvar optionCustomBehavior = func(r *fuego.BaseRoute) {\n\tr.XXX = \"YYY\"\n}\n```\n\nThen, in the controller\n\n```go\ntype MyResponse struct {\n\tAnswer string `json:\"answer\"`\n}\n\nfunc getAllPets(ctx *fuego.ContextNoBody) (*MyResponse, error) {\n\tname := ctx.QueryParam(\"name\")\n\tperPage, _ := ctx.QueryParamIntErr(\"per_page\")\n\n\treturn \u0026MyResponse{Answer: \"Hello \" + name}, nil\n}\n```\n", + "description": "\nThis is the autogenerated OpenAPI documentation for your [Fuego](https://github.com/go-fuego/fuego) API.\n\nBelow is a Fuego Cheatsheet to help you get started. Don't hesitate to check the [Fuego documentation](https://go-fuego.github.io/fuego) for more details.\n\nHappy coding! 🔥\n\n## Usage\n\n### Route registration\n\n```go\nfunc main() {\n\t// Create a new server\n\ts := fuego.NewServer()\n\n\t// Register some routes\n\tfuego.Post(s, \"/hello\", myController)\n\tfuego.Get(s, \"/myPath\", otherController)\n\tfuego.Put(s, \"/hello\", thirdController)\n\n\tadminRoutes := fuego.Group(s, \"/admin\")\n\tfuego.Use(adminRoutes, myMiddleware) // This middleware (for authentication, etc...) will be available for routes starting by /admin/*, \n\tfuego.Get(adminRoutes, \"/hello\", groupController) // This route will be available at /admin/hello\n\n\t// Start the server\n\ts.Start()\n}\n```\n\n### Basic controller\n\n```go\ntype MyBody struct {\n\tName string `json:\"name\" validate:\"required,max=30\"`\n}\n\ntype MyResponse struct {\n\tAnswer string `json:\"answer\"`\n}\n\nfunc hello(ctx fuego.ContextWithBody[MyBody]) (*MyResponse, error) {\n\tbody, err := ctx.Body()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn \u0026MyResponse{Answer: \"Hello \" + body.Name}, nil\n}\n```\n\n### Add openAPI information to the route\n\n```go\nimport (\n\t\"github.com/go-fuego/fuego\"\n\t\"github.com/go-fuego/fuego/option\"\n\t\"github.com/go-fuego/fuego/param\"\n)\n\nfunc main() {\n\ts := fuego.NewServer()\n\n\t// Custom OpenAPI options\n\tfuego.Post(s, \"/\", myController\n\t\toption.Description(\"This route does something...\"),\n\t\toption.Summary(\"This is my summary\"),\n\t\toption.Tags(\"MyTag\"), // A tag is set by default according to the return type (can be deactivated)\n\t\toption.Deprecated(), // Marks the route as deprecated in the OpenAPI spec\n\n\t\toption.Query(\"name\", \"Declares a query parameter with default value\", param.Default(\"Carmack\")),\n\t\toption.Header(\"Authorization\", \"Bearer token\", param.Required()),\n\t\toptionPagination,\n\t\toptionCustomBehavior,\n\t)\n\n\ts.Run()\n}\n\nvar optionPagination = option.Group(\n\toption.QueryInt(\"page\", \"Page number\", param.Default(1), param.Example(\"1st page\", 1), param.Example(\"42nd page\", 42)),\n\toption.QueryInt(\"perPage\", \"Number of items per page\"),\n)\n\nvar optionCustomBehavior = func(r *fuego.BaseRoute) {\n\tr.XXX = \"YYY\"\n}\n```\n\nThen, in the controller\n\n```go\ntype MyResponse struct {\n\tAnswer string `json:\"answer\"`\n}\n\nfunc getAllPets(ctx fuego.ContextNoBody) (*MyResponse, error) {\n\tname := ctx.QueryParam(\"name\")\n\tperPage, _ := ctx.QueryParamIntErr(\"per_page\")\n\n\treturn \u0026MyResponse{Answer: \"Hello \" + name}, nil\n}\n```\n", "title": "OpenAPI", "version": "0.0.1" }, diff --git a/html_test.go b/html_test.go index 7e07f37f..c748bf1b 100644 --- a/html_test.go +++ b/html_test.go @@ -18,7 +18,7 @@ func TestRender(t *testing.T) { WithTemplateGlobs("testdata/*.html"), ) - Get(s, "/test", func(ctx *ContextNoBody) (CtxRenderer, error) { + Get(s, "/test", func(ctx ContextNoBody) (CtxRenderer, error) { return ctx.Render("testdata/test.html", H{"Name": "test"}) }) diff --git a/middleware/cache/cache_test.go b/middleware/cache/cache_test.go index c0a5491d..84504cdf 100644 --- a/middleware/cache/cache_test.go +++ b/middleware/cache/cache_test.go @@ -19,7 +19,7 @@ type testStruct struct { const waitTime = 10 * time.Millisecond -func baseController(c *fuego.ContextNoBody) (testStruct, error) { +func baseController(c fuego.ContextNoBody) (testStruct, error) { time.Sleep(waitTime) return testStruct{Name: "test", Age: 10}, nil } diff --git a/mux.go b/mux.go index 18b4f642..355c7696 100644 --- a/mux.go +++ b/mux.go @@ -45,27 +45,27 @@ func Group(s *Server, path string, routeOptions ...func(*BaseRoute)) *Server { } // Capture all methods (GET, POST, PUT, PATCH, DELETE) and register a controller. -func All[ReturnType, Body any, Contexted ctx[Body]](s *Server, path string, controller func(Contexted) (ReturnType, error), options ...func(*BaseRoute)) *Route[ReturnType, Body] { +func All[T, B any](s *Server, path string, controller func(ContextWithBody[B]) (T, error), options ...func(*BaseRoute)) *Route[T, B] { return registerFuegoController(s, "", path, controller, options...) } -func Get[T, B any, Contexted ctx[B]](s *Server, path string, controller func(Contexted) (T, error), options ...func(*BaseRoute)) *Route[T, B] { +func Get[T, B any](s *Server, path string, controller func(ContextWithBody[B]) (T, error), options ...func(*BaseRoute)) *Route[T, B] { return registerFuegoController(s, http.MethodGet, path, controller, options...) } -func Post[T, B any, Contexted ctx[B]](s *Server, path string, controller func(Contexted) (T, error), options ...func(*BaseRoute)) *Route[T, B] { +func Post[T, B any](s *Server, path string, controller func(ContextWithBody[B]) (T, error), options ...func(*BaseRoute)) *Route[T, B] { return registerFuegoController(s, http.MethodPost, path, controller, options...) } -func Delete[T, B any, Contexted ctx[B]](s *Server, path string, controller func(Contexted) (T, error), options ...func(*BaseRoute)) *Route[T, B] { +func Delete[T, B any](s *Server, path string, controller func(ContextWithBody[B]) (T, error), options ...func(*BaseRoute)) *Route[T, B] { return registerFuegoController(s, http.MethodDelete, path, controller, options...) } -func Put[T, B any, Contexted ctx[B]](s *Server, path string, controller func(Contexted) (T, error), options ...func(*BaseRoute)) *Route[T, B] { +func Put[T, B any](s *Server, path string, controller func(ContextWithBody[B]) (T, error), options ...func(*BaseRoute)) *Route[T, B] { return registerFuegoController(s, http.MethodPut, path, controller, options...) } -func Patch[T, B any, Contexted ctx[B]](s *Server, path string, controller func(Contexted) (T, error), options ...func(*BaseRoute)) *Route[T, B] { +func Patch[T, B any](s *Server, path string, controller func(ContextWithBody[B]) (T, error), options ...func(*BaseRoute)) *Route[T, B] { return registerFuegoController(s, http.MethodPatch, path, controller, options...) } @@ -141,7 +141,7 @@ func PatchStd(s *Server, path string, controller func(http.ResponseWriter, *http return registerStdController(s, http.MethodPatch, path, controller, options...) } -func registerFuegoController[T, B any, Contexted ctx[B]](s *Server, method, path string, controller func(Contexted) (T, error), options ...func(*BaseRoute)) *Route[T, B] { +func registerFuegoController[T, B any](s *Server, method, path string, controller func(ContextWithBody[B]) (T, error), options ...func(*BaseRoute)) *Route[T, B] { route := NewRoute[T, B](method, path, controller, s.OpenAPI, append(s.routeOptions, options...)...) acceptHeaderParameter := openapi3.NewHeaderParameter("Accept") diff --git a/mux_test.go b/mux_test.go index cbd719f3..4e6a67e3 100644 --- a/mux_test.go +++ b/mux_test.go @@ -32,7 +32,7 @@ func TestUse(t *testing.T) { t.Run("base", func(t *testing.T) { s := NewServer() Use(s, orderMiddleware("First!")) - Get(s, "/test", func(ctx *ContextNoBody) (string, error) { + Get(s, "/test", func(ctx ContextNoBody) (string, error) { return "test", nil }) @@ -49,7 +49,7 @@ func TestUse(t *testing.T) { s := NewServer() Use(s, orderMiddleware("First!")) Use(s, orderMiddleware("Second!")) - Get(s, "/test", func(ctx *ContextNoBody) (string, error) { + Get(s, "/test", func(ctx ContextNoBody) (string, error) { return "test", nil }) @@ -66,7 +66,7 @@ func TestUse(t *testing.T) { s := NewServer() Use(s, orderMiddleware("First!")) Use(s, orderMiddleware("Second!"), orderMiddleware("Third!")) - Get(s, "/test", func(ctx *ContextNoBody) (string, error) { + Get(s, "/test", func(ctx ContextNoBody) (string, error) { return "test", nil }) @@ -85,7 +85,7 @@ func TestUse(t *testing.T) { group := Group(s, "/group") Use(group, orderMiddleware("Second!")) Use(group, orderMiddleware("Third!")) - Get(group, "/test", func(ctx *ContextNoBody) (string, error) { + Get(group, "/test", func(ctx ContextNoBody) (string, error) { return "test", nil }) @@ -123,7 +123,7 @@ func TestUseStd(t *testing.T) { func TestAll(t *testing.T) { s := NewServer() - All(s, "/test", func(ctx *ContextNoBody) (string, error) { + All(s, "/test", func(ctx ContextNoBody) (string, error) { return "test", nil }) @@ -150,7 +150,7 @@ func TestAll(t *testing.T) { func TestGet(t *testing.T) { s := NewServer() - Get(s, "/test", func(ctx *ContextNoBody) (string, error) { + Get(s, "/test", func(ctx ContextNoBody) (string, error) { return "test", nil }) @@ -165,7 +165,7 @@ func TestGet(t *testing.T) { func TestPost(t *testing.T) { s := NewServer() - Post(s, "/test", func(ctx *ContextNoBody) (string, error) { + Post(s, "/test", func(ctx ContextNoBody) (string, error) { return "test", nil }) @@ -180,7 +180,7 @@ func TestPost(t *testing.T) { func TestPut(t *testing.T) { s := NewServer() - Put(s, "/test", func(ctx *ContextNoBody) (string, error) { + Put(s, "/test", func(ctx ContextNoBody) (string, error) { return "test", nil }) @@ -195,7 +195,7 @@ func TestPut(t *testing.T) { func TestPatch(t *testing.T) { s := NewServer() - Patch(s, "/test", func(ctx *ContextNoBody) (string, error) { + Patch(s, "/test", func(ctx ContextNoBody) (string, error) { return "test", nil }) @@ -210,7 +210,7 @@ func TestPatch(t *testing.T) { func TestDelete(t *testing.T) { s := NewServer() - Delete(s, "/test", func(ctx *ContextNoBody) (string, error) { + Delete(s, "/test", func(ctx ContextNoBody) (string, error) { return "test", nil }) @@ -431,7 +431,7 @@ func TestGroupInheritance(t *testing.T) { ) t.Run("group inheritance", func(t *testing.T) { - route := Get(group2, "/test", func(ctx *ContextNoBody) (string, error) { + route := Get(group2, "/test", func(ctx ContextNoBody) (string, error) { return "test", nil }) @@ -448,7 +448,7 @@ func TestGroupTagsOnRoute(t *testing.T) { s := NewServer( WithRouteOptions(OptionTags("my-server-tag")), ) - route := Get(s, "/path", func(ctx *ContextNoBody) (string, error) { + route := Get(s, "/path", func(ctx ContextNoBody) (string, error) { return "test", nil }) require.Equal(t, []string{"my-server-tag"}, route.Operation.Tags) @@ -459,7 +459,7 @@ func TestGroupTagsOnRoute(t *testing.T) { WithRouteOptions(OptionTags("my-server-tag")), ) - route := Get(s, "/path", func(ctx *ContextNoBody) (string, error) { + route := Get(s, "/path", func(ctx ContextNoBody) (string, error) { return "test", nil }, OptionTags("my-route-tag"), @@ -483,9 +483,9 @@ func TestGroupTagsOnRoute(t *testing.T) { func TestHideOpenapiRoutes(t *testing.T) { t.Run("hide main server", func(t *testing.T) { s := NewServer() - Get(s, "/not-hidden", func(ctx *ContextNoBody) (string, error) { return "", nil }) + Get(s, "/not-hidden", func(ctx ContextNoBody) (string, error) { return "", nil }) s.Hide() - Get(s, "/test", func(ctx *ContextNoBody) (string, error) { return "", nil }) + Get(s, "/test", func(ctx ContextNoBody) (string, error) { return "", nil }) require.Equal(t, s.DisableOpenapi, true) require.True(t, s.OpenAPI.Description().Paths.Find("/not-hidden") != nil) @@ -494,10 +494,10 @@ func TestHideOpenapiRoutes(t *testing.T) { t.Run("hide group", func(t *testing.T) { s := NewServer() - Get(s, "/not-hidden", func(ctx *ContextNoBody) (string, error) { return "", nil }) + Get(s, "/not-hidden", func(ctx ContextNoBody) (string, error) { return "", nil }) g := Group(s, "/group").Hide() - Get(g, "/test", func(ctx *ContextNoBody) (string, error) { return "", nil }) + Get(g, "/test", func(ctx ContextNoBody) (string, error) { return "", nil }) require.Equal(t, g.DisableOpenapi, true) require.True(t, s.OpenAPI.Description().Paths.Find("/not-hidden") != nil) @@ -507,10 +507,10 @@ func TestHideOpenapiRoutes(t *testing.T) { t.Run("hide group but not other group", func(t *testing.T) { s := NewServer() g := Group(s, "/group").Hide() - Get(g, "/test", func(ctx *ContextNoBody) (string, error) { return "test", nil }) + Get(g, "/test", func(ctx ContextNoBody) (string, error) { return "test", nil }) g2 := Group(s, "/group2") - Get(g2, "/test", func(ctx *ContextNoBody) (string, error) { return "test", nil }) + Get(g2, "/test", func(ctx ContextNoBody) (string, error) { return "test", nil }) require.Equal(t, true, g.DisableOpenapi) require.Equal(t, false, g2.DisableOpenapi) @@ -521,10 +521,10 @@ func TestHideOpenapiRoutes(t *testing.T) { t.Run("hide group but show sub group", func(t *testing.T) { s := NewServer() g := Group(s, "/group").Hide() - Get(g, "/test", func(ctx *ContextNoBody) (string, error) { return "test", nil }) + Get(g, "/test", func(ctx ContextNoBody) (string, error) { return "test", nil }) g2 := Group(g, "/sub").Show() - Get(g2, "/test", func(ctx *ContextNoBody) (string, error) { return "test", nil }) + Get(g2, "/test", func(ctx ContextNoBody) (string, error) { return "test", nil }) require.Equal(t, true, g.DisableOpenapi) require.True(t, s.OpenAPI.Description().Paths.Find("/group/test") == nil) @@ -539,7 +539,7 @@ func BenchmarkRequest(b *testing.B) { b.Run("fuego server and fuego post", func(b *testing.B) { s := NewServer() - Post(s, "/test", func(c *ContextWithBody[MyStruct]) (Resp, error) { + Post(s, "/test", func(c ContextWithBody[MyStruct]) (Resp, error) { body, err := c.Body() if err != nil { return Resp{}, err @@ -628,24 +628,24 @@ func TestGroup(t *testing.T) { main := Group(s, "/") Use(main, dummyMiddleware) // middleware is scoped to the group - Get(main, "/main", func(ctx *ContextNoBody) (string, error) { + Get(main, "/main", func(ctx ContextNoBody) (string, error) { return "main", nil }) group1 := Group(s, "/group") - Get(group1, "/route1", func(ctx *ContextNoBody) (string, error) { + Get(group1, "/route1", func(ctx ContextNoBody) (string, error) { return "route1", nil }) group2 := Group(s, "/group2") Use(group2, dummyMiddleware) // middleware is scoped to the group - Get(group2, "/route2", func(ctx *ContextNoBody) (string, error) { + Get(group2, "/route2", func(ctx ContextNoBody) (string, error) { return "route2", nil }) subGroup := Group(group1, "/sub") - Get(subGroup, "/route3", func(ctx *ContextNoBody) (string, error) { + Get(subGroup, "/route3", func(ctx ContextNoBody) (string, error) { return "route3", nil }) @@ -754,7 +754,7 @@ func TestGroupTags(t *testing.T) { func ExampleContextNoBody_SetCookie() { s := NewServer() - Get(s, "/test", func(c *ContextNoBody) (string, error) { + Get(s, "/test", func(c ContextNoBody) (string, error) { c.SetCookie(http.Cookie{ Name: "name", Value: "value", @@ -777,7 +777,7 @@ func ExampleContextNoBody_SetCookie() { func ExampleContextNoBody_SetHeader() { s := NewServer() - Get(s, "/test", func(c *ContextNoBody) (string, error) { + Get(s, "/test", func(c ContextNoBody) (string, error) { c.SetHeader("X-Test", "test") return "test", nil }) diff --git a/openapi_description.go b/openapi_description.go index d57583d0..863dfbd5 100644 --- a/openapi_description.go +++ b/openapi_description.go @@ -41,7 +41,7 @@ type MyResponse struct { Answer string ` + "`json:\"answer\"`" + ` } -func hello(ctx *fuego.ContextWithBody[MyBody]) (*MyResponse, error) { +func hello(ctx fuego.ContextWithBody[MyBody]) (*MyResponse, error) { body, err := ctx.Body() if err != nil { return nil, err @@ -96,7 +96,7 @@ type MyResponse struct { Answer string ` + "`json:\"answer\"`" + ` } -func getAllPets(ctx *fuego.ContextNoBody) (*MyResponse, error) { +func getAllPets(ctx fuego.ContextNoBody) (*MyResponse, error) { name := ctx.QueryParam("name") perPage, _ := ctx.QueryParamIntErr("per_page") diff --git a/openapi_test.go b/openapi_test.go index 9970950e..7b695288 100644 --- a/openapi_test.go +++ b/openapi_test.go @@ -205,16 +205,16 @@ func Test_tagFromType(t *testing.T) { func TestServer_generateOpenAPI(t *testing.T) { s := NewServer() - Get(s, "/", func(*ContextNoBody) (MyStruct, error) { + Get(s, "/", func(ContextNoBody) (MyStruct, error) { return MyStruct{}, nil }) - Post(s, "/post", func(*ContextWithBody[MyStruct]) ([]MyStruct, error) { + Post(s, "/post", func(ContextWithBody[MyStruct]) ([]MyStruct, error) { return nil, nil }) - Get(s, "/post/{id}", func(*ContextNoBody) (MyOutputStruct, error) { + Get(s, "/post/{id}", func(ContextNoBody) (MyOutputStruct, error) { return MyOutputStruct{}, nil }) - Post(s, "/multidimensional/post", func(*ContextWithBody[MyStruct]) ([][]MyStruct, error) { + Post(s, "/multidimensional/post", func(ContextWithBody[MyStruct]) ([][]MyStruct, error) { return nil, nil }) document := s.OutputOpenAPISpec() @@ -251,7 +251,7 @@ func TestServer_OutputOpenApiSpec(t *testing.T) { }, ), ) - Get(s, "/", func(*ContextNoBody) (MyStruct, error) { + Get(s, "/", func(ContextNoBody) (MyStruct, error) { return MyStruct{}, nil }) @@ -273,7 +273,7 @@ func TestServer_OutputOpenApiSpec(t *testing.T) { }, ), ) - Get(s, "/", func(*ContextNoBody) (MyStruct, error) { + Get(s, "/", func(ContextNoBody) (MyStruct, error) { return MyStruct{}, nil }) @@ -294,7 +294,7 @@ func TestServer_OutputOpenApiSpec(t *testing.T) { }, ), ) - Get(s, "/", func(*ContextNoBody) (MyStruct, error) { + Get(s, "/", func(ContextNoBody) (MyStruct, error) { return MyStruct{}, nil }) @@ -315,7 +315,7 @@ func TestServer_OutputOpenApiSpec(t *testing.T) { }, ), ) - Get(s, "/", func(*ContextNoBody) (MyStruct, error) { + Get(s, "/", func(ContextNoBody) (MyStruct, error) { return MyStruct{}, nil }) @@ -350,7 +350,7 @@ func BenchmarkRoutesRegistration(b *testing.B) { return MyStruct{}, nil }) for j := 0; j < 100; j++ { - Post(s, fmt.Sprintf("/post/%d", j), func(*ContextWithBody[MyStruct]) ([]MyStruct, error) { + Post(s, fmt.Sprintf("/post/%d", j), func(ContextWithBody[MyStruct]) ([]MyStruct, error) { return nil, nil }) } @@ -371,7 +371,7 @@ func BenchmarkServer_generateOpenAPI(b *testing.B) { return MyStruct{}, nil }) for j := 0; j < 100; j++ { - Post(s, fmt.Sprintf("/post/%d", j), func(*ContextWithBody[MyStruct]) ([]MyStruct, error) { + Post(s, fmt.Sprintf("/post/%d", j), func(ContextWithBody[MyStruct]) ([]MyStruct, error) { return nil, nil }) } @@ -430,22 +430,22 @@ func TestAutoGroupTags(t *testing.T) { DisableSwagger: true, }), ) - Get(s, "/a", func(*ContextNoBody) (MyStruct, error) { + Get(s, "/a", func(ContextNoBody) (MyStruct, error) { return MyStruct{}, nil }) group := Group(s, "/group") - Get(group, "/b", func(*ContextNoBody) (MyStruct, error) { + Get(group, "/b", func(ContextNoBody) (MyStruct, error) { return MyStruct{}, nil }) subGroup := Group(group, "/subgroup") - Get(subGroup, "/c", func(*ContextNoBody) (MyStruct, error) { + Get(subGroup, "/c", func(ContextNoBody) (MyStruct, error) { return MyStruct{}, nil }) otherGroup := Group(s, "/other") - Get(otherGroup, "/d", func(*ContextNoBody) (MyStruct, error) { + Get(otherGroup, "/d", func(ContextNoBody) (MyStruct, error) { return MyStruct{}, nil }) @@ -503,7 +503,7 @@ func TestEmbeddedStructHandling(t *testing.T) { } // Register a route that returns OuterStruct - Get(s, "/embedded", func(*ContextNoBody) (OuterStruct, error) { + Get(s, "/embedded", func(ContextNoBody) (OuterStruct, error) { return OuterStruct{}, nil }) diff --git a/option_test.go b/option_test.go index 5201b3eb..43026497 100644 --- a/option_test.go +++ b/option_test.go @@ -25,7 +25,7 @@ func dummyMiddleware(handler http.Handler) http.Handler { }) } -func helloWorld(ctx *fuego.ContextNoBody) (string, error) { +func helloWorld(ctx fuego.ContextNoBody) (string, error) { return "hello world", nil } @@ -38,7 +38,7 @@ type Resp struct { Message string `json:"message"` } -func dummyController(_ *fuego.ContextWithBody[ReqBody]) (Resp, error) { +func dummyController(_ fuego.ContextWithBody[ReqBody]) (Resp, error) { return Resp{Message: "hello world"}, nil } @@ -58,11 +58,11 @@ func orderMiddleware(s string) func(http.Handler) http.Handler { func TestPerRouteMiddleware(t *testing.T) { s := fuego.NewServer() - fuego.Get(s, "/withMiddleware", func(ctx *fuego.ContextNoBody) (string, error) { + fuego.Get(s, "/withMiddleware", func(ctx fuego.ContextNoBody) (string, error) { return "withmiddleware", nil }, fuego.OptionMiddleware(dummyMiddleware)) - fuego.Get(s, "/withoutMiddleware", func(ctx *fuego.ContextNoBody) (string, error) { + fuego.Get(s, "/withoutMiddleware", func(ctx fuego.ContextNoBody) (string, error) { return "withoutmiddleware", nil }) @@ -93,7 +93,7 @@ func TestUse(t *testing.T) { t.Run("base", func(t *testing.T) { s := fuego.NewServer() fuego.Use(s, orderMiddleware("First!")) - fuego.Get(s, "/test", func(ctx *fuego.ContextNoBody) (string, error) { + fuego.Get(s, "/test", func(ctx fuego.ContextNoBody) (string, error) { return "test", nil }) @@ -110,7 +110,7 @@ func TestUse(t *testing.T) { s := fuego.NewServer() fuego.Use(s, orderMiddleware("First!")) fuego.Use(s, orderMiddleware("Second!")) - fuego.Get(s, "/test", func(ctx *fuego.ContextNoBody) (string, error) { + fuego.Get(s, "/test", func(ctx fuego.ContextNoBody) (string, error) { return "test", nil }) @@ -127,7 +127,7 @@ func TestUse(t *testing.T) { s := fuego.NewServer() fuego.Use(s, orderMiddleware("First!")) fuego.Use(s, orderMiddleware("Second!"), orderMiddleware("Third!")) - fuego.Get(s, "/test", func(ctx *fuego.ContextNoBody) (string, error) { + fuego.Get(s, "/test", func(ctx fuego.ContextNoBody) (string, error) { return "test", nil }) @@ -144,7 +144,7 @@ func TestUse(t *testing.T) { s := fuego.NewServer() fuego.Use(s, orderMiddleware("First!")) fuego.Use(s, orderMiddleware("Second!"), orderMiddleware("Third!")) - fuego.Get(s, "/test", func(ctx *fuego.ContextNoBody) (string, error) { + fuego.Get(s, "/test", func(ctx fuego.ContextNoBody) (string, error) { return "test", nil }, fuego.OptionMiddleware(orderMiddleware("Fourth!")), diff --git a/security.go b/security.go index 04c26772..719bc814 100644 --- a/security.go +++ b/security.go @@ -430,8 +430,8 @@ type LoginPayload struct { // }, // Username: "myUsername", // }, nil -func (security Security) LoginHandler(verifyUserInfo func(user, password string) (jwt.Claims, error)) func(*ContextWithBody[LoginPayload]) (tokenResponse, error) { - return func(c *ContextWithBody[LoginPayload]) (tokenResponse, error) { +func (security Security) LoginHandler(verifyUserInfo func(user, password string) (jwt.Claims, error)) func(ContextWithBody[LoginPayload]) (tokenResponse, error) { + return func(c ContextWithBody[LoginPayload]) (tokenResponse, error) { body, err := c.Body() if err != nil { return tokenResponse{}, err diff --git a/serve.go b/serve.go index c6a03979..dd92208f 100644 --- a/serve.go +++ b/serve.go @@ -1,7 +1,6 @@ package fuego import ( - "fmt" "html/template" "log/slog" "net/http" @@ -58,42 +57,10 @@ func (s *Server) url() string { return s.proto() + "://" + s.Server.Addr } -// initializes any Context type with the base ContextNoBody context. -// -// var ctx ContextWithBody[any] // does not work because it will create a ContextWithBody[any] with a nil value -func initContext[Contextable ctx[Body], Body any](baseContext ContextNoBody) (Contextable, error) { - var c Contextable - - err := validateParams(baseContext) - if err != nil { - return c, err - } - - switch any(c).(type) { - case ContextNoBody: - return any(baseContext).(Contextable), nil - case *ContextNoBody: - return any(&baseContext).(Contextable), nil - case *ContextWithBody[Body]: - return any(&ContextWithBody[Body]{ - ContextNoBody: baseContext, - }).(Contextable), nil - default: - panic("unknown type") - } -} - // HTTPHandler converts a Fuego controller into a http.HandlerFunc. // Uses Server for configuration. // Uses Route for route configuration. Optional. -func HTTPHandler[ReturnType, Body any, Contextable ctx[Body]](s *Server, controller func(c Contextable) (ReturnType, error), route *BaseRoute) http.HandlerFunc { - // Just a check, not used at request time - baseContext := *new(Contextable) - if reflect.TypeOf(baseContext) == nil { - slog.Info(fmt.Sprintf("context is nil: %v %T", baseContext, baseContext)) - panic("ctx must be provided as concrete type (not interface). ContextNoBody, ContextWithBody[any], ContextFull[any, any], ContextWithQueryParams[any] are supported") - } - +func HTTPHandler[ReturnType, Body any](s *Server, controller func(c ContextWithBody[Body]) (ReturnType, error), route *BaseRoute) http.HandlerFunc { if route == nil { route = &BaseRoute{} } @@ -109,18 +76,22 @@ func HTTPHandler[ReturnType, Body any, Contextable ctx[Body]](s *Server, control templates = template.Must(s.template.Clone()) } - ctx, err := initContext[Contextable](ContextNoBody{ - Req: r, - Res: w, - readOptions: readOptions{ - DisallowUnknownFields: s.DisallowUnknownFields, - MaxBodySize: s.maxBodySize, + ctx := &contextWithBodyImpl[Body]{ + contextNoBodyImpl: contextNoBodyImpl{ + Req: r, + Res: w, + readOptions: readOptions{ + DisallowUnknownFields: s.DisallowUnknownFields, + MaxBodySize: s.maxBodySize, + }, + fs: s.fs, + templates: templates, + params: route.Params, + urlValues: r.URL.Query(), }, - fs: s.fs, - templates: templates, - params: route.Params, - urlValues: r.URL.Query(), - }) + } + + err := validateParams(ctx.contextNoBodyImpl) if err != nil { err = s.ErrorHandler(err) s.SerializeError(w, r, err) diff --git a/serve_test.go b/serve_test.go index 209ab156..2ac4f8e5 100644 --- a/serve_test.go +++ b/serve_test.go @@ -26,11 +26,11 @@ type ans struct { Ans string `json:"ans"` } -func testController(c *ContextNoBody) (ans, error) { +func testController(c ContextNoBody) (ans, error) { return ans{Ans: "Hello World"}, nil } -func testControllerWithError(c *ContextNoBody) (ans, error) { +func testControllerWithError(c ContextNoBody) (ans, error) { return ans{}, HTTPError{Err: errors.New("error happened!")} } @@ -47,27 +47,27 @@ func (t *testOutTransformer) OutTransform(ctx context.Context) error { var _ OutTransformer = &testOutTransformer{} -func testControllerWithOutTransformer(c *ContextNoBody) (testOutTransformer, error) { +func testControllerWithOutTransformer(c ContextNoBody) (testOutTransformer, error) { return testOutTransformer{Name: "John"}, nil } -func testControllerWithOutTransformerStar(c *ContextNoBody) (*testOutTransformer, error) { +func testControllerWithOutTransformerStar(c ContextNoBody) (*testOutTransformer, error) { return &testOutTransformer{Name: "John"}, nil } -func testControllerWithOutTransformerStarError(c *ContextNoBody) (*testOutTransformer, error) { +func testControllerWithOutTransformerStarError(c ContextNoBody) (*testOutTransformer, error) { return nil, HTTPError{Err: errors.New("error happened!")} } -func testControllerWithOutTransformerStarNil(c *ContextNoBody) (*testOutTransformer, error) { +func testControllerWithOutTransformerStarNil(c ContextNoBody) (*testOutTransformer, error) { return nil, nil } -func testControllerReturningString(c *ContextNoBody) (string, error) { +func testControllerReturningString(c ContextNoBody) (string, error) { return "hello world", nil } -func testControllerReturningPtrToString(c *ContextNoBody) (*string, error) { +func testControllerReturningPtrToString(c ContextNoBody) (*string, error) { s := "hello world" return &s, nil } @@ -186,7 +186,7 @@ func TestSetStatusBeforeSend(t *testing.T) { s := NewServer() t.Run("can set status before sending", func(t *testing.T) { - handler := HTTPHandler(s, func(c *ContextNoBody) (ans, error) { + handler := HTTPHandler(s, func(c ContextNoBody) (ans, error) { c.Response().WriteHeader(201) return ans{Ans: "Hello World"}, nil }, nil) @@ -202,7 +202,7 @@ func TestSetStatusBeforeSend(t *testing.T) { }) t.Run("can set status with the shortcut before sending", func(t *testing.T) { - handler := HTTPHandler(s, func(c *ContextNoBody) (ans, error) { + handler := HTTPHandler(s, func(c ContextNoBody) (ans, error) { c.SetStatus(202) return ans{Ans: "Hello World"}, nil }, nil) @@ -251,13 +251,13 @@ func TestServeRenderer(t *testing.T) { ) t.Run("can serve renderer", func(t *testing.T) { - Get(s, "/", func(c *ContextNoBody) (Renderer, error) { + Get(s, "/", func(c ContextNoBody) (Renderer, error) { return testRenderer{}, nil }) - Get(s, "/error-in-controller", func(c *ContextNoBody) (Renderer, error) { + Get(s, "/error-in-controller", func(c ContextNoBody) (Renderer, error) { return nil, errors.New("error") }) - Get(s, "/error-in-rendering", func(c *ContextNoBody) (Renderer, error) { + Get(s, "/error-in-rendering", func(c ContextNoBody) (Renderer, error) { return testErrorRenderer{}, nil }) @@ -290,13 +290,13 @@ func TestServeRenderer(t *testing.T) { }) t.Run("can serve ctx renderer", func(t *testing.T) { - Get(s, "/ctx", func(c *ContextNoBody) (CtxRenderer, error) { + Get(s, "/ctx", func(c ContextNoBody) (CtxRenderer, error) { return testCtxRenderer{}, nil }) - Get(s, "/ctx/error-in-controller", func(c *ContextNoBody) (CtxRenderer, error) { + Get(s, "/ctx/error-in-controller", func(c ContextNoBody) (CtxRenderer, error) { return nil, errors.New("error") }) - Get(s, "/ctx/error-in-rendering", func(c *ContextNoBody) (CtxRenderer, error) { + Get(s, "/ctx/error-in-rendering", func(c ContextNoBody) (CtxRenderer, error) { return testCtxErrorRenderer{}, nil }) @@ -332,7 +332,7 @@ func TestServeRenderer(t *testing.T) { func TestServeError(t *testing.T) { s := NewServer() - Get(s, "/ctx/error-in-controller", func(c *ContextNoBody) (CtxRenderer, error) { + Get(s, "/ctx/error-in-controller", func(c ContextNoBody) (CtxRenderer, error) { return nil, HTTPError{Err: errors.New("error")} }) @@ -351,11 +351,7 @@ func TestIni(t *testing.T) { t.Run("can initialize ContextNoBody", func(t *testing.T) { req := httptest.NewRequest("GET", "/ctx/error-in-rendering", nil) w := httptest.NewRecorder() - ctx, err := initContext[ContextNoBody](ContextNoBody{ - Req: req, - Res: w, - }) - require.NoError(t, err) + ctx := NewContextNoBody(w, req, readOptions{}) require.NotNil(t, ctx) require.NotNil(t, ctx.Request()) @@ -365,11 +361,7 @@ func TestIni(t *testing.T) { t.Run("can initialize ContextNoBody", func(t *testing.T) { req := httptest.NewRequest("GET", "/ctx/error-in-rendering", nil) w := httptest.NewRecorder() - ctx, err := initContext[*ContextNoBody](ContextNoBody{ - Req: req, - Res: w, - }) - require.NoError(t, err) + ctx := NewContextNoBody(w, req, readOptions{}) require.NotNil(t, ctx) require.NotNil(t, ctx.Request()) @@ -379,11 +371,7 @@ func TestIni(t *testing.T) { t.Run("can initialize ContextWithBody[string]", func(t *testing.T) { req := httptest.NewRequest("GET", "/ctx/error-in-rendering", nil) w := httptest.NewRecorder() - ctx, err := initContext[*ContextWithBody[string]](ContextNoBody{ - Req: req, - Res: w, - }) - require.NoError(t, err) + ctx := NewContextNoBody(w, req, readOptions{}) require.NotNil(t, ctx) require.NotNil(t, ctx.Request()) @@ -393,28 +381,12 @@ func TestIni(t *testing.T) { t.Run("can initialize ContextWithBody[struct]", func(t *testing.T) { req := httptest.NewRequest("GET", "/ctx/error-in-rendering", nil) w := httptest.NewRecorder() - ctx, err := initContext[*ContextWithBody[ans]](ContextNoBody{ - Req: req, - Res: w, - }) - require.NoError(t, err) + ctx := NewContextNoBody(w, req, readOptions{}) require.NotNil(t, ctx) require.NotNil(t, ctx.Request()) require.NotNil(t, ctx.Response()) }) - - t.Run("cannot initialize with Ctx interface", func(t *testing.T) { - req := httptest.NewRequest("GET", "/ctx/error-in-rendering", nil) - w := httptest.NewRecorder() - - require.Panics(t, func() { - initContext[ctx[any]](ContextNoBody{ - Req: req, - Res: w, - }) - }) - }) } func TestServer_Run(t *testing.T) { @@ -425,7 +397,7 @@ func TestServer_Run(t *testing.T) { WithoutLogger(), ) - Get(s, "/test", func(ctx *ContextNoBody) (string, error) { + Get(s, "/test", func(ctx ContextNoBody) (string, error) { return "OK", nil }) @@ -495,7 +467,7 @@ func TestServer_RunTLS(t *testing.T) { s.Server.TLSConfig = tc.tlsConfig } - Get(s, "/test", func(ctx *ContextNoBody) (string, error) { + Get(s, "/test", func(ctx ContextNoBody) (string, error) { return "OK", nil }) diff --git a/server.go b/server.go index 221bc6e6..e60bf333 100644 --- a/server.go +++ b/server.go @@ -234,7 +234,7 @@ func WithSecurity(schemes openapi3.SecuritySchemes) func(*Server) { // For example: // // recipeGroup := fuego.Group(s, "/recipes") -// fuego.Get(recipeGroup, "/", func(*ContextNoBody) (ans, error) { +// fuego.Get(recipeGroup, "/", func(ContextNoBody) (ans, error) { // return ans{}, nil // }) // diff --git a/server_test.go b/server_test.go index bcaa08e3..45dd8bcd 100644 --- a/server_test.go +++ b/server_test.go @@ -15,11 +15,11 @@ import ( "github.com/stretchr/testify/require" ) -func controller(c *ContextNoBody) (testStruct, error) { +func controller(c ContextNoBody) (testStruct, error) { return testStruct{Name: "Ewen", Age: 23}, nil } -func controllerWithError(c *ContextNoBody) (testStruct, error) { +func controllerWithError(c ContextNoBody) (testStruct, error) { return testStruct{}, HTTPError{Err: errors.New("error")} } @@ -309,7 +309,7 @@ type Resp struct { Message string `json:"message"` } -func dummyController(_ *ContextWithBody[ReqBody]) (Resp, error) { +func dummyController(_ ContextWithBody[ReqBody]) (Resp, error) { return Resp{Message: "hello world"}, nil } @@ -348,7 +348,7 @@ func TestCustomSerialization(t *testing.T) { }), ) - Get(s, "/", func(c *ContextNoBody) (ans, error) { + Get(s, "/", func(c ContextNoBody) (ans, error) { return ans{Ans: "Hello World"}, nil }) diff --git a/validate_params.go b/validate_params.go index c69727eb..f1e0c1ec 100644 --- a/validate_params.go +++ b/validate_params.go @@ -2,7 +2,7 @@ package fuego import "fmt" -func validateParams(c ContextNoBody) error { +func validateParams(c contextNoBodyImpl) error { for k, param := range c.params { if param.Default != nil { // skip: param has a default From 2d3fbb831088eb49d0f2a6061544c6da18aeb418 Mon Sep 17 00:00:00 2001 From: EwenQuim Date: Thu, 19 Dec 2024 10:34:21 +0100 Subject: [PATCH 094/138] Remove useless contextNoBodyImpl type --- ctx.go | 111 +++++++++++++++++---------------------------- ctx_test.go | 52 ++++++++++----------- serve.go | 24 +++++----- serve_test.go | 8 ++-- validate_params.go | 2 +- 5 files changed, 83 insertions(+), 114 deletions(-) diff --git a/ctx.go b/ctx.go index 57e06a0c..53ca5874 100644 --- a/ctx.go +++ b/ctx.go @@ -25,6 +25,7 @@ type ContextNoBody = ContextWithBody[any] // Please do not use a pointer type as parameter. type ContextWithBody[B any] interface { context.Context + // Body returns the body of the request. // If (*B) implements [InTransformer], it will be transformed after deserialization. // It caches the result, so it can be called multiple times. @@ -94,17 +95,9 @@ type ContextWithBody[B any] interface { Redirect(code int, url string) (any, error) } -// NewContextWithBody returns a new context. It is used internally by Fuego. You probably want to use Ctx[B] instead. -func NewContextWithBody[B any](w http.ResponseWriter, r *http.Request, options readOptions) ContextWithBody[B] { - c := &contextWithBodyImpl[B]{ - contextNoBodyImpl: NewContextNoBody(w, r, options), - } - - return c -} - -func NewContextNoBody(w http.ResponseWriter, r *http.Request, options readOptions) contextNoBodyImpl { - c := contextNoBodyImpl{ +// NewNetHTTPContext returns a new context. It is used internally by Fuego. You probably want to use Ctx[B] instead. +func NewNetHTTPContext[B any](w http.ResponseWriter, r *http.Request, options readOptions) ContextWithBody[B] { + c := &netHttpContext[B]{ Res: w, Req: r, readOptions: readOptions{ @@ -113,25 +106,21 @@ func NewContextNoBody(w http.ResponseWriter, r *http.Request, options readOption }, urlValues: r.URL.Query(), } + return c } +var ( + _ ContextWithBody[any] = &netHttpContext[any]{} // Check that ContextWithBody implements Ctx. + _ ContextWithBody[string] = &netHttpContext[string]{} // Check that ContextWithBody implements Ctx. +) + // ContextWithBody is the same as fuego.ContextNoBody, but // has a Body. The Body type parameter represents the expected data type // from http.Request.Body. Please do not use a pointer as a type parameter. -type contextWithBodyImpl[Body any] struct { +type netHttpContext[Body any] struct { body *Body // Cache the body in request context, because it is not possible to read an HTTP request body multiple times. - contextNoBodyImpl -} - -var ( - _ ContextWithBody[any] = &contextWithBodyImpl[any]{} // Check that ContextWithBody implements Ctx. - _ ContextWithBody[string] = &contextWithBodyImpl[string]{} // Check that ContextWithBody implements Ctx. -) -// ContextNoBody is used when the controller does not have a body. -// It is used as a base context for other Context types. -type contextNoBodyImpl struct { Req *http.Request Res http.ResponseWriter @@ -144,27 +133,9 @@ type contextNoBodyImpl struct { readOptions readOptions } -var ( - _ ContextWithBody[any] = contextNoBodyImpl{} // Check that ContextNoBody implements Ctx. - _ context.Context = contextNoBodyImpl{} // Check that ContextNoBody implements context.Context. -) - -func (c contextNoBodyImpl) Body() (any, error) { - slog.Warn("this method should not be called. It probably happened because you passed the context to another controller.") - return body[map[string]any](c) -} - -func (c contextNoBodyImpl) MustBody() any { - b, err := c.Body() - if err != nil { - panic(err) - } - return b -} - // SetStatus sets the status code of the response. // Alias to http.ResponseWriter.WriteHeader. -func (c contextNoBodyImpl) SetStatus(code int) { +func (c netHttpContext[B]) SetStatus(code int) { c.Res.WriteHeader(code) } @@ -175,65 +146,65 @@ type readOptions struct { LogBody bool } -func (c contextNoBodyImpl) Redirect(code int, url string) (any, error) { +func (c netHttpContext[B]) Redirect(code int, url string) (any, error) { http.Redirect(c.Res, c.Req, url, code) return nil, nil } // ContextNoBody implements the context interface via [net/http.Request.Context] -func (c contextNoBodyImpl) Deadline() (deadline time.Time, ok bool) { +func (c netHttpContext[B]) Deadline() (deadline time.Time, ok bool) { return c.Req.Context().Deadline() } // ContextNoBody implements the context interface via [net/http.Request.Context] -func (c contextNoBodyImpl) Done() <-chan struct{} { +func (c netHttpContext[B]) Done() <-chan struct{} { return c.Req.Context().Done() } // ContextNoBody implements the context interface via [net/http.Request.Context] -func (c contextNoBodyImpl) Err() error { +func (c netHttpContext[B]) Err() error { return c.Req.Context().Err() } // ContextNoBody implements the context interface via [net/http.Request.Context] -func (c contextNoBodyImpl) Value(key any) any { +func (c netHttpContext[B]) Value(key any) any { return c.Req.Context().Value(key) } // ContextNoBody implements the context interface via [net/http.Request.Context] -func (c contextNoBodyImpl) Context() context.Context { +func (c netHttpContext[B]) Context() context.Context { return c.Req.Context() } // Get request header -func (c contextNoBodyImpl) Header(key string) string { +func (c netHttpContext[B]) Header(key string) string { return c.Request().Header.Get(key) } // Has request header -func (c contextNoBodyImpl) HasHeader(key string) bool { +func (c netHttpContext[B]) HasHeader(key string) bool { return c.Header(key) != "" } // Sets response header -func (c contextNoBodyImpl) SetHeader(key, value string) { +func (c netHttpContext[B]) SetHeader(key, value string) { c.Response().Header().Set(key, value) } // Get request cookie -func (c contextNoBodyImpl) Cookie(name string) (*http.Cookie, error) { +func (c netHttpContext[B]) Cookie(name string) (*http.Cookie, error) { return c.Request().Cookie(name) } // Has request cookie -func (c contextNoBodyImpl) HasCookie(name string) bool { +func (c netHttpContext[B]) HasCookie(name string) bool { _, err := c.Cookie(name) return err == nil } // Sets response cookie -func (c contextNoBodyImpl) SetCookie(cookie http.Cookie) { +func (c netHttpContext[B]) SetCookie(cookie http.Cookie) { http.SetCookie(c.Response(), &cookie) } @@ -245,7 +216,7 @@ func (c contextNoBodyImpl) SetCookie(cookie http.Cookie) { // that the templates will be parsed only once, removing // the need to parse the templates on each request but also preventing // to dynamically use new templates. -func (c contextNoBodyImpl) Render(templateToExecute string, data any, layoutsGlobs ...string) (CtxRenderer, error) { +func (c netHttpContext[B]) Render(templateToExecute string, data any, layoutsGlobs ...string) (CtxRenderer, error) { return &StdRenderer{ templateToExecute: templateToExecute, templates: c.templates, @@ -256,7 +227,7 @@ func (c contextNoBodyImpl) Render(templateToExecute string, data any, layoutsGlo } // PathParams returns the path parameters of the request. -func (c contextNoBodyImpl) PathParam(name string) string { +func (c netHttpContext[B]) PathParam(name string) string { return c.Req.PathValue(name) } @@ -280,12 +251,12 @@ func (e QueryParamInvalidTypeError) Error() string { } // QueryParams returns the query parameters of the request. It is a shortcut for c.Req.URL.Query(). -func (c contextNoBodyImpl) QueryParams() url.Values { +func (c netHttpContext[B]) QueryParams() url.Values { return c.urlValues } // QueryParamsArr returns an slice of string from the given query parameter. -func (c contextNoBodyImpl) QueryParamArr(name string) []string { +func (c netHttpContext[B]) QueryParamArr(name string) []string { _, ok := c.params[name] if !ok { slog.Warn("query parameter not expected in OpenAPI spec", "param", name) @@ -301,7 +272,7 @@ func (c contextNoBodyImpl) QueryParamArr(name string) []string { // fuego.Get(s, "/test", myController, // option.Query("name", "Name", param.Default("hey")) // ) -func (c contextNoBodyImpl) QueryParam(name string) string { +func (c netHttpContext[B]) QueryParam(name string) string { _, ok := c.params[name] if !ok { slog.Warn("query parameter not expected in OpenAPI spec", "param", name, "expected_one_of", c.params) @@ -314,7 +285,7 @@ func (c contextNoBodyImpl) QueryParam(name string) string { return c.urlValues.Get(name) } -func (c contextNoBodyImpl) QueryParamIntErr(name string) (int, error) { +func (c netHttpContext[B]) QueryParamIntErr(name string) (int, error) { param := c.QueryParam(name) if param == "" { defaultValue, ok := c.params[name].Default.(int) @@ -348,7 +319,7 @@ func (c contextNoBodyImpl) QueryParamIntErr(name string) (int, error) { // // and the query parameter does not exist, it will return 1. // If the query parameter does not exist and there is no default value, or if it is not an int, it returns 0. -func (c contextNoBodyImpl) QueryParamInt(name string) int { +func (c netHttpContext[B]) QueryParamInt(name string) int { param, err := c.QueryParamIntErr(name) if err != nil { return 0 @@ -367,7 +338,7 @@ func (c contextNoBodyImpl) QueryParamInt(name string) int { // // and the query parameter does not exist in the HTTP request, it will return true. // Accepted values are defined as [strconv.ParseBool] -func (c contextNoBodyImpl) QueryParamBoolErr(name string) (bool, error) { +func (c netHttpContext[B]) QueryParamBoolErr(name string) (bool, error) { param := c.QueryParam(name) if param == "" { defaultValue, ok := c.params[name].Default.(bool) @@ -400,7 +371,7 @@ func (c contextNoBodyImpl) QueryParamBoolErr(name string) (bool, error) { // ) // // and the query parameter does not exist in the HTTP request, it will return true. -func (c contextNoBodyImpl) QueryParamBool(name string) bool { +func (c netHttpContext[B]) QueryParamBool(name string) bool { param, err := c.QueryParamBoolErr(name) if err != nil { return false @@ -409,26 +380,26 @@ func (c contextNoBodyImpl) QueryParamBool(name string) bool { return param } -func (c contextNoBodyImpl) MainLang() string { +func (c netHttpContext[B]) MainLang() string { return strings.Split(c.MainLocale(), "-")[0] } -func (c contextNoBodyImpl) MainLocale() string { +func (c netHttpContext[B]) MainLocale() string { return strings.Split(c.Req.Header.Get("Accept-Language"), ",")[0] } // Request returns the HTTP request. -func (c contextNoBodyImpl) Request() *http.Request { +func (c netHttpContext[B]) Request() *http.Request { return c.Req } // Response returns the HTTP response writer. -func (c contextNoBodyImpl) Response() http.ResponseWriter { +func (c netHttpContext[B]) Response() http.ResponseWriter { return c.Res } // MustBody works like Body, but panics if there is an error. -func (c *contextWithBodyImpl[B]) MustBody() B { +func (c *netHttpContext[B]) MustBody() B { b, err := c.Body() if err != nil { panic(err) @@ -441,17 +412,17 @@ func (c *contextWithBodyImpl[B]) MustBody() B { // It caches the result, so it can be called multiple times. // The reason the body is cached is that it is impossible to read an HTTP request body multiple times, not because of performance. // For decoding, it uses the Content-Type header. If it is not set, defaults to application/json. -func (c *contextWithBodyImpl[B]) Body() (B, error) { +func (c *netHttpContext[B]) Body() (B, error) { if c.body != nil { return *c.body, nil } - body, err := body[B](c.contextNoBodyImpl) + body, err := body[B](*c) c.body = &body return body, err } -func body[B any](c contextNoBodyImpl) (B, error) { +func body[B any](c netHttpContext[B]) (B, error) { // Limit the size of the request body. if c.readOptions.MaxBodySize != 0 { c.Req.Body = http.MaxBytesReader(nil, c.Req.Body, c.readOptions.MaxBodySize) diff --git a/ctx_test.go b/ctx_test.go index 7943c407..575d3c8d 100644 --- a/ctx_test.go +++ b/ctx_test.go @@ -46,7 +46,7 @@ func TestContext_QueryParam(t *testing.T) { r := httptest.NewRequest("GET", "http://example.com/foo/123?id=456&other=hello&boo=true&name=jhon&name=doe", nil) w := httptest.NewRecorder() - c := NewContextWithBody[any](w, r, readOptions{}) + c := NewNetHTTPContext[any](w, r, readOptions{}) t.Run("string", func(t *testing.T) { param := c.QueryParam("other") @@ -124,7 +124,7 @@ func TestContext_QueryParams(t *testing.T) { r := httptest.NewRequest("GET", "http://example.com/foo/123?id=456&other=hello", nil) w := httptest.NewRecorder() - c := NewContextWithBody[any](w, r, readOptions{}) + c := NewNetHTTPContext[any](w, r, readOptions{}) params := c.QueryParams() require.NotEmpty(t, params) @@ -168,7 +168,7 @@ func TestContext_Body(t *testing.T) { w := httptest.NewRecorder() r := httptest.NewRequest("GET", "http://example.com/foo", a) - c := NewContextWithBody[testStruct](w, r, readOptions{}) + c := NewNetHTTPContext[testStruct](w, r, readOptions{}) body, err := c.Body() require.NoError(t, err) @@ -185,7 +185,7 @@ func TestContext_Body(t *testing.T) { r := httptest.NewRequest("GET", "http://example.com/foo", a) r.Header.Add("Content-Type", "application/json") - c := NewContextWithBody[testStruct](w, r, readOptions{}) + c := NewNetHTTPContext[testStruct](w, r, readOptions{}) body, err := c.Body() require.NoError(t, err) @@ -199,7 +199,7 @@ func TestContext_Body(t *testing.T) { w := httptest.NewRecorder() r := httptest.NewRequest("GET", "http://example.com/foo", a) - c := NewContextWithBody[testStruct](w, r, readOptions{}) + c := NewNetHTTPContext[testStruct](w, r, readOptions{}) body, err := c.Body() require.NoError(t, err) @@ -219,7 +219,7 @@ func TestContext_Body(t *testing.T) { } reqBody := strings.NewReader(`{"name":"John","age":30}`) - c := NewContextWithBody[testStruct]( + c := NewNetHTTPContext[testStruct]( httptest.NewRecorder(), httptest.NewRequest("GET", "http://example.com/foo", reqBody), readOptions{}) @@ -237,7 +237,7 @@ func TestContext_Body(t *testing.T) { } reqBody := strings.NewReader(`{"name":"VeryLongName","age":12}`) - c := NewContextWithBody[testStruct]( + c := NewNetHTTPContext[testStruct]( httptest.NewRecorder(), httptest.NewRequest("GET", "http://example.com/foo", reqBody), readOptions{}) @@ -250,7 +250,7 @@ func TestContext_Body(t *testing.T) { t.Run("can transform JSON body with custom method", func(t *testing.T) { reqBody := strings.NewReader(`{"name":"John","age":30}`) - c := NewContextWithBody[testStructInTransformer]( + c := NewNetHTTPContext[testStructInTransformer]( httptest.NewRecorder(), httptest.NewRequest("GET", "http://example.com/foo", reqBody), readOptions{}) @@ -263,7 +263,7 @@ func TestContext_Body(t *testing.T) { t.Run("can transform JSON body with custom method returning error", func(t *testing.T) { reqBody := strings.NewReader(`{"name":"John","age":30}`) - c := NewContextWithBody[testStructInTransformerWithError]( + c := NewNetHTTPContext[testStructInTransformerWithError]( httptest.NewRecorder(), httptest.NewRequest("GET", "http://example.com/foo", reqBody), readOptions{}) @@ -283,7 +283,7 @@ func TestContext_Body(t *testing.T) { r := httptest.NewRequest("GET", "http://example.com/foo", a) r.Header.Add("Content-Type", "application/octet-stream") - c := NewContextWithBody[[]byte](w, r, readOptions{}) + c := NewNetHTTPContext[[]byte](w, r, readOptions{}) body, err := c.Body() require.NoError(t, err) require.Equal(t, []byte(`image`), body) @@ -298,7 +298,7 @@ func TestContext_Body(t *testing.T) { r := httptest.NewRequest("GET", "http://example.com/foo", a) r.Header.Add("Content-Type", "application/octet-stream") - c := NewContextWithBody[*struct{}](w, r, readOptions{}) + c := NewNetHTTPContext[*struct{}](w, r, readOptions{}) body, err := c.Body() require.Error(t, err) require.ErrorContains(t, err, "use []byte as the body type") @@ -317,7 +317,7 @@ func TestContext_Body(t *testing.T) { r := httptest.NewRequest("GET", "http://example.com/foo", a) r.Header.Add("Content-Type", "application/xml") - c := NewContextWithBody[testStruct](w, r, readOptions{}) + c := NewNetHTTPContext[testStruct](w, r, readOptions{}) body, err := c.Body() require.NoError(t, err) @@ -335,7 +335,7 @@ age: 30 r := httptest.NewRequest("GET", "http://example.com/foo", a) r.Header.Add("Content-Type", "application/x-yaml") - c := NewContextWithBody[testStruct](w, r, readOptions{}) + c := NewNetHTTPContext[testStruct](w, r, readOptions{}) body, err := c.Body() require.NoError(t, err) @@ -345,7 +345,7 @@ age: 30 t.Run("unparsable because restricted to 1 byte", func(t *testing.T) { reqBody := strings.NewReader(`{"name":"John","age":30}`) - c := NewContextWithBody[testStructInTransformerWithError]( + c := NewNetHTTPContext[testStructInTransformerWithError]( httptest.NewRecorder(), httptest.NewRequest("GET", "http://example.com/foo", reqBody), readOptions{ @@ -367,7 +367,7 @@ age: 30 r := httptest.NewRequest("GET", "http://example.com/foo", a) r.Header.Set("Content-Type", "text/plain") - c := NewContextWithBody[string](w, r, readOptions{}) + c := NewNetHTTPContext[string](w, r, readOptions{}) _, err := c.Body() require.NoError(t, err) @@ -386,7 +386,7 @@ func FuzzContext_Body(f *testing.F) { r := httptest.NewRequest("GET", "http://example.com/foo", a) r.Header.Set("Content-Type", "application/x-www-form-urlencoded") - c := NewContextWithBody[testStruct](w, r, readOptions{}) + c := NewNetHTTPContext[testStruct](w, r, readOptions{}) _, err := c.Body() require.NoError(t, err) @@ -397,7 +397,7 @@ func BenchmarkContext_Body(b *testing.B) { b.Run("valid JSON body", func(b *testing.B) { for i := range b.N { reqBody := strings.NewReader(`{"name":"John","age":30}`) - c := NewContextWithBody[testStruct]( + c := NewNetHTTPContext[testStruct]( httptest.NewRecorder(), httptest.NewRequest("GET", "http://example.com/foo", reqBody), readOptions{}) @@ -413,7 +413,7 @@ func BenchmarkContext_Body(b *testing.B) { // See [Body] for more information. b.Run("valid JSON body cache", func(b *testing.B) { reqBody := strings.NewReader(`{"name":"John","age":30}`) - c := NewContextWithBody[testStruct]( + c := NewNetHTTPContext[testStruct]( httptest.NewRecorder(), httptest.NewRequest("GET", "http://example.com/foo", reqBody), readOptions{}) @@ -428,7 +428,7 @@ func BenchmarkContext_Body(b *testing.B) { b.Run("invalid JSON body", func(b *testing.B) { for range b.N { reqBody := strings.NewReader(`{"name":"John","age":30}`) - c := NewContextWithBody[testStruct]( + c := NewNetHTTPContext[testStruct]( httptest.NewRecorder(), httptest.NewRequest("GET", "http://example.com/foo", reqBody), readOptions{}) @@ -442,7 +442,7 @@ func BenchmarkContext_Body(b *testing.B) { b.Run("string body", func(b *testing.B) { for range b.N { reqBody := strings.NewReader(`{"name":"John","age":30}`) - c := NewContextWithBody[testStruct]( + c := NewNetHTTPContext[testStruct]( httptest.NewRecorder(), httptest.NewRequest("GET", "http://example.com/foo", reqBody), readOptions{}) @@ -463,7 +463,7 @@ func TestContext_MustBody(t *testing.T) { w := httptest.NewRecorder() r := httptest.NewRequest("GET", "http://example.com/foo", a) - c := NewContextWithBody[testStruct](w, r, readOptions{}) + c := NewNetHTTPContext[testStruct](w, r, readOptions{}) body := c.MustBody() require.Equal(t, "John", body.Name) @@ -477,7 +477,7 @@ func TestContext_MustBody(t *testing.T) { } reqBody := strings.NewReader(`{"name":"VeryLongName","age":12}`) - c := NewContextWithBody[testStruct]( + c := NewNetHTTPContext[testStruct]( httptest.NewRecorder(), httptest.NewRequest("GET", "http://example.com/foo", reqBody), readOptions{}) @@ -492,7 +492,7 @@ func TestMainLang(t *testing.T) { r := httptest.NewRequest("GET", "/", nil) r.Header.Set("Accept-Language", "fr-CH, fr;q=0.9, en;q=0.8, de;q=0.7, *;q=0.5") - c := NewContextWithBody[any](httptest.NewRecorder(), r, readOptions{}) + c := NewNetHTTPContext[any](httptest.NewRecorder(), r, readOptions{}) require.Equal(t, c.MainLang(), "fr") require.Equal(t, c.MainLocale(), "fr-CH") } @@ -500,7 +500,7 @@ func TestMainLang(t *testing.T) { func TestContextNoBody_Body(t *testing.T) { body := `{"name":"John","age":30}` r := httptest.NewRequest("GET", "/", strings.NewReader(body)) - ctx := contextNoBodyImpl{ + ctx := netHttpContext[any]{ Req: r, Res: httptest.NewRecorder(), } @@ -516,7 +516,7 @@ func TestContextNoBody_MustBody(t *testing.T) { t.Run("can read JSON body", func(t *testing.T) { body := `{"name":"John","age":30}` r := httptest.NewRequest("GET", "/", strings.NewReader(body)) - ctx := contextNoBodyImpl{ + ctx := netHttpContext[any]{ Req: r, Res: httptest.NewRecorder(), } @@ -530,7 +530,7 @@ func TestContextNoBody_MustBody(t *testing.T) { t.Run("cannot read invalid JSON body", func(t *testing.T) { body := `{"name":"John","age":30` r := httptest.NewRequest("GET", "/", strings.NewReader(body)) - ctx := contextNoBodyImpl{ + ctx := netHttpContext[any]{ Req: r, Res: httptest.NewRecorder(), } diff --git a/serve.go b/serve.go index dd92208f..f6c0e4a8 100644 --- a/serve.go +++ b/serve.go @@ -76,22 +76,20 @@ func HTTPHandler[ReturnType, Body any](s *Server, controller func(c ContextWithB templates = template.Must(s.template.Clone()) } - ctx := &contextWithBodyImpl[Body]{ - contextNoBodyImpl: contextNoBodyImpl{ - Req: r, - Res: w, - readOptions: readOptions{ - DisallowUnknownFields: s.DisallowUnknownFields, - MaxBodySize: s.maxBodySize, - }, - fs: s.fs, - templates: templates, - params: route.Params, - urlValues: r.URL.Query(), + ctx := &netHttpContext[Body]{ + Req: r, + Res: w, + readOptions: readOptions{ + DisallowUnknownFields: s.DisallowUnknownFields, + MaxBodySize: s.maxBodySize, }, + fs: s.fs, + templates: templates, + params: route.Params, + urlValues: r.URL.Query(), } - err := validateParams(ctx.contextNoBodyImpl) + err := validateParams(*ctx) if err != nil { err = s.ErrorHandler(err) s.SerializeError(w, r, err) diff --git a/serve_test.go b/serve_test.go index 2ac4f8e5..18540c9c 100644 --- a/serve_test.go +++ b/serve_test.go @@ -351,7 +351,7 @@ func TestIni(t *testing.T) { t.Run("can initialize ContextNoBody", func(t *testing.T) { req := httptest.NewRequest("GET", "/ctx/error-in-rendering", nil) w := httptest.NewRecorder() - ctx := NewContextNoBody(w, req, readOptions{}) + ctx := NewNetHTTPContext[any](w, req, readOptions{}) require.NotNil(t, ctx) require.NotNil(t, ctx.Request()) @@ -361,7 +361,7 @@ func TestIni(t *testing.T) { t.Run("can initialize ContextNoBody", func(t *testing.T) { req := httptest.NewRequest("GET", "/ctx/error-in-rendering", nil) w := httptest.NewRecorder() - ctx := NewContextNoBody(w, req, readOptions{}) + ctx := NewNetHTTPContext[any](w, req, readOptions{}) require.NotNil(t, ctx) require.NotNil(t, ctx.Request()) @@ -371,7 +371,7 @@ func TestIni(t *testing.T) { t.Run("can initialize ContextWithBody[string]", func(t *testing.T) { req := httptest.NewRequest("GET", "/ctx/error-in-rendering", nil) w := httptest.NewRecorder() - ctx := NewContextNoBody(w, req, readOptions{}) + ctx := NewNetHTTPContext[any](w, req, readOptions{}) require.NotNil(t, ctx) require.NotNil(t, ctx.Request()) @@ -381,7 +381,7 @@ func TestIni(t *testing.T) { t.Run("can initialize ContextWithBody[struct]", func(t *testing.T) { req := httptest.NewRequest("GET", "/ctx/error-in-rendering", nil) w := httptest.NewRecorder() - ctx := NewContextNoBody(w, req, readOptions{}) + ctx := NewNetHTTPContext[any](w, req, readOptions{}) require.NotNil(t, ctx) require.NotNil(t, ctx.Request()) diff --git a/validate_params.go b/validate_params.go index f1e0c1ec..d29d2b5c 100644 --- a/validate_params.go +++ b/validate_params.go @@ -2,7 +2,7 @@ package fuego import "fmt" -func validateParams(c contextNoBodyImpl) error { +func validateParams[B any](c netHttpContext[B]) error { for k, param := range c.params { if param.Default != nil { // skip: param has a default From 235810bb3af0f07721ac9fead799876677a59fe2 Mon Sep 17 00:00:00 2001 From: ignaciojeria Date: Sat, 30 Nov 2024 12:43:12 -0300 Subject: [PATCH 095/138] Customizable net.Listener for advanced use cases, such as tunneling (e.g., zrok, ngrok). --- serve.go | 3 +++ server.go | 3 +++ 2 files changed, 6 insertions(+) diff --git a/serve.go b/serve.go index f6c0e4a8..a1d24d75 100644 --- a/serve.go +++ b/serve.go @@ -14,6 +14,9 @@ import ( // It also generates the OpenAPI spec and outputs it to a file, the UI, and a handler (if enabled). func (s *Server) Run() error { s.setup() + if s.Listener != nil { + return s.Server.Serve(s.Listener) + } return s.Server.ListenAndServe() } diff --git a/server.go b/server.go index e60bf333..0d1c59de 100644 --- a/server.go +++ b/server.go @@ -6,6 +6,7 @@ import ( "io" "io/fs" "log/slog" + "net" "net/http" "os" "time" @@ -60,6 +61,8 @@ type Server struct { // Points to the server OpenAPI struct. OpenAPI *OpenAPI + Listener net.Listener // Customizable net.Listener for advanced use cases, such as tunneling (e.g., zrok, ngrok). + Security Security autoAuth AutoAuthConfig From 5b9e3dd4e6de1a8633f4ec70f76a799411d4e88d Mon Sep 17 00:00:00 2001 From: ignaciojeria Date: Sun, 1 Dec 2024 04:00:57 -0300 Subject: [PATCH 096/138] Refactor Listener setup with enhanced validation and error messages --- serve.go | 61 +++++++++++++++++++++++++++++++++++++++++++++++++------ server.go | 37 ++++++++++++++++++++++++++++++++- 2 files changed, 91 insertions(+), 7 deletions(-) diff --git a/serve.go b/serve.go index a1d24d75..833b3a6a 100644 --- a/serve.go +++ b/serve.go @@ -1,8 +1,12 @@ package fuego import ( + "crypto/tls" + "errors" + "fmt" "html/template" "log/slog" + "net" "net/http" "reflect" "time" @@ -13,11 +17,11 @@ import ( // It returns an error if the server could not start (it could not bind to the port for example). // It also generates the OpenAPI spec and outputs it to a file, the UI, and a handler (if enabled). func (s *Server) Run() error { - s.setup() - if s.Listener != nil { - return s.Server.Serve(s.Listener) + if err := s.setupDefaultListener(); err != nil { + return fmt.Errorf("failed to start server: %w", err) } - return s.Server.ListenAndServe() + s.setup() + return s.Server.Serve(s.listener) } // RunTLS starts the server with a TLS listener @@ -26,9 +30,11 @@ func (s *Server) Run() error { // It also generates the OpenAPI spec and outputs it to a file, the UI, and a handler (if enabled). func (s *Server) RunTLS(certFile, keyFile string) error { s.isTLS = true - + if err := s.setupTLSListener(certFile, keyFile); err != nil { + return fmt.Errorf("failed to start TLS server: %w", err) + } s.setup() - return s.Server.ListenAndServeTLS(certFile, keyFile) + return s.Server.Serve(s.listener) } func (s *Server) setup() { @@ -41,6 +47,49 @@ func (s *Server) setup() { } } +// setupTLSListener creates a TLS listener if no listener is already configured. +// If a non-TLS listener is already configured, an error is returned. +// Requires valid TLS certificate and key files to establish a secure listener. +// Returns an error if the listener cannot be created or if the provided certificates are invalid. +func (s *Server) setupTLSListener(certFile, keyFile string) error { + if s.listener != nil && !s.isTLS { + return errors.New("a non-TLS listener is already configured; cannot set up a TLS listener on the same server") + } + if s.listener != nil { + return errors.New("a TLS listener is already configured; use the Run() method to start the server") + } + if certFile == "" || keyFile == "" { + return errors.New("TLS certificate and key files must be provided to set up a TLS listener") + } + cert, err := tls.LoadX509KeyPair(certFile, keyFile) + if err != nil { + return fmt.Errorf("failed to load TLS certificate and key files (%s, %s): %w", certFile, keyFile, err) + } + tlsConfig := &tls.Config{Certificates: []tls.Certificate{cert}} + + listener, err := tls.Listen("tcp", s.Server.Addr, tlsConfig) + if err != nil { + return fmt.Errorf("failed to create a TLS listener on address %s: %w", s.Server.Addr, err) + } + s.listener = listener + return nil +} + +// setupDefaultListener creates a default (non-TLS) listener if none is already configured. +// If a listener is already set, this method does nothing. +// Returns an error if the listener cannot be created (e.g., address binding issues). +func (s *Server) setupDefaultListener() error { + if s.listener != nil { + return nil // Listener already exists, no action needed. + } + listener, err := net.Listen("tcp", s.Server.Addr) + if err != nil { + return fmt.Errorf("failed to create default listener on %s: %w", s.Server.Addr, err) + } + s.listener = listener + return nil +} + func (s *Server) printStartupMessage() { if !s.disableStartupMessages { elapsed := time.Since(s.startTime) diff --git a/server.go b/server.go index 0d1c59de..de49ae79 100644 --- a/server.go +++ b/server.go @@ -1,6 +1,7 @@ package fuego import ( + "crypto/tls" "fmt" "html/template" "io" @@ -61,7 +62,9 @@ type Server struct { // Points to the server OpenAPI struct. OpenAPI *OpenAPI - Listener net.Listener // Customizable net.Listener for advanced use cases, such as tunneling (e.g., zrok, ngrok). + listener net.Listener + + tlsConfig *tls.Config Security Security @@ -376,6 +379,38 @@ func WithoutLogger() func(*Server) { } } +func WithListener(listener net.Listener) func(*Server) { + return func(s *Server) { + setListener(s, listener) + } +} + +// WithTLSListener configures the server to use a TLS listener with the provided certificates. +// It ensures the provided listener is wrapped with TLS using the given cert and key files. +func WithTLSListener(listener net.Listener, certFile, keyFile string) func(*Server) { + return func(s *Server) { + if certFile == "" || keyFile == "" { + panic("TLS certificates must be provided (certFile and keyFile)") + } + cert, err := tls.LoadX509KeyPair(certFile, keyFile) + if err != nil { + panic(fmt.Errorf("failed to load TLS certificates: %w", err)) + } + tlsConfig := &tls.Config{Certificates: []tls.Certificate{cert}} + tlsListener := tls.NewListener(listener, tlsConfig) + s.tlsConfig = tlsConfig + s.isTLS = true + setListener(s, tlsListener) + } +} + +func setListener(s *Server, listener net.Listener) { + if s.listener != nil { + panic("listener already configured") + } + s.listener = listener +} + func WithOpenAPIConfig(openapiConfig OpenAPIConfig) func(*Server) { return func(s *Server) { if openapiConfig.JsonUrl != "" { From 1765cc7ea89134370592ba3427661c563d21bdbf Mon Sep 17 00:00:00 2001 From: ignaciojeria Date: Sun, 1 Dec 2024 04:10:00 -0300 Subject: [PATCH 097/138] Set isTLS after successful TLS listener setup --- serve.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/serve.go b/serve.go index 833b3a6a..17c96e4f 100644 --- a/serve.go +++ b/serve.go @@ -29,7 +29,6 @@ func (s *Server) Run() error { // It returns an error if the server could not start (it could not bind to the port for example). // It also generates the OpenAPI spec and outputs it to a file, the UI, and a handler (if enabled). func (s *Server) RunTLS(certFile, keyFile string) error { - s.isTLS = true if err := s.setupTLSListener(certFile, keyFile); err != nil { return fmt.Errorf("failed to start TLS server: %w", err) } @@ -71,6 +70,7 @@ func (s *Server) setupTLSListener(certFile, keyFile string) error { if err != nil { return fmt.Errorf("failed to create a TLS listener on address %s: %w", s.Server.Addr, err) } + s.isTLS = true s.listener = listener return nil } From 6fab33b538fd4dedf6d86dac13db1d00cf64118a Mon Sep 17 00:00:00 2001 From: ignaciojeria Date: Sun, 1 Dec 2024 04:25:21 -0300 Subject: [PATCH 098/138] unnecesary added attribute removed --- server.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/server.go b/server.go index de49ae79..f4042db9 100644 --- a/server.go +++ b/server.go @@ -64,8 +64,6 @@ type Server struct { listener net.Listener - tlsConfig *tls.Config - Security Security autoAuth AutoAuthConfig @@ -398,7 +396,6 @@ func WithTLSListener(listener net.Listener, certFile, keyFile string) func(*Serv } tlsConfig := &tls.Config{Certificates: []tls.Certificate{cert}} tlsListener := tls.NewListener(listener, tlsConfig) - s.tlsConfig = tlsConfig s.isTLS = true setListener(s, tlsListener) } From b877a00a4b89153aa8bd7a33ea0a7cba1a0febd5 Mon Sep 17 00:00:00 2001 From: Ignacio Date: Sun, 1 Dec 2024 16:39:29 +0000 Subject: [PATCH 099/138] Add default port to listener and refactor setup method with error handling --- examples/with-listener/go.mod | 28 +++++++++++++++ examples/with-listener/go.sum | 62 ++++++++++++++++++++++++++++++++++ examples/with-listener/main.go | 28 +++++++++++++++ go.work | 1 + serve.go | 39 ++++++++++++++++----- server.go | 23 +++++++++++-- 6 files changed, 170 insertions(+), 11 deletions(-) create mode 100644 examples/with-listener/go.mod create mode 100644 examples/with-listener/go.sum create mode 100644 examples/with-listener/main.go diff --git a/examples/with-listener/go.mod b/examples/with-listener/go.mod new file mode 100644 index 00000000..4dc2dd72 --- /dev/null +++ b/examples/with-listener/go.mod @@ -0,0 +1,28 @@ +module github.com/go-fuego/fuego/examples/with-listener + +go 1.22.2 + +require github.com/go-fuego/fuego v0.14.0 + +require ( + github.com/gabriel-vasile/mimetype v1.4.5 // indirect + github.com/getkin/kin-openapi v0.127.0 // indirect + github.com/go-openapi/jsonpointer v0.21.0 // indirect + github.com/go-openapi/swag v0.23.0 // indirect + github.com/go-playground/locales v0.14.1 // indirect + github.com/go-playground/universal-translator v0.18.1 // indirect + github.com/go-playground/validator/v10 v10.22.1 // indirect + github.com/golang-jwt/jwt/v5 v5.2.1 // indirect + github.com/gorilla/schema v1.4.1 // indirect + github.com/invopop/yaml v0.3.1 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/leodido/go-urn v1.4.0 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect + github.com/perimeterx/marshmallow v1.1.5 // indirect + golang.org/x/crypto v0.27.0 // indirect + golang.org/x/net v0.29.0 // indirect + golang.org/x/sys v0.25.0 // indirect + golang.org/x/text v0.19.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/examples/with-listener/go.sum b/examples/with-listener/go.sum new file mode 100644 index 00000000..55a7a2c0 --- /dev/null +++ b/examples/with-listener/go.sum @@ -0,0 +1,62 @@ +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/gabriel-vasile/mimetype v1.4.5 h1:J7wGKdGu33ocBOhGy0z653k/lFKLFDPJMG8Gql0kxn4= +github.com/gabriel-vasile/mimetype v1.4.5/go.mod h1:ibHel+/kbxn9x2407k1izTA1S81ku1z/DlgOW2QE0M4= +github.com/getkin/kin-openapi v0.127.0 h1:Mghqi3Dhryf3F8vR370nN67pAERW+3a95vomb3MAREY= +github.com/getkin/kin-openapi v0.127.0/go.mod h1:OZrfXzUfGrNbsKj+xmFBx6E5c6yH3At/tAKSc2UszXM= +github.com/go-fuego/fuego v0.14.0 h1:jYrfTXSAiWxYcqJUpFVUjH4EZ5ZBcy8piszeRlky7ZU= +github.com/go-fuego/fuego v0.14.0/go.mod h1:T+e74Ln/DR8XRCQ421seu8QvmogpRpR/0D3dYxcEq6U= +github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= +github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= +github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= +github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= +github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= +github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= +github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= +github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= +github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= +github.com/go-playground/validator/v10 v10.22.1 h1:40JcKH+bBNGFczGuoBYgX4I6m/i27HYW8P9FDk5PbgA= +github.com/go-playground/validator/v10 v10.22.1/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= +github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= +github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= +github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= +github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= +github.com/gorilla/schema v1.4.1 h1:jUg5hUjCSDZpNGLuXQOgIWGdlgrIdYvgQ0wZtdK1M3E= +github.com/gorilla/schema v1.4.1/go.mod h1:Dg5SSm5PV60mhF2NFaTV1xuYYj8tV8NOPRo4FggUMnM= +github.com/invopop/yaml v0.3.1 h1:f0+ZpmhfBSS4MhG+4HYseMdJhoeeopbSKbq5Rpeelso= +github.com/invopop/yaml v0.3.1/go.mod h1:PMOp3nn4/12yEZUFfmOuNHJsZToEEOwoWsT+D81KkeA= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= +github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= +github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= +github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= +github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= +golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= +golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= +golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= +golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= +golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= +golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/examples/with-listener/main.go b/examples/with-listener/main.go new file mode 100644 index 00000000..4bd73a5b --- /dev/null +++ b/examples/with-listener/main.go @@ -0,0 +1,28 @@ +package main + +import ( + "net" + + "github.com/go-fuego/fuego" + "github.com/go-fuego/fuego/option" +) + +func main() { + listener, err := net.Listen("tcp", "127.0.0.1:8080") + if err != nil { + panic(err) + } + s := fuego.NewServer(fuego.WithListener(listener)) + + fuego.Get(s, "/", helloWorld, + option.Summary("A simple hello world"), + option.Description("This is a simple hello world"), + option.Deprecated(), + ) + + s.Run() +} + +func helloWorld(c fuego.ContextNoBody) (string, error) { + return "Hello, World!", nil +} diff --git a/go.work b/go.work index d6686f05..e5521206 100644 --- a/go.work +++ b/go.work @@ -4,6 +4,7 @@ use ( . ./cmd/fuego ./examples/acme-tls + ./examples/with-listener ./examples/basic ./examples/custom-errors ./examples/custom-serializer diff --git a/serve.go b/serve.go index 17c96e4f..f2f0b682 100644 --- a/serve.go +++ b/serve.go @@ -17,10 +17,9 @@ import ( // It returns an error if the server could not start (it could not bind to the port for example). // It also generates the OpenAPI spec and outputs it to a file, the UI, and a handler (if enabled). func (s *Server) Run() error { - if err := s.setupDefaultListener(); err != nil { - return fmt.Errorf("failed to start server: %w", err) + if err := s.setup("", ""); err != nil { + return err } - s.setup() return s.Server.Serve(s.listener) } @@ -29,14 +28,26 @@ func (s *Server) Run() error { // It returns an error if the server could not start (it could not bind to the port for example). // It also generates the OpenAPI spec and outputs it to a file, the UI, and a handler (if enabled). func (s *Server) RunTLS(certFile, keyFile string) error { - if err := s.setupTLSListener(certFile, keyFile); err != nil { - return fmt.Errorf("failed to start TLS server: %w", err) + s.isTLS = true + if err := s.setup(certFile, keyFile); err != nil { + return err } - s.setup() return s.Server.Serve(s.listener) } -func (s *Server) setup() { +func (s *Server) setup(certFile, keyFile string) error { + if !s.isTLS { + err := s.setupDefaultListener() + if err != nil { + return err + } + } + if s.isTLS { + err := s.setupTLSListener(certFile, keyFile) + if err != nil { + return err + } + } go s.OutputOpenAPISpec() s.printStartupMessage() @@ -44,6 +55,7 @@ func (s *Server) setup() { if s.corsMiddleware != nil { s.Server.Handler = s.corsMiddleware(s.Server.Handler) } + return nil } // setupTLSListener creates a TLS listener if no listener is already configured. @@ -66,7 +78,11 @@ func (s *Server) setupTLSListener(certFile, keyFile string) error { } tlsConfig := &tls.Config{Certificates: []tls.Certificate{cert}} - listener, err := tls.Listen("tcp", s.Server.Addr, tlsConfig) + addr := s.Server.Addr + if addr == "" { + addr = "127.0.0.1:9999" + } + listener, err := tls.Listen("tcp", addr, tlsConfig) if err != nil { return fmt.Errorf("failed to create a TLS listener on address %s: %w", s.Server.Addr, err) } @@ -82,11 +98,16 @@ func (s *Server) setupDefaultListener() error { if s.listener != nil { return nil // Listener already exists, no action needed. } - listener, err := net.Listen("tcp", s.Server.Addr) + addr := s.Server.Addr + if addr == "" { + addr = "127.0.0.1:9999" + } + listener, err := net.Listen("tcp", addr) if err != nil { return fmt.Errorf("failed to create default listener on %s: %w", s.Server.Addr, err) } s.listener = listener + s.Addr = s.listener.Addr().String() return nil } diff --git a/server.go b/server.go index f4042db9..517c3411 100644 --- a/server.go +++ b/server.go @@ -114,7 +114,6 @@ func NewServer(options ...func(*Server)) *Server { // Default options that can be overridden defaultOptions := [...]func(*Server){ - WithAddr("localhost:9999"), WithDisallowUnknownFields(true), WithSerializer(Send), WithErrorSerializer(SendError), @@ -154,6 +153,17 @@ func NewServer(options ...func(*Server)) *Server { return s } +func getServerAddress(s *Server) string { + if s.listener != nil { + return s.listener.Addr().String() + } + if s.Server.Addr != "" { + return s.Server.Addr + } + // Default address if none is set + return ":9999" +} + // WithTemplateFS sets the filesystem used to load templates. // To be used with [WithTemplateGlobs] or [WithTemplates]. // For example: @@ -320,7 +330,12 @@ func WithPort(port int) func(*Server) { // WithAddr optionally specifies the TCP address for the server to listen on, in the form "host:port". // If not specified addr ':9999' will be used. func WithAddr(addr string) func(*Server) { - return func(c *Server) { c.Server.Addr = addr } + return func(c *Server) { + if c.listener != nil { + panic("cannot set addr when a listener is already configured") + } + c.Server.Addr = addr + } } // WithXML sets the serializer to XML @@ -405,7 +420,11 @@ func setListener(s *Server, listener net.Listener) { if s.listener != nil { panic("listener already configured") } + if s.Server.Addr != "" { + panic(fmt.Sprintf("cannot set listener when addr is already configured: addr=%s", s.Server.Addr)) + } s.listener = listener + s.Server.Addr = listener.Addr().String() } func WithOpenAPIConfig(openapiConfig OpenAPIConfig) func(*Server) { From ac163c84453526683f70c82d26be133d39d78f6c Mon Sep 17 00:00:00 2001 From: Ignacio Date: Sun, 1 Dec 2024 16:52:52 +0000 Subject: [PATCH 100/138] listener encapsulation changed from private to public --- serve.go | 16 ++++++++-------- server.go | 12 ++++++------ 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/serve.go b/serve.go index f2f0b682..6b88bd2f 100644 --- a/serve.go +++ b/serve.go @@ -20,7 +20,7 @@ func (s *Server) Run() error { if err := s.setup("", ""); err != nil { return err } - return s.Server.Serve(s.listener) + return s.Server.Serve(s.Listener) } // RunTLS starts the server with a TLS listener @@ -32,7 +32,7 @@ func (s *Server) RunTLS(certFile, keyFile string) error { if err := s.setup(certFile, keyFile); err != nil { return err } - return s.Server.Serve(s.listener) + return s.Server.Serve(s.Listener) } func (s *Server) setup(certFile, keyFile string) error { @@ -63,10 +63,10 @@ func (s *Server) setup(certFile, keyFile string) error { // Requires valid TLS certificate and key files to establish a secure listener. // Returns an error if the listener cannot be created or if the provided certificates are invalid. func (s *Server) setupTLSListener(certFile, keyFile string) error { - if s.listener != nil && !s.isTLS { + if s.Listener != nil && !s.isTLS { return errors.New("a non-TLS listener is already configured; cannot set up a TLS listener on the same server") } - if s.listener != nil { + if s.Listener != nil { return errors.New("a TLS listener is already configured; use the Run() method to start the server") } if certFile == "" || keyFile == "" { @@ -87,7 +87,7 @@ func (s *Server) setupTLSListener(certFile, keyFile string) error { return fmt.Errorf("failed to create a TLS listener on address %s: %w", s.Server.Addr, err) } s.isTLS = true - s.listener = listener + s.Listener = listener return nil } @@ -95,7 +95,7 @@ func (s *Server) setupTLSListener(certFile, keyFile string) error { // If a listener is already set, this method does nothing. // Returns an error if the listener cannot be created (e.g., address binding issues). func (s *Server) setupDefaultListener() error { - if s.listener != nil { + if s.Listener != nil { return nil // Listener already exists, no action needed. } addr := s.Server.Addr @@ -106,8 +106,8 @@ func (s *Server) setupDefaultListener() error { if err != nil { return fmt.Errorf("failed to create default listener on %s: %w", s.Server.Addr, err) } - s.listener = listener - s.Addr = s.listener.Addr().String() + s.Listener = listener + s.Addr = s.Listener.Addr().String() return nil } diff --git a/server.go b/server.go index 517c3411..521cc813 100644 --- a/server.go +++ b/server.go @@ -62,7 +62,7 @@ type Server struct { // Points to the server OpenAPI struct. OpenAPI *OpenAPI - listener net.Listener + Listener net.Listener Security Security @@ -154,8 +154,8 @@ func NewServer(options ...func(*Server)) *Server { } func getServerAddress(s *Server) string { - if s.listener != nil { - return s.listener.Addr().String() + if s.Listener != nil { + return s.Listener.Addr().String() } if s.Server.Addr != "" { return s.Server.Addr @@ -331,7 +331,7 @@ func WithPort(port int) func(*Server) { // If not specified addr ':9999' will be used. func WithAddr(addr string) func(*Server) { return func(c *Server) { - if c.listener != nil { + if c.Listener != nil { panic("cannot set addr when a listener is already configured") } c.Server.Addr = addr @@ -417,13 +417,13 @@ func WithTLSListener(listener net.Listener, certFile, keyFile string) func(*Serv } func setListener(s *Server, listener net.Listener) { - if s.listener != nil { + if s.Listener != nil { panic("listener already configured") } if s.Server.Addr != "" { panic(fmt.Sprintf("cannot set listener when addr is already configured: addr=%s", s.Server.Addr)) } - s.listener = listener + s.Listener = listener s.Server.Addr = listener.Addr().String() } From 3812d3f5a88eb7baa7becb5b4bb20dac0fd4e310 Mon Sep 17 00:00:00 2001 From: Ignacio Date: Sun, 1 Dec 2024 17:00:31 +0000 Subject: [PATCH 101/138] default tls port :443 --- serve.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/serve.go b/serve.go index 6b88bd2f..3fd3710f 100644 --- a/serve.go +++ b/serve.go @@ -80,7 +80,7 @@ func (s *Server) setupTLSListener(certFile, keyFile string) error { addr := s.Server.Addr if addr == "" { - addr = "127.0.0.1:9999" + addr = "127.0.0.1:443" } listener, err := tls.Listen("tcp", addr, tlsConfig) if err != nil { From f361e5203fee415e028f4086d17ad6f6f996d8c4 Mon Sep 17 00:00:00 2001 From: Ignacio Date: Sun, 1 Dec 2024 17:04:50 +0000 Subject: [PATCH 102/138] set only default port in address --- serve.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/serve.go b/serve.go index 3fd3710f..4e9d0f85 100644 --- a/serve.go +++ b/serve.go @@ -80,7 +80,7 @@ func (s *Server) setupTLSListener(certFile, keyFile string) error { addr := s.Server.Addr if addr == "" { - addr = "127.0.0.1:443" + addr = ":443" } listener, err := tls.Listen("tcp", addr, tlsConfig) if err != nil { @@ -100,7 +100,7 @@ func (s *Server) setupDefaultListener() error { } addr := s.Server.Addr if addr == "" { - addr = "127.0.0.1:9999" + addr = ":9999" } listener, err := net.Listen("tcp", addr) if err != nil { From 3ed88c3b7cead1e7f41c862870f7163c3e3dbe32 Mon Sep 17 00:00:00 2001 From: Ignacio Date: Sun, 1 Dec 2024 18:30:41 +0000 Subject: [PATCH 103/138] codebase simplified using With functions --- serve.go | 48 ++++-------------------------------------------- server.go | 23 +++++++++++++---------- 2 files changed, 17 insertions(+), 54 deletions(-) diff --git a/serve.go b/serve.go index 4e9d0f85..a11bbd6b 100644 --- a/serve.go +++ b/serve.go @@ -1,8 +1,6 @@ package fuego import ( - "crypto/tls" - "errors" "fmt" "html/template" "log/slog" @@ -37,16 +35,12 @@ func (s *Server) RunTLS(certFile, keyFile string) error { func (s *Server) setup(certFile, keyFile string) error { if !s.isTLS { - err := s.setupDefaultListener() - if err != nil { + if err := s.setupDefaultListener(); err != nil { return err } } if s.isTLS { - err := s.setupTLSListener(certFile, keyFile) - if err != nil { - return err - } + WithTLSListener(certFile, keyFile)(s) } go s.OutputOpenAPISpec() s.printStartupMessage() @@ -58,39 +52,6 @@ func (s *Server) setup(certFile, keyFile string) error { return nil } -// setupTLSListener creates a TLS listener if no listener is already configured. -// If a non-TLS listener is already configured, an error is returned. -// Requires valid TLS certificate and key files to establish a secure listener. -// Returns an error if the listener cannot be created or if the provided certificates are invalid. -func (s *Server) setupTLSListener(certFile, keyFile string) error { - if s.Listener != nil && !s.isTLS { - return errors.New("a non-TLS listener is already configured; cannot set up a TLS listener on the same server") - } - if s.Listener != nil { - return errors.New("a TLS listener is already configured; use the Run() method to start the server") - } - if certFile == "" || keyFile == "" { - return errors.New("TLS certificate and key files must be provided to set up a TLS listener") - } - cert, err := tls.LoadX509KeyPair(certFile, keyFile) - if err != nil { - return fmt.Errorf("failed to load TLS certificate and key files (%s, %s): %w", certFile, keyFile, err) - } - tlsConfig := &tls.Config{Certificates: []tls.Certificate{cert}} - - addr := s.Server.Addr - if addr == "" { - addr = ":443" - } - listener, err := tls.Listen("tcp", addr, tlsConfig) - if err != nil { - return fmt.Errorf("failed to create a TLS listener on address %s: %w", s.Server.Addr, err) - } - s.isTLS = true - s.Listener = listener - return nil -} - // setupDefaultListener creates a default (non-TLS) listener if none is already configured. // If a listener is already set, this method does nothing. // Returns an error if the listener cannot be created (e.g., address binding issues). @@ -104,10 +65,9 @@ func (s *Server) setupDefaultListener() error { } listener, err := net.Listen("tcp", addr) if err != nil { - return fmt.Errorf("failed to create default listener on %s: %w", s.Server.Addr, err) + return err } - s.Listener = listener - s.Addr = s.Listener.Addr().String() + WithListener(listener)(s) return nil } diff --git a/server.go b/server.go index 521cc813..dd3c13c5 100644 --- a/server.go +++ b/server.go @@ -392,36 +392,39 @@ func WithoutLogger() func(*Server) { } } +// WithListener configures the server to use a custom listener. +// If no listener is provided, it creates a default listener using the server's address. func WithListener(listener net.Listener) func(*Server) { return func(s *Server) { setListener(s, listener) } } -// WithTLSListener configures the server to use a TLS listener with the provided certificates. -// It ensures the provided listener is wrapped with TLS using the given cert and key files. -func WithTLSListener(listener net.Listener, certFile, keyFile string) func(*Server) { +func WithTLSListener(certFile, keyFile string) func(*Server) { return func(s *Server) { if certFile == "" || keyFile == "" { panic("TLS certificates must be provided (certFile and keyFile)") } cert, err := tls.LoadX509KeyPair(certFile, keyFile) if err != nil { - panic(fmt.Errorf("failed to load TLS certificates: %w", err)) + panic(fmt.Errorf("failed to load TLS certificate and key files (%s, %s): %w", certFile, keyFile, err)) } tlsConfig := &tls.Config{Certificates: []tls.Certificate{cert}} - tlsListener := tls.NewListener(listener, tlsConfig) - s.isTLS = true + addr := s.Server.Addr + if addr == "" { + addr = ":443" + } + tlsListener, err := tls.Listen("tcp", addr, tlsConfig) + if err != nil { + panic(fmt.Errorf("failed to create a TLS listener on address %s: %w", addr, err)) + } setListener(s, tlsListener) } } func setListener(s *Server, listener net.Listener) { if s.Listener != nil { - panic("listener already configured") - } - if s.Server.Addr != "" { - panic(fmt.Sprintf("cannot set listener when addr is already configured: addr=%s", s.Server.Addr)) + panic("a listener is already configured; cannot overwrite it") } s.Listener = listener s.Server.Addr = listener.Addr().String() From 9bb70c51d16c0bb883dbf166fda870aabf01e608 Mon Sep 17 00:00:00 2001 From: ccoVeille <3875889+ccoVeille@users.noreply.github.com> Date: Sun, 1 Dec 2024 22:00:39 +0100 Subject: [PATCH 104/138] refactor code --- serve.go | 21 +++++++++------------ server.go | 18 ++++++++++-------- 2 files changed, 19 insertions(+), 20 deletions(-) diff --git a/serve.go b/serve.go index a11bbd6b..0e41f46a 100644 --- a/serve.go +++ b/serve.go @@ -15,7 +15,7 @@ import ( // It returns an error if the server could not start (it could not bind to the port for example). // It also generates the OpenAPI spec and outputs it to a file, the UI, and a handler (if enabled). func (s *Server) Run() error { - if err := s.setup("", ""); err != nil { + if err := s.setup(); err != nil { return err } return s.Server.Serve(s.Listener) @@ -26,21 +26,15 @@ func (s *Server) Run() error { // It returns an error if the server could not start (it could not bind to the port for example). // It also generates the OpenAPI spec and outputs it to a file, the UI, and a handler (if enabled). func (s *Server) RunTLS(certFile, keyFile string) error { - s.isTLS = true - if err := s.setup(certFile, keyFile); err != nil { + if err := s.setup(); err != nil { return err } - return s.Server.Serve(s.Listener) + return s.Server.ServeTLS(s.Listener, certFile, keyFile) } -func (s *Server) setup(certFile, keyFile string) error { - if !s.isTLS { - if err := s.setupDefaultListener(); err != nil { - return err - } - } - if s.isTLS { - WithTLSListener(certFile, keyFile)(s) +func (s *Server) setup() error { + if err := s.setupDefaultListener(); err != nil { + return err } go s.OutputOpenAPISpec() s.printStartupMessage() @@ -62,6 +56,9 @@ func (s *Server) setupDefaultListener() error { addr := s.Server.Addr if addr == "" { addr = ":9999" + if s.isTLS { + addr = ":443" + } } listener, err := net.Listen("tcp", addr) if err != nil { diff --git a/server.go b/server.go index dd3c13c5..3081f80e 100644 --- a/server.go +++ b/server.go @@ -402,22 +402,24 @@ func WithListener(listener net.Listener) func(*Server) { func WithTLSListener(certFile, keyFile string) func(*Server) { return func(s *Server) { - if certFile == "" || keyFile == "" { - panic("TLS certificates must be provided (certFile and keyFile)") + tlsConfig := tls.Config{} + if certFile != "" && keyFile != "" { + cert, err := tls.LoadX509KeyPair(certFile, keyFile) + if err != nil { + panic(fmt.Errorf("failed to load TLS certificate and key files (%s, %s): %w", certFile, keyFile, err)) + } + tlsConfig.Certificates = []tls.Certificate{cert} } - cert, err := tls.LoadX509KeyPair(certFile, keyFile) - if err != nil { - panic(fmt.Errorf("failed to load TLS certificate and key files (%s, %s): %w", certFile, keyFile, err)) - } - tlsConfig := &tls.Config{Certificates: []tls.Certificate{cert}} + addr := s.Server.Addr if addr == "" { addr = ":443" } - tlsListener, err := tls.Listen("tcp", addr, tlsConfig) + tlsListener, err := tls.Listen("tcp", addr, &tlsConfig) if err != nil { panic(fmt.Errorf("failed to create a TLS listener on address %s: %w", addr, err)) } + s.isTLS = true setListener(s, tlsListener) } } From 421a6f4e4cb6e42ec3f0cba6a404d485cd641cdd Mon Sep 17 00:00:00 2001 From: Ignacio Date: Mon, 2 Dec 2024 02:00:27 +0000 Subject: [PATCH 105/138] Remove unnecessary public listener attribute and getAddr function; add close method; set host to localhost by default, matching the original implementation --- serve.go | 10 +++++----- server.go | 21 +++++---------------- 2 files changed, 10 insertions(+), 21 deletions(-) diff --git a/serve.go b/serve.go index 0e41f46a..179fdaaa 100644 --- a/serve.go +++ b/serve.go @@ -18,7 +18,7 @@ func (s *Server) Run() error { if err := s.setup(); err != nil { return err } - return s.Server.Serve(s.Listener) + return s.Server.Serve(s.listener) } // RunTLS starts the server with a TLS listener @@ -29,7 +29,7 @@ func (s *Server) RunTLS(certFile, keyFile string) error { if err := s.setup(); err != nil { return err } - return s.Server.ServeTLS(s.Listener, certFile, keyFile) + return s.Server.ServeTLS(s.listener, certFile, keyFile) } func (s *Server) setup() error { @@ -50,14 +50,14 @@ func (s *Server) setup() error { // If a listener is already set, this method does nothing. // Returns an error if the listener cannot be created (e.g., address binding issues). func (s *Server) setupDefaultListener() error { - if s.Listener != nil { + if s.listener != nil { return nil // Listener already exists, no action needed. } addr := s.Server.Addr if addr == "" { - addr = ":9999" + addr = "localhost:9999" if s.isTLS { - addr = ":443" + addr = "localhost:443" } } listener, err := net.Listen("tcp", addr) diff --git a/server.go b/server.go index 3081f80e..af33a6af 100644 --- a/server.go +++ b/server.go @@ -62,7 +62,7 @@ type Server struct { // Points to the server OpenAPI struct. OpenAPI *OpenAPI - Listener net.Listener + listener net.Listener Security Security @@ -153,17 +153,6 @@ func NewServer(options ...func(*Server)) *Server { return s } -func getServerAddress(s *Server) string { - if s.Listener != nil { - return s.Listener.Addr().String() - } - if s.Server.Addr != "" { - return s.Server.Addr - } - // Default address if none is set - return ":9999" -} - // WithTemplateFS sets the filesystem used to load templates. // To be used with [WithTemplateGlobs] or [WithTemplates]. // For example: @@ -331,7 +320,7 @@ func WithPort(port int) func(*Server) { // If not specified addr ':9999' will be used. func WithAddr(addr string) func(*Server) { return func(c *Server) { - if c.Listener != nil { + if c.listener != nil { panic("cannot set addr when a listener is already configured") } c.Server.Addr = addr @@ -413,7 +402,7 @@ func WithTLSListener(certFile, keyFile string) func(*Server) { addr := s.Server.Addr if addr == "" { - addr = ":443" + addr = "localhost:443" } tlsListener, err := tls.Listen("tcp", addr, &tlsConfig) if err != nil { @@ -425,10 +414,10 @@ func WithTLSListener(certFile, keyFile string) func(*Server) { } func setListener(s *Server, listener net.Listener) { - if s.Listener != nil { + if s.listener != nil { panic("a listener is already configured; cannot overwrite it") } - s.Listener = listener + s.listener = listener s.Server.Addr = listener.Addr().String() } From a7d111531d708983abb1498a0788017664c77de4 Mon Sep 17 00:00:00 2001 From: Ignacio Date: Mon, 2 Dec 2024 02:17:43 +0000 Subject: [PATCH 106/138] WithTlsListenner removed --- server.go | 37 ++++--------------------------------- 1 file changed, 4 insertions(+), 33 deletions(-) diff --git a/server.go b/server.go index af33a6af..7456f36d 100644 --- a/server.go +++ b/server.go @@ -1,7 +1,6 @@ package fuego import ( - "crypto/tls" "fmt" "html/template" "io" @@ -385,40 +384,12 @@ func WithoutLogger() func(*Server) { // If no listener is provided, it creates a default listener using the server's address. func WithListener(listener net.Listener) func(*Server) { return func(s *Server) { - setListener(s, listener) - } -} - -func WithTLSListener(certFile, keyFile string) func(*Server) { - return func(s *Server) { - tlsConfig := tls.Config{} - if certFile != "" && keyFile != "" { - cert, err := tls.LoadX509KeyPair(certFile, keyFile) - if err != nil { - panic(fmt.Errorf("failed to load TLS certificate and key files (%s, %s): %w", certFile, keyFile, err)) - } - tlsConfig.Certificates = []tls.Certificate{cert} - } - - addr := s.Server.Addr - if addr == "" { - addr = "localhost:443" + if s.listener != nil { + panic("a listener is already configured; cannot overwrite it") } - tlsListener, err := tls.Listen("tcp", addr, &tlsConfig) - if err != nil { - panic(fmt.Errorf("failed to create a TLS listener on address %s: %w", addr, err)) - } - s.isTLS = true - setListener(s, tlsListener) - } -} - -func setListener(s *Server, listener net.Listener) { - if s.listener != nil { - panic("a listener is already configured; cannot overwrite it") + s.listener = listener + s.Server.Addr = listener.Addr().String() } - s.listener = listener - s.Server.Addr = listener.Addr().String() } func WithOpenAPIConfig(openapiConfig OpenAPIConfig) func(*Server) { From 8881232ac347f8878c95d3b97d9479ba1d015e13 Mon Sep 17 00:00:00 2001 From: Ignacio Date: Mon, 2 Dec 2024 02:27:31 +0000 Subject: [PATCH 107/138] isTls set to true --- serve.go | 1 + 1 file changed, 1 insertion(+) diff --git a/serve.go b/serve.go index 179fdaaa..3a8e377f 100644 --- a/serve.go +++ b/serve.go @@ -26,6 +26,7 @@ func (s *Server) Run() error { // It returns an error if the server could not start (it could not bind to the port for example). // It also generates the OpenAPI spec and outputs it to a file, the UI, and a handler (if enabled). func (s *Server) RunTLS(certFile, keyFile string) error { + s.isTLS = true if err := s.setup(); err != nil { return err } From c0a88810fca68b92355011474ed71c1843f51230 Mon Sep 17 00:00:00 2001 From: Ignacio Date: Mon, 2 Dec 2024 05:03:06 +0000 Subject: [PATCH 108/138] address set by WithListener and protocol added to OpenAPI servers --- server.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server.go b/server.go index 7456f36d..aa26c275 100644 --- a/server.go +++ b/server.go @@ -387,8 +387,8 @@ func WithListener(listener net.Listener) func(*Server) { if s.listener != nil { panic("a listener is already configured; cannot overwrite it") } + WithAddr(listener.Addr().String())(s) s.listener = listener - s.Server.Addr = listener.Addr().String() } } From f1f5f4a36f3e153e4864579545b9633b7239d440 Mon Sep 17 00:00:00 2001 From: Ignacio Date: Mon, 2 Dec 2024 05:15:45 +0000 Subject: [PATCH 109/138] invalid comment removed --- server.go | 1 - 1 file changed, 1 deletion(-) diff --git a/server.go b/server.go index aa26c275..681dd7da 100644 --- a/server.go +++ b/server.go @@ -381,7 +381,6 @@ func WithoutLogger() func(*Server) { } // WithListener configures the server to use a custom listener. -// If no listener is provided, it creates a default listener using the server's address. func WithListener(listener net.Listener) func(*Server) { return func(s *Server) { if s.listener != nil { From 65f50181b46caa16072693e1c84372e21496b350 Mon Sep 17 00:00:00 2001 From: Ignacio Date: Mon, 2 Dec 2024 06:25:55 +0000 Subject: [PATCH 110/138] set server addres if is empty added again to avoid broke tests and validate if listenner is tls using reflection --- server.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/server.go b/server.go index 681dd7da..b21a519f 100644 --- a/server.go +++ b/server.go @@ -9,6 +9,7 @@ import ( "net" "net/http" "os" + "reflect" "time" "github.com/getkin/kin-openapi/openapi3" @@ -386,11 +387,20 @@ func WithListener(listener net.Listener) func(*Server) { if s.listener != nil { panic("a listener is already configured; cannot overwrite it") } + s.isTLS = isTLSListener(listener) WithAddr(listener.Addr().String())(s) s.listener = listener } } +func isTLSListener(listener net.Listener) bool { + listenerType := reflect.TypeOf(listener) + if listenerType != nil && listenerType.String() == "*tls.listener" { + return true + } + return false +} + func WithOpenAPIConfig(openapiConfig OpenAPIConfig) func(*Server) { return func(s *Server) { if openapiConfig.JsonUrl != "" { From d319ece2d0417bf23c714c1be197f09a5dba23f8 Mon Sep 17 00:00:00 2001 From: Ignacio Date: Tue, 3 Dec 2024 16:25:04 +0000 Subject: [PATCH 111/138] codebase improvements based on observations --- serve.go | 11 ++--------- server.go | 17 ++++++++++------- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/serve.go b/serve.go index 3a8e377f..fa4226de 100644 --- a/serve.go +++ b/serve.go @@ -1,7 +1,6 @@ package fuego import ( - "fmt" "html/template" "log/slog" "net" @@ -52,16 +51,10 @@ func (s *Server) setup() error { // Returns an error if the listener cannot be created (e.g., address binding issues). func (s *Server) setupDefaultListener() error { if s.listener != nil { + WithAddr(s.listener.Addr().String())(s) return nil // Listener already exists, no action needed. } - addr := s.Server.Addr - if addr == "" { - addr = "localhost:9999" - if s.isTLS { - addr = "localhost:443" - } - } - listener, err := net.Listen("tcp", addr) + listener, err := net.Listen("tcp", s.Addr) if err != nil { return err } diff --git a/server.go b/server.go index b21a519f..c01ed8f1 100644 --- a/server.go +++ b/server.go @@ -114,6 +114,7 @@ func NewServer(options ...func(*Server)) *Server { // Default options that can be overridden defaultOptions := [...]func(*Server){ + WithAddr("localhost:9999"), WithDisallowUnknownFields(true), WithSerializer(Send), WithErrorSerializer(SendError), @@ -320,9 +321,6 @@ func WithPort(port int) func(*Server) { // If not specified addr ':9999' will be used. func WithAddr(addr string) func(*Server) { return func(c *Server) { - if c.listener != nil { - panic("cannot set addr when a listener is already configured") - } c.Server.Addr = addr } } @@ -382,13 +380,18 @@ func WithoutLogger() func(*Server) { } // WithListener configures the server to use a custom listener. +// If a listener is provided using this option, any address specified with WithAddr will be ignored. +// +// Example: +// +// listener, _ := net.Listen("tcp", ":8080") +// server := NewServer( +// WithListener(listener), +// WithAddr(":9999"), // This will be ignored because WithListener takes precedence. +// ) func WithListener(listener net.Listener) func(*Server) { return func(s *Server) { - if s.listener != nil { - panic("a listener is already configured; cannot overwrite it") - } s.isTLS = isTLSListener(listener) - WithAddr(listener.Addr().String())(s) s.listener = listener } } From e7d8152deeb1d04c2f9a26418c671d46da92ad17 Mon Sep 17 00:00:00 2001 From: Ignacio Date: Tue, 3 Dec 2024 16:40:48 +0000 Subject: [PATCH 112/138] WithAddr doc improved --- server.go | 1 + 1 file changed, 1 insertion(+) diff --git a/server.go b/server.go index c01ed8f1..71e892ca 100644 --- a/server.go +++ b/server.go @@ -319,6 +319,7 @@ func WithPort(port int) func(*Server) { // WithAddr optionally specifies the TCP address for the server to listen on, in the form "host:port". // If not specified addr ':9999' will be used. +// If a listener is explicitly set using WithListener, the provided address will be ignored, func WithAddr(addr string) func(*Server) { return func(c *Server) { c.Server.Addr = addr From aef48a3df651395038353d01800e74800efbf0c4 Mon Sep 17 00:00:00 2001 From: Ignacio Date: Wed, 4 Dec 2024 02:57:25 +0000 Subject: [PATCH 113/138] Checking if the server is TLS is not needed. --- server.go | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/server.go b/server.go index 71e892ca..46e0a9c4 100644 --- a/server.go +++ b/server.go @@ -9,7 +9,6 @@ import ( "net" "net/http" "os" - "reflect" "time" "github.com/getkin/kin-openapi/openapi3" @@ -392,19 +391,10 @@ func WithoutLogger() func(*Server) { // ) func WithListener(listener net.Listener) func(*Server) { return func(s *Server) { - s.isTLS = isTLSListener(listener) s.listener = listener } } -func isTLSListener(listener net.Listener) bool { - listenerType := reflect.TypeOf(listener) - if listenerType != nil && listenerType.String() == "*tls.listener" { - return true - } - return false -} - func WithOpenAPIConfig(openapiConfig OpenAPIConfig) func(*Server) { return func(s *Server) { if openapiConfig.JsonUrl != "" { From 094dadd6bd083b2395af8d5d4bc867ac34fb897b Mon Sep 17 00:00:00 2001 From: Ignacio Date: Wed, 4 Dec 2024 03:13:10 +0000 Subject: [PATCH 114/138] OpenAPI local server moved to setup. --- serve.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/serve.go b/serve.go index fa4226de..9ba3389d 100644 --- a/serve.go +++ b/serve.go @@ -7,6 +7,8 @@ import ( "net/http" "reflect" "time" + + "github.com/getkin/kin-openapi/openapi3" ) // Run starts the server. @@ -43,6 +45,11 @@ func (s *Server) setup() error { if s.corsMiddleware != nil { s.Server.Handler = s.corsMiddleware(s.Server.Handler) } + + s.OpenApiSpec.Servers = append(s.OpenApiSpec.Servers, &openapi3.Server{ + URL: fmt.Sprintf("%s://%s", s.proto(), s.Addr), + Description: "local server", + }) return nil } From 0230de7d8e50c6fe5164426a5b93f2a8d3f28066 Mon Sep 17 00:00:00 2001 From: Ignacio Date: Wed, 4 Dec 2024 16:55:40 +0000 Subject: [PATCH 115/138] set openapi spec server from listener(if present) or address --- serve.go | 6 ------ server.go | 10 ++++++++++ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/serve.go b/serve.go index 9ba3389d..67e9ebc2 100644 --- a/serve.go +++ b/serve.go @@ -7,8 +7,6 @@ import ( "net/http" "reflect" "time" - - "github.com/getkin/kin-openapi/openapi3" ) // Run starts the server. @@ -46,10 +44,6 @@ func (s *Server) setup() error { s.Server.Handler = s.corsMiddleware(s.Server.Handler) } - s.OpenApiSpec.Servers = append(s.OpenApiSpec.Servers, &openapi3.Server{ - URL: fmt.Sprintf("%s://%s", s.proto(), s.Addr), - Description: "local server", - }) return nil } diff --git a/server.go b/server.go index 46e0a9c4..ec91331b 100644 --- a/server.go +++ b/server.go @@ -128,6 +128,15 @@ func NewServer(options ...func(*Server)) *Server { option(s) } + addr := s.Addr + if s.listener != nil { + addr = s.listener.Addr().String() + } + s.OpenApiSpec.Servers = append(s.OpenApiSpec.Servers, &openapi3.Server{ + URL: fmt.Sprintf("%s://%s", s.proto(), addr), + Description: "local server", + }) + s.startTime = time.Now() if s.autoAuth.Enabled { @@ -392,6 +401,7 @@ func WithoutLogger() func(*Server) { func WithListener(listener net.Listener) func(*Server) { return func(s *Server) { s.listener = listener + s.Addr = s.listener.Addr().String() } } From 8dca7184fe0b769f16866e604a9f01bae66d5e53 Mon Sep 17 00:00:00 2001 From: Ignacio Date: Wed, 4 Dec 2024 21:05:36 +0000 Subject: [PATCH 116/138] make lint --- server.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server.go b/server.go index ec91331b..440f629e 100644 --- a/server.go +++ b/server.go @@ -136,7 +136,7 @@ func NewServer(options ...func(*Server)) *Server { URL: fmt.Sprintf("%s://%s", s.proto(), addr), Description: "local server", }) - + s.startTime = time.Now() if s.autoAuth.Enabled { From 84f071f026f7b930f8ae64dad4e05fb655f044ea Mon Sep 17 00:00:00 2001 From: Ignacio Date: Thu, 5 Dec 2024 05:37:01 +0000 Subject: [PATCH 117/138] Remove unnecessary comments and WithAddr handling in defaultSetupListener when listener != nil --- serve.go | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/serve.go b/serve.go index 67e9ebc2..55297a46 100644 --- a/serve.go +++ b/serve.go @@ -47,13 +47,9 @@ func (s *Server) setup() error { return nil } -// setupDefaultListener creates a default (non-TLS) listener if none is already configured. -// If a listener is already set, this method does nothing. -// Returns an error if the listener cannot be created (e.g., address binding issues). func (s *Server) setupDefaultListener() error { if s.listener != nil { - WithAddr(s.listener.Addr().String())(s) - return nil // Listener already exists, no action needed. + return nil } listener, err := net.Listen("tcp", s.Addr) if err != nil { From a778cf896ef5d41754957002ece8ca057e480528 Mon Sep 17 00:00:00 2001 From: Ignacio Date: Thu, 5 Dec 2024 05:46:00 +0000 Subject: [PATCH 118/138] setupDefaultListenner fixed --- serve.go | 1 + 1 file changed, 1 insertion(+) diff --git a/serve.go b/serve.go index 55297a46..6da4c485 100644 --- a/serve.go +++ b/serve.go @@ -49,6 +49,7 @@ func (s *Server) setup() error { func (s *Server) setupDefaultListener() error { if s.listener != nil { + WithAddr(s.listener.Addr().String())(s) return nil } listener, err := net.Listen("tcp", s.Addr) From b30b63eb7f77f8907e77f49bfbc51c992df38a85 Mon Sep 17 00:00:00 2001 From: Ignacio Date: Fri, 6 Dec 2024 19:12:33 +0000 Subject: [PATCH 119/138] Set attributes directly instead of using the with function. --- serve.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/serve.go b/serve.go index 6da4c485..6eb55260 100644 --- a/serve.go +++ b/serve.go @@ -49,14 +49,14 @@ func (s *Server) setup() error { func (s *Server) setupDefaultListener() error { if s.listener != nil { - WithAddr(s.listener.Addr().String())(s) + s.Addr = s.listener.Addr().String() return nil } listener, err := net.Listen("tcp", s.Addr) if err != nil { return err } - WithListener(listener)(s) + s.listener = listener return nil } From 17ded45a30f2ebbdecf21daab43e8e3456619668 Mon Sep 17 00:00:00 2001 From: dylanhitt Date: Fri, 20 Dec 2024 12:16:57 -0500 Subject: [PATCH 120/138] chore: remove previously deprecated WithPort --- documentation/docs/guides/options.md | 16 ---------------- server.go | 10 ---------- server_test.go | 14 -------------- 3 files changed, 40 deletions(-) diff --git a/documentation/docs/guides/options.md b/documentation/docs/guides/options.md index d2ccde16..b73b251f 100644 --- a/documentation/docs/guides/options.md +++ b/documentation/docs/guides/options.md @@ -41,22 +41,6 @@ func main() { } ``` -### Port (Deprecated) - -**Deprecated** in favor of `WithAddr` shown above. - -You can change the port of the server with the `WithPort` option. - -```go -import "github.com/go-fuego/fuego" - -func main() { - s := fuego.NewServer( - fuego.WithPort(8080), - ) -} -``` - ### CORS CORS middleware is not registered as a usual middleware, diff --git a/server.go b/server.go index e60bf333..ad146ede 100644 --- a/server.go +++ b/server.go @@ -1,7 +1,6 @@ package fuego import ( - "fmt" "html/template" "io" "io/fs" @@ -304,15 +303,6 @@ func WithDisallowUnknownFields(b bool) func(*Server) { return func(c *Server) { c.DisallowUnknownFields = b } } -// WithPort sets the port of the server. For example, 8080. -// If not specified, the default port is 9999. -// If you want to use a different address, use [WithAddr] instead. -// -// Deprecated: Please use [WithAddr] -func WithPort(port int) func(*Server) { - return func(s *Server) { s.Server.Addr = fmt.Sprintf("localhost:%d", port) } -} - // WithAddr optionally specifies the TCP address for the server to listen on, in the form "host:port". // If not specified addr ':9999' will be used. func WithAddr(addr string) func(*Server) { diff --git a/server_test.go b/server_test.go index 45dd8bcd..3a71fb56 100644 --- a/server_test.go +++ b/server_test.go @@ -263,20 +263,6 @@ func TestWithAddr(t *testing.T) { } } -func TestWithPort(t *testing.T) { - t.Run("with custom port, that port is used", func(t *testing.T) { - s := NewServer( - WithPort(8488), - ) - require.Equal(t, "localhost:8488", s.Server.Addr) - }) - - t.Run("no port provided, default is used (9999)", func(t *testing.T) { - s := NewServer() - require.Equal(t, "localhost:9999", s.Server.Addr) - }) -} - func TestWithoutStartupMessages(t *testing.T) { s := NewServer( WithoutStartupMessages(), From 625a60bc250461d4ccb2f65e5d1548846b86ac78 Mon Sep 17 00:00:00 2001 From: dylanhitt Date: Fri, 20 Dec 2024 12:43:11 -0500 Subject: [PATCH 121/138] chore: remove unneeded set of address in WithListener --- server.go | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/server.go b/server.go index 440f629e..46e0a9c4 100644 --- a/server.go +++ b/server.go @@ -128,15 +128,6 @@ func NewServer(options ...func(*Server)) *Server { option(s) } - addr := s.Addr - if s.listener != nil { - addr = s.listener.Addr().String() - } - s.OpenApiSpec.Servers = append(s.OpenApiSpec.Servers, &openapi3.Server{ - URL: fmt.Sprintf("%s://%s", s.proto(), addr), - Description: "local server", - }) - s.startTime = time.Now() if s.autoAuth.Enabled { @@ -401,7 +392,6 @@ func WithoutLogger() func(*Server) { func WithListener(listener net.Listener) func(*Server) { return func(s *Server) { s.listener = listener - s.Addr = s.listener.Addr().String() } } From 401b5e4779cccbd03aa6a1cf6519578b1c5e4260 Mon Sep 17 00:00:00 2001 From: dylanhitt Date: Fri, 20 Dec 2024 12:43:17 -0500 Subject: [PATCH 122/138] chore: add tests for use of WithListener --- serve.go | 5 +---- serve_test.go | 44 +++++++++++++++++++++++++++++++++++--------- server_test.go | 17 +++++++++++++++++ 3 files changed, 53 insertions(+), 13 deletions(-) diff --git a/serve.go b/serve.go index 6eb55260..657d5994 100644 --- a/serve.go +++ b/serve.go @@ -53,11 +53,8 @@ func (s *Server) setupDefaultListener() error { return nil } listener, err := net.Listen("tcp", s.Addr) - if err != nil { - return err - } s.listener = listener - return nil + return err } func (s *Server) printStartupMessage() { diff --git a/serve_test.go b/serve_test.go index 18540c9c..d2cd7eca 100644 --- a/serve_test.go +++ b/serve_test.go @@ -390,13 +390,7 @@ func TestIni(t *testing.T) { } func TestServer_Run(t *testing.T) { - // This is not a standard test, it is here to ensure that the server can run. - // Please do not run this kind of test for your controllers, it is NOT unit testing. - t.Run("can run server", func(t *testing.T) { - s := NewServer( - WithoutLogger(), - ) - + runServer := func(s *Server) (*Server, func()) { Get(s, "/test", func(ctx ContextNoBody) (string, error) { return "OK", nil }) @@ -404,13 +398,21 @@ func TestServer_Run(t *testing.T) { go func() { s.Run() }() - defer func() { // stop our test server when we are done + return s, func() { // stop our test server when we are done ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) if err := s.Server.Shutdown(ctx); err != nil { t.Log(err) } cancel() - }() + } + } + // This is not a standard test, it is here to ensure that the server can run. + // Please do not run this kind of test for your controllers, it is NOT unit testing. + t.Run("can run server", func(t *testing.T) { + s, shutdown := runServer(NewServer( + WithoutLogger(), + )) + defer shutdown() require.Eventually(t, func() bool { req := httptest.NewRequest("GET", "/test", nil) @@ -420,6 +422,30 @@ func TestServer_Run(t *testing.T) { return w.Body.String() == `OK` }, 5*time.Second, 500*time.Millisecond) }) + + t.Run("can run server WithListener", func(t *testing.T) { + listener, err := net.Listen("tcp", ":8080") + require.NoError(t, err) + s, shutdown := runServer(NewServer( + WithListener(listener), + )) + defer shutdown() + + require.Eventually(t, func() bool { + req := httptest.NewRequest("GET", "/test", nil) + w := httptest.NewRecorder() + s.Mux.ServeHTTP(w, req) + + return w.Body.String() == `OK` + }, 5*time.Second, 500*time.Millisecond) + }) + + t.Run("invalid address", func(t *testing.T) { + s := NewServer( + WithAddr("----:nope"), + ) + require.Error(t, s.Run()) + }) } func TestServer_RunTLS(t *testing.T) { diff --git a/server_test.go b/server_test.go index 45dd8bcd..895fcb8a 100644 --- a/server_test.go +++ b/server_test.go @@ -5,6 +5,7 @@ import ( "html/template" "io" "log/slog" + "net" "net/http" "net/http/httptest" "testing" @@ -339,6 +340,22 @@ func TestWithRequestContentType(t *testing.T) { }) } +func TestWithListener(t *testing.T) { + t.Run("with custom listener", func(t *testing.T) { + listener, err := net.Listen("tcp", ":8080") + require.NoError(t, err) + s := NewServer( + WithListener(listener), + ) + require.NotNil(t, s.listener) + }) + + t.Run("no custom listener", func(t *testing.T) { + s := NewServer() + require.Nil(t, s.listener) + }) +} + func TestCustomSerialization(t *testing.T) { s := NewServer( WithSerializer(func(w http.ResponseWriter, r *http.Request, a any) error { From d02f27009a8e92338a4982654e9608f7bfaee628 Mon Sep 17 00:00:00 2001 From: EwenQuim Date: Thu, 19 Dec 2024 12:17:58 +0100 Subject: [PATCH 123/138] Moved shared context information to internal package --- ctx.go | 38 +++++++++++++------------------------- internal/common_context.go | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 25 deletions(-) create mode 100644 internal/common_context.go diff --git a/ctx.go b/ctx.go index 53ca5874..ebd1f897 100644 --- a/ctx.go +++ b/ctx.go @@ -12,6 +12,8 @@ import ( "strconv" "strings" "time" + + "github.com/go-fuego/fuego/internal" ) const ( @@ -77,6 +79,12 @@ type ContextWithBody[B any] interface { Header(key string) string // Get request header SetHeader(key, value string) // Sets response header + // Returns the underlying net/http, gin or echo context. + // + // Usage: + // ctx := c.Context() // net/http: the [context.Context] of the *http.Request + // ctx := c.Context().(*gin.Context) // gin: Safe because the underlying context is always a [gin.Context] + // ctx := c.Context().(echo.Context) // echo: Safe because the underlying context is always a [echo.Context] Context() context.Context Request() *http.Request // Request returns the underlying HTTP request. @@ -98,6 +106,9 @@ type ContextWithBody[B any] interface { // NewNetHTTPContext returns a new context. It is used internally by Fuego. You probably want to use Ctx[B] instead. func NewNetHTTPContext[B any](w http.ResponseWriter, r *http.Request, options readOptions) ContextWithBody[B] { c := &netHttpContext[B]{ + CommonContext: internal.CommonContext[B]{ + CommonCtx: r.Context(), + }, Res: w, Req: r, readOptions: readOptions{ @@ -119,6 +130,8 @@ var ( // has a Body. The Body type parameter represents the expected data type // from http.Request.Body. Please do not use a pointer as a type parameter. type netHttpContext[Body any] struct { + internal.CommonContext[Body] + body *Body // Cache the body in request context, because it is not possible to read an HTTP request body multiple times. Req *http.Request @@ -152,31 +165,6 @@ func (c netHttpContext[B]) Redirect(code int, url string) (any, error) { return nil, nil } -// ContextNoBody implements the context interface via [net/http.Request.Context] -func (c netHttpContext[B]) Deadline() (deadline time.Time, ok bool) { - return c.Req.Context().Deadline() -} - -// ContextNoBody implements the context interface via [net/http.Request.Context] -func (c netHttpContext[B]) Done() <-chan struct{} { - return c.Req.Context().Done() -} - -// ContextNoBody implements the context interface via [net/http.Request.Context] -func (c netHttpContext[B]) Err() error { - return c.Req.Context().Err() -} - -// ContextNoBody implements the context interface via [net/http.Request.Context] -func (c netHttpContext[B]) Value(key any) any { - return c.Req.Context().Value(key) -} - -// ContextNoBody implements the context interface via [net/http.Request.Context] -func (c netHttpContext[B]) Context() context.Context { - return c.Req.Context() -} - // Get request header func (c netHttpContext[B]) Header(key string) string { return c.Request().Header.Get(key) diff --git a/internal/common_context.go b/internal/common_context.go new file mode 100644 index 00000000..8e787ac4 --- /dev/null +++ b/internal/common_context.go @@ -0,0 +1,35 @@ +package internal + +import ( + "context" + "time" +) + +// Base context shared by all adaptors (net/http, gin, echo, etc...) +type CommonContext[B any] struct { + CommonCtx context.Context +} + +func (c CommonContext[B]) Context() context.Context { + return c.CommonCtx +} + +// ContextNoBody implements the context interface via [net/http.Request.Context] +func (c CommonContext[B]) Deadline() (deadline time.Time, ok bool) { + return c.Context().Deadline() +} + +// ContextNoBody implements the context interface via [net/http.Request.Context] +func (c CommonContext[B]) Done() <-chan struct{} { + return c.Context().Done() +} + +// ContextNoBody implements the context interface via [net/http.Request.Context] +func (c CommonContext[B]) Err() error { + return c.Context().Err() +} + +// ContextNoBody implements the context interface via [net/http.Request.Context] +func (c CommonContext[B]) Value(key any) any { + return c.Context().Value(key) +} From 6b5df4fba0598240ab9f8e74801fc4769e8ccbc2 Mon Sep 17 00:00:00 2001 From: EwenQuim Date: Thu, 19 Dec 2024 13:49:55 +0100 Subject: [PATCH 124/138] Share params between net/http and gin --- ctx.go | 156 +------------------------------- internal/common_context.go | 181 +++++++++++++++++++++++++++++++++++++ openapi_operations.go | 27 +----- serve.go | 9 +- server_test.go | 2 - validate_params.go | 4 +- 6 files changed, 195 insertions(+), 184 deletions(-) diff --git a/ctx.go b/ctx.go index ebd1f897..de8a83c0 100644 --- a/ctx.go +++ b/ctx.go @@ -6,10 +6,8 @@ import ( "html/template" "io" "io/fs" - "log/slog" "net/http" "net/url" - "strconv" "strings" "time" @@ -108,6 +106,7 @@ func NewNetHTTPContext[B any](w http.ResponseWriter, r *http.Request, options re c := &netHttpContext[B]{ CommonContext: internal.CommonContext[B]{ CommonCtx: r.Context(), + UrlValues: r.URL.Query(), }, Res: w, Req: r, @@ -115,7 +114,6 @@ func NewNetHTTPContext[B any](w http.ResponseWriter, r *http.Request, options re DisallowUnknownFields: options.DisallowUnknownFields, MaxBodySize: options.MaxBodySize, }, - urlValues: r.URL.Query(), } return c @@ -140,9 +138,6 @@ type netHttpContext[Body any] struct { fs fs.FS templates *template.Template - params map[string]OpenAPIParam // list of expected query parameters (declared in the OpenAPI spec) - urlValues url.Values - readOptions readOptions } @@ -219,155 +214,6 @@ func (c netHttpContext[B]) PathParam(name string) string { return c.Req.PathValue(name) } -type QueryParamNotFoundError struct { - ParamName string -} - -func (e QueryParamNotFoundError) Error() string { - return fmt.Errorf("param %s not found", e.ParamName).Error() -} - -type QueryParamInvalidTypeError struct { - ParamName string - ParamValue string - ExpectedType string - Err error -} - -func (e QueryParamInvalidTypeError) Error() string { - return fmt.Errorf("param %s=%s is not of type %s: %w", e.ParamName, e.ParamValue, e.ExpectedType, e.Err).Error() -} - -// QueryParams returns the query parameters of the request. It is a shortcut for c.Req.URL.Query(). -func (c netHttpContext[B]) QueryParams() url.Values { - return c.urlValues -} - -// QueryParamsArr returns an slice of string from the given query parameter. -func (c netHttpContext[B]) QueryParamArr(name string) []string { - _, ok := c.params[name] - if !ok { - slog.Warn("query parameter not expected in OpenAPI spec", "param", name) - } - return c.urlValues[name] -} - -// QueryParam returns the query parameter with the given name. -// If it does not exist, it returns an empty string, unless there is a default value declared in the OpenAPI spec. -// -// Example: -// -// fuego.Get(s, "/test", myController, -// option.Query("name", "Name", param.Default("hey")) -// ) -func (c netHttpContext[B]) QueryParam(name string) string { - _, ok := c.params[name] - if !ok { - slog.Warn("query parameter not expected in OpenAPI spec", "param", name, "expected_one_of", c.params) - } - - if !c.urlValues.Has(name) { - defaultValue, _ := c.params[name].Default.(string) - return defaultValue - } - return c.urlValues.Get(name) -} - -func (c netHttpContext[B]) QueryParamIntErr(name string) (int, error) { - param := c.QueryParam(name) - if param == "" { - defaultValue, ok := c.params[name].Default.(int) - if ok { - return defaultValue, nil - } - - return 0, QueryParamNotFoundError{ParamName: name} - } - - i, err := strconv.Atoi(param) - if err != nil { - return 0, QueryParamInvalidTypeError{ - ParamName: name, - ParamValue: param, - ExpectedType: "int", - Err: err, - } - } - - return i, nil -} - -// QueryParamInt returns the query parameter with the given name as an int. -// If it does not exist, it returns the default value declared in the OpenAPI spec. -// For example, if the query parameter is declared as: -// -// fuego.Get(s, "/test", myController, -// option.QueryInt("page", "Page number", param.Default(1)) -// ) -// -// and the query parameter does not exist, it will return 1. -// If the query parameter does not exist and there is no default value, or if it is not an int, it returns 0. -func (c netHttpContext[B]) QueryParamInt(name string) int { - param, err := c.QueryParamIntErr(name) - if err != nil { - return 0 - } - - return param -} - -// QueryParamBool returns the query parameter with the given name as a bool. -// If the query parameter does not exist or is not a bool, it returns the default value declared in the OpenAPI spec. -// For example, if the query parameter is declared as: -// -// fuego.Get(s, "/test", myController, -// option.QueryBool("is_ok", "Is OK?", param.Default(true)) -// ) -// -// and the query parameter does not exist in the HTTP request, it will return true. -// Accepted values are defined as [strconv.ParseBool] -func (c netHttpContext[B]) QueryParamBoolErr(name string) (bool, error) { - param := c.QueryParam(name) - if param == "" { - defaultValue, ok := c.params[name].Default.(bool) - if ok { - return defaultValue, nil - } - - return false, QueryParamNotFoundError{ParamName: name} - } - - b, err := strconv.ParseBool(param) - if err != nil { - return false, QueryParamInvalidTypeError{ - ParamName: name, - ParamValue: param, - ExpectedType: "bool", - Err: err, - } - } - return b, nil -} - -// QueryParamBool returns the query parameter with the given name as a bool. -// If the query parameter does not exist or is not a bool, it returns false. -// Accepted values are defined as [strconv.ParseBool] -// Example: -// -// fuego.Get(s, "/test", myController, -// option.QueryBool("is_ok", "Is OK?", param.Default(true)) -// ) -// -// and the query parameter does not exist in the HTTP request, it will return true. -func (c netHttpContext[B]) QueryParamBool(name string) bool { - param, err := c.QueryParamBoolErr(name) - if err != nil { - return false - } - - return param -} - func (c netHttpContext[B]) MainLang() string { return strings.Split(c.MainLocale(), "-")[0] } diff --git a/internal/common_context.go b/internal/common_context.go index 8e787ac4..8000569a 100644 --- a/internal/common_context.go +++ b/internal/common_context.go @@ -2,14 +2,46 @@ package internal import ( "context" + "fmt" + "log/slog" + "net/url" + "strconv" "time" ) +type OpenAPIParam struct { + Name string + Description string + + Required bool + Nullable bool + + // Default value for the parameter. + // Type is checked at start-time. + Default any + Example string + Examples map[string]any + Type ParamType + + // integer, string, bool + GoType string + + // Status codes for which this parameter is required. + // Only used for response parameters. + // If empty, it is required for 200 status codes. + StatusCodes []int +} + // Base context shared by all adaptors (net/http, gin, echo, etc...) type CommonContext[B any] struct { CommonCtx context.Context + + UrlValues url.Values + OpenAPIParams map[string]OpenAPIParam // list of expected query parameters (declared in the OpenAPI spec) } +type ParamType string // Query, Header, Cookie + func (c CommonContext[B]) Context() context.Context { return c.CommonCtx } @@ -33,3 +65,152 @@ func (c CommonContext[B]) Err() error { func (c CommonContext[B]) Value(key any) any { return c.Context().Value(key) } + +// QueryParams returns the query parameters of the request. It is a shortcut for c.Req.URL.Query(). +func (c CommonContext[B]) QueryParams() url.Values { + return c.UrlValues +} + +// QueryParam returns the query parameter with the given name. +// If it does not exist, it returns an empty string, unless there is a default value declared in the OpenAPI spec. +// +// Example: +// +// fuego.Get(s, "/test", myController, +// option.Query("name", "Name", param.Default("hey")) +// ) +func (c CommonContext[B]) QueryParam(name string) string { + _, ok := c.OpenAPIParams[name] + if !ok { + slog.Warn("query parameter not expected in OpenAPI spec", "param", name, "expected_one_of", c.OpenAPIParams) + } + + if !c.UrlValues.Has(name) { + defaultValue, _ := c.OpenAPIParams[name].Default.(string) + return defaultValue + } + return c.UrlValues.Get(name) +} + +func (c CommonContext[B]) QueryParamIntErr(name string) (int, error) { + param := c.QueryParam(name) + if param == "" { + defaultValue, ok := c.OpenAPIParams[name].Default.(int) + if ok { + return defaultValue, nil + } + + return 0, QueryParamNotFoundError{ParamName: name} + } + + i, err := strconv.Atoi(param) + if err != nil { + return 0, QueryParamInvalidTypeError{ + ParamName: name, + ParamValue: param, + ExpectedType: "int", + Err: err, + } + } + + return i, nil +} + +type QueryParamNotFoundError struct { + ParamName string +} + +func (e QueryParamNotFoundError) Error() string { + return fmt.Errorf("param %s not found", e.ParamName).Error() +} + +type QueryParamInvalidTypeError struct { + ParamName string + ParamValue string + ExpectedType string + Err error +} + +func (e QueryParamInvalidTypeError) Error() string { + return fmt.Errorf("param %s=%s is not of type %s: %w", e.ParamName, e.ParamValue, e.ExpectedType, e.Err).Error() +} + +// QueryParamsArr returns an slice of string from the given query parameter. +func (c CommonContext[B]) QueryParamArr(name string) []string { + _, ok := c.OpenAPIParams[name] + if !ok { + slog.Warn("query parameter not expected in OpenAPI spec", "param", name) + } + return c.UrlValues[name] +} + +// QueryParamInt returns the query parameter with the given name as an int. +// If it does not exist, it returns the default value declared in the OpenAPI spec. +// For example, if the query parameter is declared as: +// +// fuego.Get(s, "/test", myController, +// option.QueryInt("page", "Page number", param.Default(1)) +// ) +// +// and the query parameter does not exist, it will return 1. +// If the query parameter does not exist and there is no default value, or if it is not an int, it returns 0. +func (c CommonContext[B]) QueryParamInt(name string) int { + param, err := c.QueryParamIntErr(name) + if err != nil { + return 0 + } + + return param +} + +// QueryParamBool returns the query parameter with the given name as a bool. +// If the query parameter does not exist or is not a bool, it returns the default value declared in the OpenAPI spec. +// For example, if the query parameter is declared as: +// +// fuego.Get(s, "/test", myController, +// option.QueryBool("is_ok", "Is OK?", param.Default(true)) +// ) +// +// and the query parameter does not exist in the HTTP request, it will return true. +// Accepted values are defined as [strconv.ParseBool] +func (c CommonContext[B]) QueryParamBoolErr(name string) (bool, error) { + param := c.QueryParam(name) + if param == "" { + defaultValue, ok := c.OpenAPIParams[name].Default.(bool) + if ok { + return defaultValue, nil + } + + return false, QueryParamNotFoundError{ParamName: name} + } + + b, err := strconv.ParseBool(param) + if err != nil { + return false, QueryParamInvalidTypeError{ + ParamName: name, + ParamValue: param, + ExpectedType: "bool", + Err: err, + } + } + return b, nil +} + +// QueryParamBool returns the query parameter with the given name as a bool. +// If the query parameter does not exist or is not a bool, it returns false. +// Accepted values are defined as [strconv.ParseBool] +// Example: +// +// fuego.Get(s, "/test", myController, +// option.QueryBool("is_ok", "Is OK?", param.Default(true)) +// ) +// +// and the query parameter does not exist in the HTTP request, it will return true. +func (c CommonContext[B]) QueryParamBool(name string) bool { + param, err := c.QueryParamBoolErr(name) + if err != nil { + return false + } + + return param +} diff --git a/openapi_operations.go b/openapi_operations.go index 77a4cc02..0781cf37 100644 --- a/openapi_operations.go +++ b/openapi_operations.go @@ -4,9 +4,11 @@ import ( "strconv" "github.com/getkin/kin-openapi/openapi3" + + "github.com/go-fuego/fuego/internal" ) -type ParamType string // Query, Header, Cookie +type ParamType = internal.ParamType // Query, Header, Cookie const ( PathParamType ParamType = "path" @@ -15,28 +17,7 @@ const ( CookieParamType ParamType = "cookie" ) -type OpenAPIParam struct { - Name string - Description string - OpenAPIParamOption -} - -type OpenAPIParamOption struct { - Required bool - Nullable bool - // Default value for the parameter. - // Type is checked at start-time. - Default any - Example string - Examples map[string]any - Type ParamType - // integer, string, bool - GoType string - // Status codes for which this parameter is required. - // Only used for response parameters. - // If empty, it is required for 200 status codes. - StatusCodes []int -} +type OpenAPIParam = internal.OpenAPIParam // Registers a response for the route, only if error for this code is not already set. func addResponseIfNotSet(openapi *OpenAPI, operation *openapi3.Operation, code int, description string, response Response) { diff --git a/serve.go b/serve.go index f6c0e4a8..b963e6d7 100644 --- a/serve.go +++ b/serve.go @@ -6,6 +6,8 @@ import ( "net/http" "reflect" "time" + + "github.com/go-fuego/fuego/internal" ) // Run starts the server. @@ -77,6 +79,11 @@ func HTTPHandler[ReturnType, Body any](s *Server, controller func(c ContextWithB } ctx := &netHttpContext[Body]{ + CommonContext: internal.CommonContext[Body]{ + CommonCtx: r.Context(), + UrlValues: r.URL.Query(), + OpenAPIParams: route.Params, + }, Req: r, Res: w, readOptions: readOptions{ @@ -85,8 +92,6 @@ func HTTPHandler[ReturnType, Body any](s *Server, controller func(c ContextWithB }, fs: s.fs, templates: templates, - params: route.Params, - urlValues: r.URL.Query(), } err := validateParams(*ctx) diff --git a/server_test.go b/server_test.go index 3a71fb56..f1370364 100644 --- a/server_test.go +++ b/server_test.go @@ -460,8 +460,6 @@ func TestGroupParamsInMainServerInstance(t *testing.T) { route := Get(s, "/test", controller) require.Equal(t, "test-value", route.Operation.Parameters.GetByInAndName("header", "X-Test-Header").Description) - // expectedParams := map[string]OpenAPIParam{"X-Test-Header": {Name: "X-Test-Header", Description: "test-value", OpenAPIParamOption: OpenAPIParamOption{Required: false, Example: "", Type: ""}}} - // require.Equal(t, expectedParams, route.Params) } func TestHideGroupAfterGroupParam(t *testing.T) { diff --git a/validate_params.go b/validate_params.go index d29d2b5c..b545398d 100644 --- a/validate_params.go +++ b/validate_params.go @@ -3,7 +3,7 @@ package fuego import "fmt" func validateParams[B any](c netHttpContext[B]) error { - for k, param := range c.params { + for k, param := range c.OpenAPIParams { if param.Default != nil { // skip: param has a default continue @@ -12,7 +12,7 @@ func validateParams[B any](c netHttpContext[B]) error { if param.Required { switch param.Type { case QueryParamType: - if !c.urlValues.Has(k) { + if !c.UrlValues.Has(k) { err := fmt.Errorf("%s is a required query param", k) return BadRequestError{ Title: "Query Param Not Found", From 299138853a92c25f8e993fffe5e14366c962aeca Mon Sep 17 00:00:00 2001 From: EwenQuim Date: Fri, 20 Dec 2024 18:32:10 +0100 Subject: [PATCH 125/138] Optimize OpenAPIParam struct field alignment --- ctx.go | 5 +++-- internal/common_context.go | 6 +++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/ctx.go b/ctx.go index de8a83c0..08ac8f63 100644 --- a/ctx.go +++ b/ctx.go @@ -105,8 +105,9 @@ type ContextWithBody[B any] interface { func NewNetHTTPContext[B any](w http.ResponseWriter, r *http.Request, options readOptions) ContextWithBody[B] { c := &netHttpContext[B]{ CommonContext: internal.CommonContext[B]{ - CommonCtx: r.Context(), - UrlValues: r.URL.Query(), + CommonCtx: r.Context(), + UrlValues: r.URL.Query(), + OpenAPIParams: make(map[string]OpenAPIParam), }, Res: w, Req: r, diff --git a/internal/common_context.go b/internal/common_context.go index 8000569a..bba70180 100644 --- a/internal/common_context.go +++ b/internal/common_context.go @@ -13,9 +13,6 @@ type OpenAPIParam struct { Name string Description string - Required bool - Nullable bool - // Default value for the parameter. // Type is checked at start-time. Default any @@ -30,6 +27,9 @@ type OpenAPIParam struct { // Only used for response parameters. // If empty, it is required for 200 status codes. StatusCodes []int + + Required bool + Nullable bool } // Base context shared by all adaptors (net/http, gin, echo, etc...) From 6a7c0cb3cbf3c13b7556712d20fd000163bc3b98 Mon Sep 17 00:00:00 2001 From: Ewen Quimerc'h <46993939+EwenQuim@users.noreply.github.com> Date: Fri, 20 Dec 2024 19:35:28 +0100 Subject: [PATCH 126/138] Moved all non-net/http related code to the new Engine struct (#290) --- engine.go | 16 ++++++++++++++++ server.go | 20 +++++++++----------- 2 files changed, 25 insertions(+), 11 deletions(-) create mode 100644 engine.go diff --git a/engine.go b/engine.go new file mode 100644 index 00000000..acb89568 --- /dev/null +++ b/engine.go @@ -0,0 +1,16 @@ +package fuego + +func NewEngine() *Engine { + return &Engine{ + OpenAPI: NewOpenAPI(), + ErrorHandler: ErrorHandler, + } +} + +// The Engine is the main struct of the framework. +type Engine struct { + OpenAPI *OpenAPI + ErrorHandler func(error) error + + acceptedContentTypes []string +} diff --git a/server.go b/server.go index ad146ede..a573c4e2 100644 --- a/server.go +++ b/server.go @@ -56,8 +56,7 @@ type Server struct { disableAutoGroupTags bool basePath string // Base path of the group - // Points to the server OpenAPI struct. - OpenAPI *OpenAPI + *Engine Security Security @@ -65,16 +64,16 @@ type Server struct { fs fs.FS template *template.Template // TODO: use preparsed templates - acceptedContentTypes []string - DisallowUnknownFields bool // If true, the server will return an error if the request body contains unknown fields. Useful for quick debugging in development. DisableOpenapi bool // If true, the routes within the server will not generate an OpenAPI spec. maxBodySize int64 - Serialize Sender // Custom serializer that overrides the default one. - SerializeError ErrorSender // Used to serialize the error response. Defaults to [SendError]. - ErrorHandler func(err error) error // Used to transform any error into a unified error type structure with status code. Defaults to [ErrorHandler] - startTime time.Time + // Custom serializer that overrides the default one. + Serialize Sender + // Used to serialize the error response. Defaults to [SendError]. + SerializeError ErrorSender + + startTime time.Time OpenAPIConfig OpenAPIConfig @@ -99,8 +98,8 @@ func NewServer(options ...func(*Server)) *Server { WriteTimeout: 30 * time.Second, IdleTimeout: 30 * time.Second, }, - Mux: http.NewServeMux(), - OpenAPI: NewOpenAPI(), + Mux: http.NewServeMux(), + Engine: NewEngine(), OpenAPIConfig: defaultOpenAPIConfig, @@ -113,7 +112,6 @@ func NewServer(options ...func(*Server)) *Server { WithDisallowUnknownFields(true), WithSerializer(Send), WithErrorSerializer(SendError), - WithErrorHandler(ErrorHandler), WithRouteOptions( OptionAddResponse(http.StatusBadRequest, "Bad Request _(validation or deserialization error)_", Response{Type: HTTPError{}}), OptionAddResponse(http.StatusInternalServerError, "Internal Server Error _(panics)_", Response{Type: HTTPError{}}), From 7465f373e1aac6655b9cc9564f39e39691b02a80 Mon Sep 17 00:00:00 2001 From: dylanhitt Date: Fri, 20 Dec 2024 14:31:24 -0500 Subject: [PATCH 127/138] chore: change RunTLS test to use require.Eventually/httptest --- serve_test.go | 30 ++++++------------------------ 1 file changed, 6 insertions(+), 24 deletions(-) diff --git a/serve_test.go b/serve_test.go index 18540c9c..603b5260 100644 --- a/serve_test.go +++ b/serve_test.go @@ -9,10 +9,8 @@ import ( "crypto/x509/pkix" "encoding/pem" "errors" - "fmt" "io" "math/big" - "net" "net/http" "net/http/httptest" "os" @@ -485,29 +483,13 @@ func TestServer_RunTLS(t *testing.T) { cancel() }() - // wait for the server to start - conn, err := net.DialTimeout("tcp", s.Server.Addr, 5*time.Second) - if err != nil { - t.Fatal(err) - } - defer conn.Close() - - client := &http.Client{Transport: &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}}} - req, err := http.NewRequest("GET", fmt.Sprintf("https://%s/test", s.Server.Addr), nil) - if err != nil { - t.Fatal(err) - } - req.Header.Set("Accept", "text/plain") + require.Eventually(t, func() bool { + req := httptest.NewRequest("GET", "https://localhost:3005/test", nil) + w := httptest.NewRecorder() + s.Mux.ServeHTTP(w, req) - resp, err := client.Do(req) - if err != nil { - t.Fatal(err) - } - body, err := io.ReadAll(resp.Body) - if err != nil { - t.Fatal(err) - } - require.Equal(t, []byte("OK"), body) + return w.Body.String() == `OK` + }, 5*time.Second, 500*time.Millisecond) }) } } From ff572b841d3f6bbaffc8ed4eddcb7cad3f8d5d01 Mon Sep 17 00:00:00 2001 From: Dylan Hitt Date: Fri, 20 Dec 2024 18:24:58 -0500 Subject: [PATCH 128/138] OptionShow (#291) * feat: add OptionShow * chore: nolint on Engine.acceptedContentTypes --- mux.go | 2 +- mux_test.go | 5 ----- openapi.go | 10 ++++++++-- option.go | 7 +++++++ option/option.go | 3 +++ server.go | 4 ++-- 6 files changed, 21 insertions(+), 10 deletions(-) diff --git a/mux.go b/mux.go index 355c7696..6267d408 100644 --- a/mux.go +++ b/mux.go @@ -86,7 +86,7 @@ func Register[T, B any](s *Server, route Route[T, B], controller http.Handler, o route.Middlewares = append(s.middlewares, route.Middlewares...) s.Mux.Handle(fullPath, withMiddlewares(route.Handler, route.Middlewares...)) - if s.DisableOpenapi || route.Hidden || route.Method == "" { + if route.Hidden || route.Method == "" { return &route } diff --git a/mux_test.go b/mux_test.go index 4e6a67e3..e3f0bdc6 100644 --- a/mux_test.go +++ b/mux_test.go @@ -487,7 +487,6 @@ func TestHideOpenapiRoutes(t *testing.T) { s.Hide() Get(s, "/test", func(ctx ContextNoBody) (string, error) { return "", nil }) - require.Equal(t, s.DisableOpenapi, true) require.True(t, s.OpenAPI.Description().Paths.Find("/not-hidden") != nil) require.True(t, s.OpenAPI.Description().Paths.Find("/test") == nil) }) @@ -499,7 +498,6 @@ func TestHideOpenapiRoutes(t *testing.T) { g := Group(s, "/group").Hide() Get(g, "/test", func(ctx ContextNoBody) (string, error) { return "", nil }) - require.Equal(t, g.DisableOpenapi, true) require.True(t, s.OpenAPI.Description().Paths.Find("/not-hidden") != nil) require.True(t, s.OpenAPI.Description().Paths.Find("/group/test") == nil) }) @@ -512,8 +510,6 @@ func TestHideOpenapiRoutes(t *testing.T) { g2 := Group(s, "/group2") Get(g2, "/test", func(ctx ContextNoBody) (string, error) { return "test", nil }) - require.Equal(t, true, g.DisableOpenapi) - require.Equal(t, false, g2.DisableOpenapi) require.True(t, s.OpenAPI.Description().Paths.Find("/group/test") == nil) require.True(t, s.OpenAPI.Description().Paths.Find("/group2/test") != nil) }) @@ -526,7 +522,6 @@ func TestHideOpenapiRoutes(t *testing.T) { g2 := Group(g, "/sub").Show() Get(g2, "/test", func(ctx ContextNoBody) (string, error) { return "test", nil }) - require.Equal(t, true, g.DisableOpenapi) require.True(t, s.OpenAPI.Description().Paths.Find("/group/test") == nil) require.True(t, s.OpenAPI.Description().Paths.Find("/group/sub/test") != nil) }) diff --git a/openapi.go b/openapi.go index 5bf95723..a30ce75a 100644 --- a/openapi.go +++ b/openapi.go @@ -85,15 +85,21 @@ func NewOpenApiSpec() openapi3.T { } // Hide prevents the routes in this server or group from being included in the OpenAPI spec. +// Deprecated: Please use [OptionHide] with [WithRouteOptions] func (s *Server) Hide() *Server { - s.DisableOpenapi = true + WithRouteOptions( + OptionHide(), + )(s) return s } // Show allows displaying the routes. Activated by default so useless in most cases, // but this can be useful if you deactivated the parent group. +// Deprecated: Please use [OptionShow] with [WithRouteOptions] func (s *Server) Show() *Server { - s.DisableOpenapi = false + WithRouteOptions( + OptionShow(), + )(s) return s } diff --git a/option.go b/option.go index b3b97cfc..0f3d26c3 100644 --- a/option.go +++ b/option.go @@ -371,6 +371,13 @@ func OptionHide() func(*BaseRoute) { } } +// Show shows the route from the OpenAPI spec. +func OptionShow() func(*BaseRoute) { + return func(r *BaseRoute) { + r.Hidden = false + } +} + // OptionDefaultStatusCode sets the default status code for the route. func OptionDefaultStatusCode(defaultStatusCode int) func(*BaseRoute) { return func(r *BaseRoute) { diff --git a/option/option.go b/option/option.go index 3dd1db8e..5cdadeaf 100644 --- a/option/option.go +++ b/option/option.go @@ -170,5 +170,8 @@ var RequestContentType = fuego.OptionRequestContentType // Hide hides the route from the OpenAPI spec. var Hide = fuego.OptionHide +// Show shows the route from the OpenAPI spec. +var Show = fuego.OptionShow + // DefaultStatusCode sets the default status code for the route. var DefaultStatusCode = fuego.OptionDefaultStatusCode diff --git a/server.go b/server.go index a573c4e2..452be969 100644 --- a/server.go +++ b/server.go @@ -64,8 +64,8 @@ type Server struct { fs fs.FS template *template.Template // TODO: use preparsed templates - DisallowUnknownFields bool // If true, the server will return an error if the request body contains unknown fields. Useful for quick debugging in development. - DisableOpenapi bool // If true, the routes within the server will not generate an OpenAPI spec. + // If true, the server will return an error if the request body contains unknown fields. Useful for quick debugging in development. + DisallowUnknownFields bool maxBodySize int64 // Custom serializer that overrides the default one. From 2a78faaeef286e62b32f2e01fa3f141e5ba74411 Mon Sep 17 00:00:00 2001 From: dylanhitt Date: Fri, 20 Dec 2024 17:02:19 -0500 Subject: [PATCH 129/138] chore: comment Deprecated -> OptionDeprecated --- option.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/option.go b/option.go index 0f3d26c3..11d135ab 100644 --- a/option.go +++ b/option.go @@ -293,7 +293,7 @@ func OptionOperationID(operationID string) func(*BaseRoute) { } } -// Deprecated marks the route as deprecated. +// OptionDeprecated marks the route as deprecated. func OptionDeprecated() func(*BaseRoute) { return func(r *BaseRoute) { r.Operation.Deprecated = true From 6b04996794c60dd9897dcdbe4b42c8d1ecc57b0f Mon Sep 17 00:00:00 2001 From: EwenQuim Date: Sat, 21 Dec 2024 10:37:54 +0100 Subject: [PATCH 130/138] =?UTF-8?q?Replace=20=E2=80=9C...=E2=80=9D=20by=20?= =?UTF-8?q?ellipsis=20=E2=80=9C=E2=80=A6=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mux.go | 2 +- option_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mux.go b/mux.go index 6267d408..ed8fee16 100644 --- a/mux.go +++ b/mux.go @@ -212,7 +212,7 @@ func DefaultDescription[T any](handler string, middlewares []T) string { description += "\n- `" + FuncName(fn) + "`" if i == 4 { - description += "\n- more middleware..." + description += "\n- more middleware…" break } } diff --git a/option_test.go b/option_test.go index 43026497..c21339d8 100644 --- a/option_test.go +++ b/option_test.go @@ -829,7 +829,7 @@ func TestOptionDescription(t *testing.T) { option.Middleware(dummyMiddleware), // 7th middleware, should not be included ) - require.Equal(t, "#### Controller: \n\n`github.com/go-fuego/fuego_test.helloWorld`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego_test.dummyMiddleware`\n- `github.com/go-fuego/fuego_test.dummyMiddleware`\n- `github.com/go-fuego/fuego_test.dummyMiddleware`\n- `github.com/go-fuego/fuego_test.dummyMiddleware`\n- `github.com/go-fuego/fuego_test.dummyMiddleware`\n- more middleware...\n\n---\n\nanother description", route.Operation.Description) + require.Equal(t, "#### Controller: \n\n`github.com/go-fuego/fuego_test.helloWorld`\n\n#### Middlewares:\n\n- `github.com/go-fuego/fuego_test.dummyMiddleware`\n- `github.com/go-fuego/fuego_test.dummyMiddleware`\n- `github.com/go-fuego/fuego_test.dummyMiddleware`\n- `github.com/go-fuego/fuego_test.dummyMiddleware`\n- `github.com/go-fuego/fuego_test.dummyMiddleware`\n- more middleware…\n\n---\n\nanother description", route.Operation.Description) }) } From 0a1f2a2ed1fc410a5a1823962171cfbeb5eb4274 Mon Sep 17 00:00:00 2001 From: EwenQuim Date: Sat, 21 Dec 2024 10:38:55 +0100 Subject: [PATCH 131/138] Updated the documentation for the ContextWithBody interface. --- ctx.go | 2 +- html.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ctx.go b/ctx.go index 08ac8f63..2ca4017b 100644 --- a/ctx.go +++ b/ctx.go @@ -20,7 +20,7 @@ const ( type ContextNoBody = ContextWithBody[any] -// ctx is the context of the request. +// ContextWithBody is the context of the request. // It contains the request body, the path parameters, the query parameters, and the HTTP request. // Please do not use a pointer type as parameter. type ContextWithBody[B any] interface { diff --git a/html.go b/html.go index 4d8cc59b..d92a00d8 100644 --- a/html.go +++ b/html.go @@ -49,7 +49,7 @@ type Renderer interface { type Gomponent = Renderer // HTML is a marker type used to differentiate between a string response and an HTML response. -// To use templating, use [Ctx.Render]. +// To use templating, use [Context.Render]. type HTML string // H is a shortcut for map[string]any From b4be136426a3445966ef25bf549c0ba6f3185d5a Mon Sep 17 00:00:00 2001 From: EwenQuim Date: Sun, 22 Dec 2024 09:09:17 +0100 Subject: [PATCH 132/138] Make ValidateParams take an interface instead of netHttpContext only --- ctx.go | 11 ++++++----- internal/common_context.go | 11 +++++++++++ serve.go | 3 ++- validate_params.go | 14 +++++++++++--- 4 files changed, 30 insertions(+), 9 deletions(-) diff --git a/ctx.go b/ctx.go index 2ca4017b..6a8aefe3 100644 --- a/ctx.go +++ b/ctx.go @@ -120,11 +120,6 @@ func NewNetHTTPContext[B any](w http.ResponseWriter, r *http.Request, options re return c } -var ( - _ ContextWithBody[any] = &netHttpContext[any]{} // Check that ContextWithBody implements Ctx. - _ ContextWithBody[string] = &netHttpContext[string]{} // Check that ContextWithBody implements Ctx. -) - // ContextWithBody is the same as fuego.ContextNoBody, but // has a Body. The Body type parameter represents the expected data type // from http.Request.Body. Please do not use a pointer as a type parameter. @@ -142,6 +137,12 @@ type netHttpContext[Body any] struct { readOptions readOptions } +var ( + _ ContextWithBody[any] = &netHttpContext[any]{} // Check that ContextWithBody implements Ctx. + _ ContextWithBody[string] = &netHttpContext[string]{} // Check that ContextWithBody implements Ctx. + _ ValidableCtx = &netHttpContext[any]{} // Check that ContextWithBody implements ValidableCtx. +) + // SetStatus sets the status code of the response. // Alias to http.ResponseWriter.WriteHeader. func (c netHttpContext[B]) SetStatus(code int) { diff --git a/internal/common_context.go b/internal/common_context.go index bba70180..78315e0e 100644 --- a/internal/common_context.go +++ b/internal/common_context.go @@ -42,6 +42,11 @@ type CommonContext[B any] struct { type ParamType string // Query, Header, Cookie +// GetOpenAPIParams returns the OpenAPI parameters declared in the OpenAPI spec. +func (c CommonContext[B]) GetOpenAPIParams() map[string]OpenAPIParam { + return c.OpenAPIParams +} + func (c CommonContext[B]) Context() context.Context { return c.CommonCtx } @@ -71,6 +76,12 @@ func (c CommonContext[B]) QueryParams() url.Values { return c.UrlValues } +// HasQueryParam returns true if the query parameter with the given name exists. +func (c CommonContext[B]) HasQueryParam(name string) bool { + _, ok := c.UrlValues[name] + return ok +} + // QueryParam returns the query parameter with the given name. // If it does not exist, it returns an empty string, unless there is a default value declared in the OpenAPI spec. // diff --git a/serve.go b/serve.go index b963e6d7..516b92a4 100644 --- a/serve.go +++ b/serve.go @@ -94,7 +94,8 @@ func HTTPHandler[ReturnType, Body any](s *Server, controller func(c ContextWithB templates: templates, } - err := validateParams(*ctx) + // PARAMS VALIDATION + err := ValidateParams(ctx) if err != nil { err = s.ErrorHandler(err) s.SerializeError(w, r, err) diff --git a/validate_params.go b/validate_params.go index b545398d..7679a083 100644 --- a/validate_params.go +++ b/validate_params.go @@ -2,8 +2,16 @@ package fuego import "fmt" -func validateParams[B any](c netHttpContext[B]) error { - for k, param := range c.OpenAPIParams { +type ValidableCtx interface { + GetOpenAPIParams() map[string]OpenAPIParam + HasQueryParam(key string) bool + HasHeader(key string) bool + HasCookie(key string) bool +} + +// ValidateParams checks if all required parameters are present in the request. +func ValidateParams(c ValidableCtx) error { + for k, param := range c.GetOpenAPIParams() { if param.Default != nil { // skip: param has a default continue @@ -12,7 +20,7 @@ func validateParams[B any](c netHttpContext[B]) error { if param.Required { switch param.Type { case QueryParamType: - if !c.UrlValues.Has(k) { + if !c.HasQueryParam(k) { err := fmt.Errorf("%s is a required query param", k) return BadRequestError{ Title: "Query Param Not Found", From 3dc77c6f0397ba2696ddfc5b24729bd9edd8fb79 Mon Sep 17 00:00:00 2001 From: EwenQuim Date: Sun, 22 Dec 2024 11:35:24 +0100 Subject: [PATCH 133/138] Fixes tests from /cmd package --- cmd/fuego/commands/controller_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/fuego/commands/controller_test.go b/cmd/fuego/commands/controller_test.go index 9cb4a575..a843075c 100644 --- a/cmd/fuego/commands/controller_test.go +++ b/cmd/fuego/commands/controller_test.go @@ -10,9 +10,9 @@ import ( func TestCreateController(t *testing.T) { res, err := createNewEntityDomainFile("books", "controller.go", "booksController.go") require.NoError(t, err) - require.Contains(t, res, "package controller") + require.Contains(t, res, "package books") require.Contains(t, res, `fuego.Get(booksGroup, "/{id}", rs.getBooks)`) require.Contains(t, res, `func (rs BooksResources) postBooks(c fuego.ContextWithBody[BooksCreate]) (Books, error)`) - require.FileExists(t, "./controller/books.go") - os.Remove("./controller/books.go") + require.FileExists(t, "./domains/books/booksController.go") + os.Remove("./domains/books/booksController.go") } From 3593d75793679cb9aa2681697b590e168bb4f7aa Mon Sep 17 00:00:00 2001 From: EwenQuim Date: Sun, 22 Dec 2024 11:37:27 +0100 Subject: [PATCH 134/138] Updated all dependencies and requires Go 1.23 --- cmd/fuego/go.mod | 12 +++++----- cmd/fuego/go.sum | 16 +++++++------- examples/acme-tls/go.mod | 8 +++---- examples/acme-tls/go.sum | 12 +++++----- examples/basic/go.mod | 10 ++++----- examples/basic/go.sum | 16 +++++++------- examples/custom-errors/go.mod | 10 ++++----- examples/custom-errors/go.sum | 16 +++++++------- examples/custom-serializer/go.mod | 8 +++---- examples/custom-serializer/go.sum | 12 +++++----- examples/full-app-gourmet/go.mod | 24 ++++++++++---------- examples/full-app-gourmet/go.sum | 28 ++++++++++++------------ examples/generate-opengraph-image/go.mod | 8 +++---- examples/generate-opengraph-image/go.sum | 16 +++++++------- examples/hello-world/go.mod | 8 +++---- examples/hello-world/go.sum | 12 +++++----- examples/openapi/go.mod | 8 +++---- examples/openapi/go.sum | 12 +++++----- extra/markdown/go.mod | 2 +- go.mod | 6 ++--- go.sum | 8 +++---- middleware/basicauth/go.mod | 8 +++---- middleware/basicauth/go.sum | 12 +++++----- middleware/cache/go.mod | 2 +- testing-from-outside/go.mod | 2 +- 25 files changed, 136 insertions(+), 140 deletions(-) diff --git a/cmd/fuego/go.mod b/cmd/fuego/go.mod index b5a2d247..d48f8df1 100644 --- a/cmd/fuego/go.mod +++ b/cmd/fuego/go.mod @@ -1,18 +1,16 @@ module github.com/go-fuego/fuego/cmd/fuego -go 1.22.2 - -toolchain go1.22.5 +go 1.23.3 require ( - github.com/go-fuego/fuego v0.16.1 + github.com/go-fuego/fuego v0.16.2 github.com/stretchr/testify v1.10.0 github.com/urfave/cli/v2 v2.27.5 golang.org/x/text v0.21.0 ) require ( - github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.6 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/gabriel-vasile/mimetype v1.4.7 // indirect github.com/getkin/kin-openapi v0.128.0 // indirect @@ -26,14 +24,14 @@ require ( github.com/invopop/yaml v0.3.1 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/leodido/go-urn v1.4.0 // indirect - github.com/mailru/easyjson v0.7.7 // indirect + github.com/mailru/easyjson v0.9.0 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect golang.org/x/crypto v0.31.0 // indirect - golang.org/x/net v0.32.0 // indirect + golang.org/x/net v0.33.0 // indirect golang.org/x/sys v0.28.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/cmd/fuego/go.sum b/cmd/fuego/go.sum index 5a13b80d..19c8060b 100644 --- a/cmd/fuego/go.sum +++ b/cmd/fuego/go.sum @@ -1,13 +1,13 @@ -github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc= -github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.6 h1:XJtiaUW6dEEqVuZiMTn1ldk455QWwEIsMIJlo5vtkx0= +github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/gabriel-vasile/mimetype v1.4.7 h1:SKFKl7kD0RiPdbht0s7hFtjl489WcQ1VyPW8ZzUMYCA= github.com/gabriel-vasile/mimetype v1.4.7/go.mod h1:GDlAgAyIRT27BhFl53XNAFtfjzOkLaF35JdEG0P7LtU= github.com/getkin/kin-openapi v0.128.0 h1:jqq3D9vC9pPq1dGcOCv7yOp1DaEe7c/T1vzcLbITSp4= github.com/getkin/kin-openapi v0.128.0/go.mod h1:OZrfXzUfGrNbsKj+xmFBx6E5c6yH3At/tAKSc2UszXM= -github.com/go-fuego/fuego v0.16.1 h1:G+sDF55BjFI7FH7dd07HDx4jfNPxXEeab+YKuLjj5zY= -github.com/go-fuego/fuego v0.16.1/go.mod h1:ARPlRxY+RgbahF6ZvnjsESGQd3h/jCw8ksCJxKLbgjY= +github.com/go-fuego/fuego v0.16.2 h1:xEMJBbGEo/8324NTHbT4peLiM1g2dpYAiG08z/d0+dU= +github.com/go-fuego/fuego v0.16.2/go.mod h1:V4DCdygAVcKYKUyeizhb1J83azstmaCJWDSJNMzeTDE= github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= @@ -36,8 +36,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= +github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= @@ -60,8 +60,8 @@ github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGC github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM= golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= -golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= -golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs= +golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= +golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= diff --git a/examples/acme-tls/go.mod b/examples/acme-tls/go.mod index c40b192a..63bac972 100644 --- a/examples/acme-tls/go.mod +++ b/examples/acme-tls/go.mod @@ -1,10 +1,10 @@ module github.com/go-fuego/fuego/examples/acme-tls -go 1.22.2 +go 1.23.3 require ( github.com/caddyserver/certmagic v0.21.4 - github.com/go-fuego/fuego v0.16.1 + github.com/go-fuego/fuego v0.16.2 ) require ( @@ -23,7 +23,7 @@ require ( github.com/klauspost/cpuid/v2 v2.2.9 // indirect github.com/leodido/go-urn v1.4.0 // indirect github.com/libdns/libdns v0.2.2 // indirect - github.com/mailru/easyjson v0.7.7 // indirect + github.com/mailru/easyjson v0.9.0 // indirect github.com/mholt/acmez/v2 v2.0.3 // indirect github.com/miekg/dns v1.1.62 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect @@ -33,7 +33,7 @@ require ( go.uber.org/zap v1.27.0 // indirect golang.org/x/crypto v0.31.0 // indirect golang.org/x/mod v0.22.0 // indirect - golang.org/x/net v0.32.0 // indirect + golang.org/x/net v0.33.0 // indirect golang.org/x/sync v0.10.0 // indirect golang.org/x/sys v0.28.0 // indirect golang.org/x/text v0.21.0 // indirect diff --git a/examples/acme-tls/go.sum b/examples/acme-tls/go.sum index ece17be1..b218f6b1 100644 --- a/examples/acme-tls/go.sum +++ b/examples/acme-tls/go.sum @@ -8,8 +8,8 @@ github.com/gabriel-vasile/mimetype v1.4.7 h1:SKFKl7kD0RiPdbht0s7hFtjl489WcQ1VyPW github.com/gabriel-vasile/mimetype v1.4.7/go.mod h1:GDlAgAyIRT27BhFl53XNAFtfjzOkLaF35JdEG0P7LtU= github.com/getkin/kin-openapi v0.128.0 h1:jqq3D9vC9pPq1dGcOCv7yOp1DaEe7c/T1vzcLbITSp4= github.com/getkin/kin-openapi v0.128.0/go.mod h1:OZrfXzUfGrNbsKj+xmFBx6E5c6yH3At/tAKSc2UszXM= -github.com/go-fuego/fuego v0.16.1 h1:G+sDF55BjFI7FH7dd07HDx4jfNPxXEeab+YKuLjj5zY= -github.com/go-fuego/fuego v0.16.1/go.mod h1:ARPlRxY+RgbahF6ZvnjsESGQd3h/jCw8ksCJxKLbgjY= +github.com/go-fuego/fuego v0.16.2 h1:xEMJBbGEo/8324NTHbT4peLiM1g2dpYAiG08z/d0+dU= +github.com/go-fuego/fuego v0.16.2/go.mod h1:V4DCdygAVcKYKUyeizhb1J83azstmaCJWDSJNMzeTDE= github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= @@ -44,8 +44,8 @@ github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= github.com/libdns/libdns v0.2.2 h1:O6ws7bAfRPaBsgAYt8MDe2HcNBGC29hkZ9MX2eUSX3s= github.com/libdns/libdns v0.2.2/go.mod h1:4Bj9+5CQiNMVGf87wjX4CY3HQJypUHRuLvlsfsZqLWQ= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= +github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/mholt/acmez/v2 v2.0.3 h1:CgDBlEwg3QBp6s45tPQmFIBrkRIkBT4rW4orMM6p4sw= github.com/mholt/acmez/v2 v2.0.3/go.mod h1:pQ1ysaDeGrIMvJ9dfJMk5kJNkn7L2sb3UhyrX6Q91cw= github.com/miekg/dns v1.1.62 h1:cN8OuEF1/x5Rq6Np+h1epln8OiyPWV+lROx9LxcGgIQ= @@ -80,8 +80,8 @@ golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4= golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= -golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= -golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs= +golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= +golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= diff --git a/examples/basic/go.mod b/examples/basic/go.mod index b0ca4cc2..283748e7 100644 --- a/examples/basic/go.mod +++ b/examples/basic/go.mod @@ -1,10 +1,10 @@ module github.com/go-fuego/fuego/examples/basic -go 1.22.2 +go 1.23.3 require ( - github.com/go-chi/chi/v5 v5.1.0 - github.com/go-fuego/fuego v0.16.1 + github.com/go-chi/chi/v5 v5.2.0 + github.com/go-fuego/fuego v0.16.2 github.com/rs/cors v1.11.1 ) @@ -21,11 +21,11 @@ require ( github.com/invopop/yaml v0.3.1 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/leodido/go-urn v1.4.0 // indirect - github.com/mailru/easyjson v0.7.7 // indirect + github.com/mailru/easyjson v0.9.0 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect golang.org/x/crypto v0.31.0 // indirect - golang.org/x/net v0.32.0 // indirect + golang.org/x/net v0.33.0 // indirect golang.org/x/sys v0.28.0 // indirect golang.org/x/text v0.21.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/examples/basic/go.sum b/examples/basic/go.sum index 4116f07a..418ce635 100644 --- a/examples/basic/go.sum +++ b/examples/basic/go.sum @@ -4,10 +4,10 @@ github.com/gabriel-vasile/mimetype v1.4.7 h1:SKFKl7kD0RiPdbht0s7hFtjl489WcQ1VyPW github.com/gabriel-vasile/mimetype v1.4.7/go.mod h1:GDlAgAyIRT27BhFl53XNAFtfjzOkLaF35JdEG0P7LtU= github.com/getkin/kin-openapi v0.128.0 h1:jqq3D9vC9pPq1dGcOCv7yOp1DaEe7c/T1vzcLbITSp4= github.com/getkin/kin-openapi v0.128.0/go.mod h1:OZrfXzUfGrNbsKj+xmFBx6E5c6yH3At/tAKSc2UszXM= -github.com/go-chi/chi/v5 v5.1.0 h1:acVI1TYaD+hhedDJ3r54HyA6sExp3HfXq7QWEEY/xMw= -github.com/go-chi/chi/v5 v5.1.0/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= -github.com/go-fuego/fuego v0.16.1 h1:G+sDF55BjFI7FH7dd07HDx4jfNPxXEeab+YKuLjj5zY= -github.com/go-fuego/fuego v0.16.1/go.mod h1:ARPlRxY+RgbahF6ZvnjsESGQd3h/jCw8ksCJxKLbgjY= +github.com/go-chi/chi/v5 v5.2.0 h1:Aj1EtB0qR2Rdo2dG4O94RIU35w2lvQSj6BRA4+qwFL0= +github.com/go-chi/chi/v5 v5.2.0/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= +github.com/go-fuego/fuego v0.16.2 h1:xEMJBbGEo/8324NTHbT4peLiM1g2dpYAiG08z/d0+dU= +github.com/go-fuego/fuego v0.16.2/go.mod h1:V4DCdygAVcKYKUyeizhb1J83azstmaCJWDSJNMzeTDE= github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= @@ -36,8 +36,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= +github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= @@ -56,8 +56,8 @@ github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0 github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= -golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= -golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs= +golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= +golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= diff --git a/examples/custom-errors/go.mod b/examples/custom-errors/go.mod index 2ec98ad0..ba80aca6 100644 --- a/examples/custom-errors/go.mod +++ b/examples/custom-errors/go.mod @@ -1,10 +1,10 @@ module github.com/go-fuego/fuego/examples/custom-errors -go 1.22.2 +go 1.23.3 require ( - github.com/go-chi/chi/v5 v5.1.0 - github.com/go-fuego/fuego v0.16.1 + github.com/go-chi/chi/v5 v5.2.0 + github.com/go-fuego/fuego v0.16.2 github.com/rs/cors v1.11.1 ) @@ -21,11 +21,11 @@ require ( github.com/invopop/yaml v0.3.1 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/leodido/go-urn v1.4.0 // indirect - github.com/mailru/easyjson v0.7.7 // indirect + github.com/mailru/easyjson v0.9.0 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect golang.org/x/crypto v0.31.0 // indirect - golang.org/x/net v0.32.0 // indirect + golang.org/x/net v0.33.0 // indirect golang.org/x/sys v0.28.0 // indirect golang.org/x/text v0.21.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/examples/custom-errors/go.sum b/examples/custom-errors/go.sum index 4116f07a..418ce635 100644 --- a/examples/custom-errors/go.sum +++ b/examples/custom-errors/go.sum @@ -4,10 +4,10 @@ github.com/gabriel-vasile/mimetype v1.4.7 h1:SKFKl7kD0RiPdbht0s7hFtjl489WcQ1VyPW github.com/gabriel-vasile/mimetype v1.4.7/go.mod h1:GDlAgAyIRT27BhFl53XNAFtfjzOkLaF35JdEG0P7LtU= github.com/getkin/kin-openapi v0.128.0 h1:jqq3D9vC9pPq1dGcOCv7yOp1DaEe7c/T1vzcLbITSp4= github.com/getkin/kin-openapi v0.128.0/go.mod h1:OZrfXzUfGrNbsKj+xmFBx6E5c6yH3At/tAKSc2UszXM= -github.com/go-chi/chi/v5 v5.1.0 h1:acVI1TYaD+hhedDJ3r54HyA6sExp3HfXq7QWEEY/xMw= -github.com/go-chi/chi/v5 v5.1.0/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= -github.com/go-fuego/fuego v0.16.1 h1:G+sDF55BjFI7FH7dd07HDx4jfNPxXEeab+YKuLjj5zY= -github.com/go-fuego/fuego v0.16.1/go.mod h1:ARPlRxY+RgbahF6ZvnjsESGQd3h/jCw8ksCJxKLbgjY= +github.com/go-chi/chi/v5 v5.2.0 h1:Aj1EtB0qR2Rdo2dG4O94RIU35w2lvQSj6BRA4+qwFL0= +github.com/go-chi/chi/v5 v5.2.0/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= +github.com/go-fuego/fuego v0.16.2 h1:xEMJBbGEo/8324NTHbT4peLiM1g2dpYAiG08z/d0+dU= +github.com/go-fuego/fuego v0.16.2/go.mod h1:V4DCdygAVcKYKUyeizhb1J83azstmaCJWDSJNMzeTDE= github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= @@ -36,8 +36,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= +github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= @@ -56,8 +56,8 @@ github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0 github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= -golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= -golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs= +golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= +golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= diff --git a/examples/custom-serializer/go.mod b/examples/custom-serializer/go.mod index 465b365c..0eb98f82 100644 --- a/examples/custom-serializer/go.mod +++ b/examples/custom-serializer/go.mod @@ -1,9 +1,9 @@ module github.com/go-fuego/fuego/examples/custom-serializer -go 1.22.2 +go 1.23.3 require ( - github.com/go-fuego/fuego v0.16.1 + github.com/go-fuego/fuego v0.16.2 github.com/json-iterator/go v1.1.12 ) @@ -20,13 +20,13 @@ require ( github.com/invopop/yaml v0.3.1 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/leodido/go-urn v1.4.0 // indirect - github.com/mailru/easyjson v0.7.7 // indirect + github.com/mailru/easyjson v0.9.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect golang.org/x/crypto v0.31.0 // indirect - golang.org/x/net v0.32.0 // indirect + golang.org/x/net v0.33.0 // indirect golang.org/x/sys v0.28.0 // indirect golang.org/x/text v0.21.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/examples/custom-serializer/go.sum b/examples/custom-serializer/go.sum index cfa75374..6452bbb8 100644 --- a/examples/custom-serializer/go.sum +++ b/examples/custom-serializer/go.sum @@ -5,8 +5,8 @@ github.com/gabriel-vasile/mimetype v1.4.7 h1:SKFKl7kD0RiPdbht0s7hFtjl489WcQ1VyPW github.com/gabriel-vasile/mimetype v1.4.7/go.mod h1:GDlAgAyIRT27BhFl53XNAFtfjzOkLaF35JdEG0P7LtU= github.com/getkin/kin-openapi v0.128.0 h1:jqq3D9vC9pPq1dGcOCv7yOp1DaEe7c/T1vzcLbITSp4= github.com/getkin/kin-openapi v0.128.0/go.mod h1:OZrfXzUfGrNbsKj+xmFBx6E5c6yH3At/tAKSc2UszXM= -github.com/go-fuego/fuego v0.16.1 h1:G+sDF55BjFI7FH7dd07HDx4jfNPxXEeab+YKuLjj5zY= -github.com/go-fuego/fuego v0.16.1/go.mod h1:ARPlRxY+RgbahF6ZvnjsESGQd3h/jCw8ksCJxKLbgjY= +github.com/go-fuego/fuego v0.16.2 h1:xEMJBbGEo/8324NTHbT4peLiM1g2dpYAiG08z/d0+dU= +github.com/go-fuego/fuego v0.16.2/go.mod h1:V4DCdygAVcKYKUyeizhb1J83azstmaCJWDSJNMzeTDE= github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= @@ -38,8 +38,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= +github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -63,8 +63,8 @@ github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0 github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= -golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= -golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs= +golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= +golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= diff --git a/examples/full-app-gourmet/go.mod b/examples/full-app-gourmet/go.mod index 2bf4e00d..c5bee815 100644 --- a/examples/full-app-gourmet/go.mod +++ b/examples/full-app-gourmet/go.mod @@ -1,25 +1,23 @@ module github.com/go-fuego/fuego/examples/full-app-gourmet -go 1.22.6 - -toolchain go1.23.3 +go 1.23.3 require ( github.com/a-h/templ v0.2.793 - github.com/go-chi/chi/v5 v5.1.0 - github.com/go-fuego/fuego v0.16.1 - github.com/go-fuego/fuego/extra/markdown v0.0.0-20241213083019-8a613313c19f + github.com/go-chi/chi/v5 v5.2.0 + github.com/go-fuego/fuego v0.16.2 + github.com/go-fuego/fuego/extra/markdown v0.0.0-20241222081101-b4be136426a3 github.com/go-fuego/fuego/middleware/basicauth v0.15.1 - github.com/go-fuego/fuego/middleware/cache v0.0.0-20241213083019-8a613313c19f + github.com/go-fuego/fuego/middleware/cache v0.0.0-20241222081101-b4be136426a3 github.com/golang-jwt/jwt/v5 v5.2.1 github.com/golang-migrate/migrate/v4 v4.18.1 github.com/google/uuid v1.6.0 github.com/joho/godotenv v1.5.1 - github.com/lmittmann/tint v1.0.5 + github.com/lmittmann/tint v1.0.6 github.com/rs/cors v1.11.1 github.com/stretchr/testify v1.10.0 golang.org/x/text v0.21.0 - modernc.org/sqlite v1.34.2 + modernc.org/sqlite v1.34.3 ) require ( @@ -40,7 +38,7 @@ require ( github.com/invopop/yaml v0.3.1 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/leodido/go-urn v1.4.0 // indirect - github.com/mailru/easyjson v0.7.7 // indirect + github.com/mailru/easyjson v0.9.0 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/ncruces/go-strftime v0.1.9 // indirect @@ -49,11 +47,11 @@ require ( github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect go.uber.org/atomic v1.11.0 // indirect golang.org/x/crypto v0.31.0 // indirect - golang.org/x/exp v0.0.0-20241210194714-1829a127f884 // indirect - golang.org/x/net v0.32.0 // indirect + golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67 // indirect + golang.org/x/net v0.33.0 // indirect golang.org/x/sys v0.28.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - modernc.org/gc/v3 v3.0.0-20241004144649-1aea3fae8852 // indirect + modernc.org/gc/v3 v3.0.0-20241213165251-3bc300f6d0c9 // indirect modernc.org/libc v1.61.4 // indirect modernc.org/mathutil v1.6.0 // indirect modernc.org/memory v1.8.0 // indirect diff --git a/examples/full-app-gourmet/go.sum b/examples/full-app-gourmet/go.sum index 0d7d36fc..2dfd406e 100644 --- a/examples/full-app-gourmet/go.sum +++ b/examples/full-app-gourmet/go.sum @@ -8,8 +8,8 @@ github.com/gabriel-vasile/mimetype v1.4.7 h1:SKFKl7kD0RiPdbht0s7hFtjl489WcQ1VyPW github.com/gabriel-vasile/mimetype v1.4.7/go.mod h1:GDlAgAyIRT27BhFl53XNAFtfjzOkLaF35JdEG0P7LtU= github.com/getkin/kin-openapi v0.128.0 h1:jqq3D9vC9pPq1dGcOCv7yOp1DaEe7c/T1vzcLbITSp4= github.com/getkin/kin-openapi v0.128.0/go.mod h1:OZrfXzUfGrNbsKj+xmFBx6E5c6yH3At/tAKSc2UszXM= -github.com/go-chi/chi/v5 v5.1.0 h1:acVI1TYaD+hhedDJ3r54HyA6sExp3HfXq7QWEEY/xMw= -github.com/go-chi/chi/v5 v5.1.0/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= +github.com/go-chi/chi/v5 v5.2.0 h1:Aj1EtB0qR2Rdo2dG4O94RIU35w2lvQSj6BRA4+qwFL0= +github.com/go-chi/chi/v5 v5.2.0/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= github.com/go-fuego/fuego/middleware/basicauth v0.15.1 h1:8VelgvZjvm0pg6X29qCFDPVzSqCFdv5ppRDy7hWAykc= github.com/go-fuego/fuego/middleware/basicauth v0.15.1/go.mod h1:W2UY/grQlayDI3bJ1TpWhekeQXgSqIT1V3cu0pbvUYM= github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= @@ -61,10 +61,10 @@ github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/lmittmann/tint v1.0.5 h1:NQclAutOfYsqs2F1Lenue6OoWCajs5wJcP3DfWVpePw= -github.com/lmittmann/tint v1.0.5/go.mod h1:HIS3gSy7qNwGCj+5oRjAutErFBl4BzdQP6cJZ0NfMwE= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/lmittmann/tint v1.0.6 h1:vkkuDAZXc0EFGNzYjWcV0h7eEX+uujH48f/ifSkJWgc= +github.com/lmittmann/tint v1.0.6/go.mod h1:HIS3gSy7qNwGCj+5oRjAutErFBl4BzdQP6cJZ0NfMwE= +github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= +github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= @@ -91,12 +91,12 @@ go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= -golang.org/x/exp v0.0.0-20241210194714-1829a127f884 h1:Y/Mj/94zIQQGHVSv1tTtQBDaQaJe62U9bkDZKKyhPCU= -golang.org/x/exp v0.0.0-20241210194714-1829a127f884/go.mod h1:qj5a5QZpwLU2NLQudwIN5koi3beDhSAlJwa67PuM98c= +golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67 h1:1UoZQm6f0P/ZO0w1Ri+f+ifG/gXhegadRdwBIXEFWDo= +golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67/go.mod h1:qj5a5QZpwLU2NLQudwIN5koi3beDhSAlJwa67PuM98c= golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4= golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= -golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= -golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs= +golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= +golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -119,8 +119,8 @@ modernc.org/fileutil v1.3.0 h1:gQ5SIzK3H9kdfai/5x41oQiKValumqNTDXMvKo62HvE= modernc.org/fileutil v1.3.0/go.mod h1:XatxS8fZi3pS8/hKG2GH/ArUogfxjpEKs3Ku3aK4JyQ= modernc.org/gc/v2 v2.5.0 h1:bJ9ChznK1L1mUtAQtxi0wi5AtAs5jQuw4PrPHO5pb6M= modernc.org/gc/v2 v2.5.0/go.mod h1:wzN5dK1AzVGoH6XOzc3YZ+ey/jPgYHLuVckd62P0GYU= -modernc.org/gc/v3 v3.0.0-20241004144649-1aea3fae8852 h1:IYXPPTTjjoSHvUClZIYexDiO7g+4x+XveKT4gCIAwiY= -modernc.org/gc/v3 v3.0.0-20241004144649-1aea3fae8852/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4= +modernc.org/gc/v3 v3.0.0-20241213165251-3bc300f6d0c9 h1:ovz6yUKX71igz2yvk4NpiCL5fvdjZAI+DhuDEGx1xyU= +modernc.org/gc/v3 v3.0.0-20241213165251-3bc300f6d0c9/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4= modernc.org/libc v1.61.4 h1:wVyqEx6tlltte9lPTjq0kDAdtdM9c4JH8rU6M1ZVawA= modernc.org/libc v1.61.4/go.mod h1:VfXVuM/Shh5XsMNrh3C6OkfL78G3loa4ZC/Ljv9k7xc= modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= @@ -131,8 +131,8 @@ modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4= modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= modernc.org/sortutil v1.2.0 h1:jQiD3PfS2REGJNzNCMMaLSp/wdMNieTbKX920Cqdgqc= modernc.org/sortutil v1.2.0/go.mod h1:TKU2s7kJMf1AE84OoiGppNHJwvB753OYfNl2WRb++Ss= -modernc.org/sqlite v1.34.2 h1:J9n76TPsfYYkFkZ9Uy1QphILYifiVEwwOT7yP5b++2Y= -modernc.org/sqlite v1.34.2/go.mod h1:dnR723UrTtjKpoHCAMN0Q/gZ9MT4r+iRvIBb9umWFkU= +modernc.org/sqlite v1.34.3 h1:494MIwJKBLd0tErBYkRar2HvEpy04Bl0ykPEm4XLhbo= +modernc.org/sqlite v1.34.3/go.mod h1:dnR723UrTtjKpoHCAMN0Q/gZ9MT4r+iRvIBb9umWFkU= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= diff --git a/examples/generate-opengraph-image/go.mod b/examples/generate-opengraph-image/go.mod index c572ad4e..06a78136 100644 --- a/examples/generate-opengraph-image/go.mod +++ b/examples/generate-opengraph-image/go.mod @@ -4,8 +4,8 @@ go 1.23.3 require ( github.com/getkin/kin-openapi v0.128.0 - github.com/go-fuego/fuego v0.16.1 - github.com/go-fuego/fuego/middleware/cache v0.0.0-20241213083019-8a613313c19f + github.com/go-fuego/fuego v0.16.2 + github.com/go-fuego/fuego/middleware/cache v0.0.0-20241222081101-b4be136426a3 github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 golang.org/x/image v0.23.0 ) @@ -23,11 +23,11 @@ require ( github.com/invopop/yaml v0.3.1 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/leodido/go-urn v1.4.0 // indirect - github.com/mailru/easyjson v0.7.7 // indirect + github.com/mailru/easyjson v0.9.0 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect golang.org/x/crypto v0.31.0 // indirect - golang.org/x/net v0.32.0 // indirect + golang.org/x/net v0.33.0 // indirect golang.org/x/sys v0.28.0 // indirect golang.org/x/text v0.21.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/examples/generate-opengraph-image/go.sum b/examples/generate-opengraph-image/go.sum index 60bffdc5..bf9498ff 100644 --- a/examples/generate-opengraph-image/go.sum +++ b/examples/generate-opengraph-image/go.sum @@ -4,10 +4,10 @@ github.com/gabriel-vasile/mimetype v1.4.7 h1:SKFKl7kD0RiPdbht0s7hFtjl489WcQ1VyPW github.com/gabriel-vasile/mimetype v1.4.7/go.mod h1:GDlAgAyIRT27BhFl53XNAFtfjzOkLaF35JdEG0P7LtU= github.com/getkin/kin-openapi v0.128.0 h1:jqq3D9vC9pPq1dGcOCv7yOp1DaEe7c/T1vzcLbITSp4= github.com/getkin/kin-openapi v0.128.0/go.mod h1:OZrfXzUfGrNbsKj+xmFBx6E5c6yH3At/tAKSc2UszXM= -github.com/go-fuego/fuego v0.16.1 h1:G+sDF55BjFI7FH7dd07HDx4jfNPxXEeab+YKuLjj5zY= -github.com/go-fuego/fuego v0.16.1/go.mod h1:ARPlRxY+RgbahF6ZvnjsESGQd3h/jCw8ksCJxKLbgjY= -github.com/go-fuego/fuego/middleware/cache v0.0.0-20241213083019-8a613313c19f h1:dMjv20u2/oP/SjGBmlx2GsKFGha0Zax80FRUztI+ZNg= -github.com/go-fuego/fuego/middleware/cache v0.0.0-20241213083019-8a613313c19f/go.mod h1:1X75DId7/U/PJ+qPOqQePEyxj8u3FV6MzJw7oc+INL8= +github.com/go-fuego/fuego v0.16.2 h1:xEMJBbGEo/8324NTHbT4peLiM1g2dpYAiG08z/d0+dU= +github.com/go-fuego/fuego v0.16.2/go.mod h1:V4DCdygAVcKYKUyeizhb1J83azstmaCJWDSJNMzeTDE= +github.com/go-fuego/fuego/middleware/cache v0.0.0-20241222081101-b4be136426a3 h1:ACGdWbOMmfv+/C6HR71GfFTGrrX3OKJ82ev6KTK29v8= +github.com/go-fuego/fuego/middleware/cache v0.0.0-20241222081101-b4be136426a3/go.mod h1:k9gcjH1qWV0slZqZRP9QHf2MNU1tyajAosGbdzoaCsc= github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= @@ -40,8 +40,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= +github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= @@ -60,8 +60,8 @@ golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/image v0.23.0 h1:HseQ7c2OpPKTPVzNjG5fwJsOTCiiwS4QdsYi5XU6H68= golang.org/x/image v0.23.0/go.mod h1:wJJBTdLfCCf3tiHa1fNxpZmUI4mmoZvwMCPP0ddoNKY= -golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= -golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs= +golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= +golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= diff --git a/examples/hello-world/go.mod b/examples/hello-world/go.mod index 68c7b73c..d88fb6f0 100644 --- a/examples/hello-world/go.mod +++ b/examples/hello-world/go.mod @@ -1,8 +1,8 @@ module github.com/go-fuego/fuego/examples/hello-world -go 1.22.2 +go 1.23.3 -require github.com/go-fuego/fuego v0.16.1 +require github.com/go-fuego/fuego v0.16.2 require ( github.com/gabriel-vasile/mimetype v1.4.7 // indirect @@ -17,11 +17,11 @@ require ( github.com/invopop/yaml v0.3.1 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/leodido/go-urn v1.4.0 // indirect - github.com/mailru/easyjson v0.7.7 // indirect + github.com/mailru/easyjson v0.9.0 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect golang.org/x/crypto v0.31.0 // indirect - golang.org/x/net v0.32.0 // indirect + golang.org/x/net v0.33.0 // indirect golang.org/x/sys v0.28.0 // indirect golang.org/x/text v0.21.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/examples/hello-world/go.sum b/examples/hello-world/go.sum index 07dcf4ad..02841358 100644 --- a/examples/hello-world/go.sum +++ b/examples/hello-world/go.sum @@ -4,8 +4,8 @@ github.com/gabriel-vasile/mimetype v1.4.7 h1:SKFKl7kD0RiPdbht0s7hFtjl489WcQ1VyPW github.com/gabriel-vasile/mimetype v1.4.7/go.mod h1:GDlAgAyIRT27BhFl53XNAFtfjzOkLaF35JdEG0P7LtU= github.com/getkin/kin-openapi v0.128.0 h1:jqq3D9vC9pPq1dGcOCv7yOp1DaEe7c/T1vzcLbITSp4= github.com/getkin/kin-openapi v0.128.0/go.mod h1:OZrfXzUfGrNbsKj+xmFBx6E5c6yH3At/tAKSc2UszXM= -github.com/go-fuego/fuego v0.16.1 h1:G+sDF55BjFI7FH7dd07HDx4jfNPxXEeab+YKuLjj5zY= -github.com/go-fuego/fuego v0.16.1/go.mod h1:ARPlRxY+RgbahF6ZvnjsESGQd3h/jCw8ksCJxKLbgjY= +github.com/go-fuego/fuego v0.16.2 h1:xEMJBbGEo/8324NTHbT4peLiM1g2dpYAiG08z/d0+dU= +github.com/go-fuego/fuego v0.16.2/go.mod h1:V4DCdygAVcKYKUyeizhb1J83azstmaCJWDSJNMzeTDE= github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= @@ -34,8 +34,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= +github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= @@ -52,8 +52,8 @@ github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0 github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= -golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= -golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs= +golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= +golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= diff --git a/examples/openapi/go.mod b/examples/openapi/go.mod index a981b0b3..819b7c8c 100644 --- a/examples/openapi/go.mod +++ b/examples/openapi/go.mod @@ -1,8 +1,8 @@ module github.com/go-fuego/fuego/examples/openapi -go 1.22.2 +go 1.23.3 -require github.com/go-fuego/fuego v0.16.1 +require github.com/go-fuego/fuego v0.16.2 require ( github.com/gabriel-vasile/mimetype v1.4.7 // indirect @@ -17,11 +17,11 @@ require ( github.com/invopop/yaml v0.3.1 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/leodido/go-urn v1.4.0 // indirect - github.com/mailru/easyjson v0.7.7 // indirect + github.com/mailru/easyjson v0.9.0 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect golang.org/x/crypto v0.31.0 // indirect - golang.org/x/net v0.32.0 // indirect + golang.org/x/net v0.33.0 // indirect golang.org/x/sys v0.28.0 // indirect golang.org/x/text v0.21.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/examples/openapi/go.sum b/examples/openapi/go.sum index 07dcf4ad..02841358 100644 --- a/examples/openapi/go.sum +++ b/examples/openapi/go.sum @@ -4,8 +4,8 @@ github.com/gabriel-vasile/mimetype v1.4.7 h1:SKFKl7kD0RiPdbht0s7hFtjl489WcQ1VyPW github.com/gabriel-vasile/mimetype v1.4.7/go.mod h1:GDlAgAyIRT27BhFl53XNAFtfjzOkLaF35JdEG0P7LtU= github.com/getkin/kin-openapi v0.128.0 h1:jqq3D9vC9pPq1dGcOCv7yOp1DaEe7c/T1vzcLbITSp4= github.com/getkin/kin-openapi v0.128.0/go.mod h1:OZrfXzUfGrNbsKj+xmFBx6E5c6yH3At/tAKSc2UszXM= -github.com/go-fuego/fuego v0.16.1 h1:G+sDF55BjFI7FH7dd07HDx4jfNPxXEeab+YKuLjj5zY= -github.com/go-fuego/fuego v0.16.1/go.mod h1:ARPlRxY+RgbahF6ZvnjsESGQd3h/jCw8ksCJxKLbgjY= +github.com/go-fuego/fuego v0.16.2 h1:xEMJBbGEo/8324NTHbT4peLiM1g2dpYAiG08z/d0+dU= +github.com/go-fuego/fuego v0.16.2/go.mod h1:V4DCdygAVcKYKUyeizhb1J83azstmaCJWDSJNMzeTDE= github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= @@ -34,8 +34,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= +github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= @@ -52,8 +52,8 @@ github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0 github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= -golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= -golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs= +golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= +golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= diff --git a/extra/markdown/go.mod b/extra/markdown/go.mod index 48d17f83..35f49d61 100644 --- a/extra/markdown/go.mod +++ b/extra/markdown/go.mod @@ -1,6 +1,6 @@ module github.com/go-fuego/fuego/extra/markdown -go 1.22.5 +go 1.23.3 require ( github.com/gomarkdown/markdown v0.0.0-20241205020045-f7e15b2f3e62 diff --git a/go.mod b/go.mod index c7555029..67ebff84 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/go-fuego/fuego -go 1.22.2 +go 1.23.3 require ( github.com/getkin/kin-openapi v0.128.0 @@ -24,12 +24,12 @@ require ( github.com/invopop/yaml v0.3.1 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/leodido/go-urn v1.4.0 // indirect - github.com/mailru/easyjson v0.7.7 // indirect + github.com/mailru/easyjson v0.9.0 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect golang.org/x/crypto v0.31.0 // indirect - golang.org/x/net v0.32.0 // indirect + golang.org/x/net v0.33.0 // indirect golang.org/x/sys v0.28.0 // indirect golang.org/x/text v0.21.0 // indirect ) diff --git a/go.sum b/go.sum index ae553362..bdad8c54 100644 --- a/go.sum +++ b/go.sum @@ -34,8 +34,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= +github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= @@ -52,8 +52,8 @@ github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0 github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= -golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= -golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs= +golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= +golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= diff --git a/middleware/basicauth/go.mod b/middleware/basicauth/go.mod index b2cc896b..71b87878 100644 --- a/middleware/basicauth/go.mod +++ b/middleware/basicauth/go.mod @@ -1,9 +1,9 @@ module github.com/go-fuego/fuego/middleware/basicauth -go 1.22.6 +go 1.23.3 require ( - github.com/go-fuego/fuego v0.16.1 + github.com/go-fuego/fuego v0.16.2 github.com/stretchr/testify v1.10.0 ) @@ -21,12 +21,12 @@ require ( github.com/invopop/yaml v0.3.1 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/leodido/go-urn v1.4.0 // indirect - github.com/mailru/easyjson v0.7.7 // indirect + github.com/mailru/easyjson v0.9.0 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect golang.org/x/crypto v0.31.0 // indirect - golang.org/x/net v0.32.0 // indirect + golang.org/x/net v0.33.0 // indirect golang.org/x/sys v0.28.0 // indirect golang.org/x/text v0.21.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/middleware/basicauth/go.sum b/middleware/basicauth/go.sum index 07dcf4ad..02841358 100644 --- a/middleware/basicauth/go.sum +++ b/middleware/basicauth/go.sum @@ -4,8 +4,8 @@ github.com/gabriel-vasile/mimetype v1.4.7 h1:SKFKl7kD0RiPdbht0s7hFtjl489WcQ1VyPW github.com/gabriel-vasile/mimetype v1.4.7/go.mod h1:GDlAgAyIRT27BhFl53XNAFtfjzOkLaF35JdEG0P7LtU= github.com/getkin/kin-openapi v0.128.0 h1:jqq3D9vC9pPq1dGcOCv7yOp1DaEe7c/T1vzcLbITSp4= github.com/getkin/kin-openapi v0.128.0/go.mod h1:OZrfXzUfGrNbsKj+xmFBx6E5c6yH3At/tAKSc2UszXM= -github.com/go-fuego/fuego v0.16.1 h1:G+sDF55BjFI7FH7dd07HDx4jfNPxXEeab+YKuLjj5zY= -github.com/go-fuego/fuego v0.16.1/go.mod h1:ARPlRxY+RgbahF6ZvnjsESGQd3h/jCw8ksCJxKLbgjY= +github.com/go-fuego/fuego v0.16.2 h1:xEMJBbGEo/8324NTHbT4peLiM1g2dpYAiG08z/d0+dU= +github.com/go-fuego/fuego v0.16.2/go.mod h1:V4DCdygAVcKYKUyeizhb1J83azstmaCJWDSJNMzeTDE= github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= @@ -34,8 +34,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= +github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= @@ -52,8 +52,8 @@ github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0 github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= -golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= -golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs= +golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= +golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= diff --git a/middleware/cache/go.mod b/middleware/cache/go.mod index ccd63626..3ef1f95c 100644 --- a/middleware/cache/go.mod +++ b/middleware/cache/go.mod @@ -1,6 +1,6 @@ module github.com/go-fuego/fuego/middleware/cache -go 1.22.6 +go 1.23.3 require ( github.com/go-fuego/fuego v0.15.1 diff --git a/testing-from-outside/go.mod b/testing-from-outside/go.mod index 13696dfa..544323aa 100644 --- a/testing-from-outside/go.mod +++ b/testing-from-outside/go.mod @@ -1,6 +1,6 @@ module testing-from-outside -go 1.22.4 +go 1.23.3 require ( github.com/go-fuego/fuego v0.13.4 From c10561b857067adb88efc48a5fe176eeca3ef109 Mon Sep 17 00:00:00 2001 From: Ewen Quimerc'h <46993939+EwenQuim@users.noreply.github.com> Date: Sun, 22 Dec 2024 12:48:05 +0100 Subject: [PATCH 135/138] Generic main handler (#300) * Rely on Context to build main Fuego controller response * Makes main handler generic * Generic Fuego main handler * Hide Serialize and SerializeError from the public API --- ctx.go | 48 ++++++++++--- ctx_test.go | 43 ++++++------ internal/common_context.go | 3 + serve.go | 134 ++++++++++++++++++++----------------- serve_test.go | 8 +-- 5 files changed, 138 insertions(+), 98 deletions(-) diff --git a/ctx.go b/ctx.go index 6a8aefe3..53984bb2 100644 --- a/ctx.go +++ b/ctx.go @@ -26,6 +26,8 @@ type ContextNoBody = ContextWithBody[any] type ContextWithBody[B any] interface { context.Context + ValidableCtx + // Body returns the body of the request. // If (*B) implements [InTransformer], it will be transformed after deserialization. // It caches the result, so it can be called multiple times. @@ -102,19 +104,17 @@ type ContextWithBody[B any] interface { } // NewNetHTTPContext returns a new context. It is used internally by Fuego. You probably want to use Ctx[B] instead. -func NewNetHTTPContext[B any](w http.ResponseWriter, r *http.Request, options readOptions) ContextWithBody[B] { +func NewNetHTTPContext[B any](route BaseRoute, w http.ResponseWriter, r *http.Request, options readOptions) *netHttpContext[B] { c := &netHttpContext[B]{ CommonContext: internal.CommonContext[B]{ - CommonCtx: r.Context(), - UrlValues: r.URL.Query(), - OpenAPIParams: make(map[string]OpenAPIParam), - }, - Res: w, - Req: r, - readOptions: readOptions{ - DisallowUnknownFields: options.DisallowUnknownFields, - MaxBodySize: options.MaxBodySize, + CommonCtx: r.Context(), + UrlValues: r.URL.Query(), + OpenAPIParams: route.Params, + DefaultStatusCode: route.DefaultStatusCode, }, + Req: r, + Res: w, + readOptions: options, } return c @@ -134,7 +134,9 @@ type netHttpContext[Body any] struct { fs fs.FS templates *template.Template - readOptions readOptions + readOptions readOptions + serializer Sender + errorSerializer ErrorSender } var ( @@ -258,6 +260,30 @@ func (c *netHttpContext[B]) Body() (B, error) { return body, err } +// Serialize serializes the given data to the response. It uses the Content-Type header to determine the serialization format. +func (c netHttpContext[B]) Serialize(data any) error { + if c.serializer == nil { + return Send(c.Res, c.Req, data) + } + return c.serializer(c.Res, c.Req, data) +} + +// SerializeError serializes the given error to the response. It uses the Content-Type header to determine the serialization format. +func (c netHttpContext[B]) SerializeError(err error) { + if c.errorSerializer == nil { + SendError(c.Res, c.Req, err) + return + } + c.errorSerializer(c.Res, c.Req, err) +} + +// setDefaultStatusCode sets the default status code of the response. +func (c netHttpContext[B]) SetDefaultStatusCode() { + if c.DefaultStatusCode != 0 { + c.SetStatus(c.DefaultStatusCode) + } +} + func body[B any](c netHttpContext[B]) (B, error) { // Limit the size of the request body. if c.readOptions.MaxBodySize != 0 { diff --git a/ctx_test.go b/ctx_test.go index 575d3c8d..8d971e1b 100644 --- a/ctx_test.go +++ b/ctx_test.go @@ -46,7 +46,7 @@ func TestContext_QueryParam(t *testing.T) { r := httptest.NewRequest("GET", "http://example.com/foo/123?id=456&other=hello&boo=true&name=jhon&name=doe", nil) w := httptest.NewRecorder() - c := NewNetHTTPContext[any](w, r, readOptions{}) + c := NewNetHTTPContext[any](BaseRoute{}, w, r, readOptions{}) t.Run("string", func(t *testing.T) { param := c.QueryParam("other") @@ -124,7 +124,7 @@ func TestContext_QueryParams(t *testing.T) { r := httptest.NewRequest("GET", "http://example.com/foo/123?id=456&other=hello", nil) w := httptest.NewRecorder() - c := NewNetHTTPContext[any](w, r, readOptions{}) + c := NewNetHTTPContext[any](BaseRoute{}, w, r, readOptions{}) params := c.QueryParams() require.NotEmpty(t, params) @@ -168,7 +168,7 @@ func TestContext_Body(t *testing.T) { w := httptest.NewRecorder() r := httptest.NewRequest("GET", "http://example.com/foo", a) - c := NewNetHTTPContext[testStruct](w, r, readOptions{}) + c := NewNetHTTPContext[testStruct](BaseRoute{}, w, r, readOptions{}) body, err := c.Body() require.NoError(t, err) @@ -185,7 +185,7 @@ func TestContext_Body(t *testing.T) { r := httptest.NewRequest("GET", "http://example.com/foo", a) r.Header.Add("Content-Type", "application/json") - c := NewNetHTTPContext[testStruct](w, r, readOptions{}) + c := NewNetHTTPContext[testStruct](BaseRoute{}, w, r, readOptions{}) body, err := c.Body() require.NoError(t, err) @@ -199,7 +199,7 @@ func TestContext_Body(t *testing.T) { w := httptest.NewRecorder() r := httptest.NewRequest("GET", "http://example.com/foo", a) - c := NewNetHTTPContext[testStruct](w, r, readOptions{}) + c := NewNetHTTPContext[testStruct](BaseRoute{}, w, r, readOptions{}) body, err := c.Body() require.NoError(t, err) @@ -220,6 +220,7 @@ func TestContext_Body(t *testing.T) { reqBody := strings.NewReader(`{"name":"John","age":30}`) c := NewNetHTTPContext[testStruct]( + BaseRoute{}, httptest.NewRecorder(), httptest.NewRequest("GET", "http://example.com/foo", reqBody), readOptions{}) @@ -238,6 +239,7 @@ func TestContext_Body(t *testing.T) { reqBody := strings.NewReader(`{"name":"VeryLongName","age":12}`) c := NewNetHTTPContext[testStruct]( + BaseRoute{}, httptest.NewRecorder(), httptest.NewRequest("GET", "http://example.com/foo", reqBody), readOptions{}) @@ -251,6 +253,7 @@ func TestContext_Body(t *testing.T) { t.Run("can transform JSON body with custom method", func(t *testing.T) { reqBody := strings.NewReader(`{"name":"John","age":30}`) c := NewNetHTTPContext[testStructInTransformer]( + BaseRoute{}, httptest.NewRecorder(), httptest.NewRequest("GET", "http://example.com/foo", reqBody), readOptions{}) @@ -264,7 +267,7 @@ func TestContext_Body(t *testing.T) { t.Run("can transform JSON body with custom method returning error", func(t *testing.T) { reqBody := strings.NewReader(`{"name":"John","age":30}`) c := NewNetHTTPContext[testStructInTransformerWithError]( - httptest.NewRecorder(), + BaseRoute{}, httptest.NewRecorder(), httptest.NewRequest("GET", "http://example.com/foo", reqBody), readOptions{}) @@ -283,7 +286,7 @@ func TestContext_Body(t *testing.T) { r := httptest.NewRequest("GET", "http://example.com/foo", a) r.Header.Add("Content-Type", "application/octet-stream") - c := NewNetHTTPContext[[]byte](w, r, readOptions{}) + c := NewNetHTTPContext[[]byte](BaseRoute{}, w, r, readOptions{}) body, err := c.Body() require.NoError(t, err) require.Equal(t, []byte(`image`), body) @@ -298,7 +301,7 @@ func TestContext_Body(t *testing.T) { r := httptest.NewRequest("GET", "http://example.com/foo", a) r.Header.Add("Content-Type", "application/octet-stream") - c := NewNetHTTPContext[*struct{}](w, r, readOptions{}) + c := NewNetHTTPContext[*struct{}](BaseRoute{}, w, r, readOptions{}) body, err := c.Body() require.Error(t, err) require.ErrorContains(t, err, "use []byte as the body type") @@ -317,7 +320,7 @@ func TestContext_Body(t *testing.T) { r := httptest.NewRequest("GET", "http://example.com/foo", a) r.Header.Add("Content-Type", "application/xml") - c := NewNetHTTPContext[testStruct](w, r, readOptions{}) + c := NewNetHTTPContext[testStruct](BaseRoute{}, w, r, readOptions{}) body, err := c.Body() require.NoError(t, err) @@ -335,7 +338,7 @@ age: 30 r := httptest.NewRequest("GET", "http://example.com/foo", a) r.Header.Add("Content-Type", "application/x-yaml") - c := NewNetHTTPContext[testStruct](w, r, readOptions{}) + c := NewNetHTTPContext[testStruct](BaseRoute{}, w, r, readOptions{}) body, err := c.Body() require.NoError(t, err) @@ -346,7 +349,7 @@ age: 30 t.Run("unparsable because restricted to 1 byte", func(t *testing.T) { reqBody := strings.NewReader(`{"name":"John","age":30}`) c := NewNetHTTPContext[testStructInTransformerWithError]( - httptest.NewRecorder(), + BaseRoute{}, httptest.NewRecorder(), httptest.NewRequest("GET", "http://example.com/foo", reqBody), readOptions{ MaxBodySize: 1, @@ -367,7 +370,7 @@ age: 30 r := httptest.NewRequest("GET", "http://example.com/foo", a) r.Header.Set("Content-Type", "text/plain") - c := NewNetHTTPContext[string](w, r, readOptions{}) + c := NewNetHTTPContext[string](BaseRoute{}, w, r, readOptions{}) _, err := c.Body() require.NoError(t, err) @@ -386,7 +389,7 @@ func FuzzContext_Body(f *testing.F) { r := httptest.NewRequest("GET", "http://example.com/foo", a) r.Header.Set("Content-Type", "application/x-www-form-urlencoded") - c := NewNetHTTPContext[testStruct](w, r, readOptions{}) + c := NewNetHTTPContext[testStruct](BaseRoute{}, w, r, readOptions{}) _, err := c.Body() require.NoError(t, err) @@ -398,7 +401,7 @@ func BenchmarkContext_Body(b *testing.B) { for i := range b.N { reqBody := strings.NewReader(`{"name":"John","age":30}`) c := NewNetHTTPContext[testStruct]( - httptest.NewRecorder(), + BaseRoute{}, httptest.NewRecorder(), httptest.NewRequest("GET", "http://example.com/foo", reqBody), readOptions{}) _, err := c.Body() @@ -414,7 +417,7 @@ func BenchmarkContext_Body(b *testing.B) { b.Run("valid JSON body cache", func(b *testing.B) { reqBody := strings.NewReader(`{"name":"John","age":30}`) c := NewNetHTTPContext[testStruct]( - httptest.NewRecorder(), + BaseRoute{}, httptest.NewRecorder(), httptest.NewRequest("GET", "http://example.com/foo", reqBody), readOptions{}) for i := range b.N { @@ -429,7 +432,7 @@ func BenchmarkContext_Body(b *testing.B) { for range b.N { reqBody := strings.NewReader(`{"name":"John","age":30}`) c := NewNetHTTPContext[testStruct]( - httptest.NewRecorder(), + BaseRoute{}, httptest.NewRecorder(), httptest.NewRequest("GET", "http://example.com/foo", reqBody), readOptions{}) _, err := c.Body() @@ -443,7 +446,7 @@ func BenchmarkContext_Body(b *testing.B) { for range b.N { reqBody := strings.NewReader(`{"name":"John","age":30}`) c := NewNetHTTPContext[testStruct]( - httptest.NewRecorder(), + BaseRoute{}, httptest.NewRecorder(), httptest.NewRequest("GET", "http://example.com/foo", reqBody), readOptions{}) _, err := c.Body() @@ -463,7 +466,7 @@ func TestContext_MustBody(t *testing.T) { w := httptest.NewRecorder() r := httptest.NewRequest("GET", "http://example.com/foo", a) - c := NewNetHTTPContext[testStruct](w, r, readOptions{}) + c := NewNetHTTPContext[testStruct](BaseRoute{}, w, r, readOptions{}) body := c.MustBody() require.Equal(t, "John", body.Name) @@ -478,7 +481,7 @@ func TestContext_MustBody(t *testing.T) { reqBody := strings.NewReader(`{"name":"VeryLongName","age":12}`) c := NewNetHTTPContext[testStruct]( - httptest.NewRecorder(), + BaseRoute{}, httptest.NewRecorder(), httptest.NewRequest("GET", "http://example.com/foo", reqBody), readOptions{}) @@ -492,7 +495,7 @@ func TestMainLang(t *testing.T) { r := httptest.NewRequest("GET", "/", nil) r.Header.Set("Accept-Language", "fr-CH, fr;q=0.9, en;q=0.8, de;q=0.7, *;q=0.5") - c := NewNetHTTPContext[any](httptest.NewRecorder(), r, readOptions{}) + c := NewNetHTTPContext[any](BaseRoute{}, httptest.NewRecorder(), r, readOptions{}) require.Equal(t, c.MainLang(), "fr") require.Equal(t, c.MainLocale(), "fr-CH") } diff --git a/internal/common_context.go b/internal/common_context.go index 78315e0e..982c9222 100644 --- a/internal/common_context.go +++ b/internal/common_context.go @@ -38,6 +38,9 @@ type CommonContext[B any] struct { UrlValues url.Values OpenAPIParams map[string]OpenAPIParam // list of expected query parameters (declared in the OpenAPI spec) + + // default status code for the response + DefaultStatusCode int } type ParamType string // Query, Header, Cookie diff --git a/serve.go b/serve.go index 516b92a4..d1dacdc5 100644 --- a/serve.go +++ b/serve.go @@ -6,8 +6,6 @@ import ( "net/http" "reflect" "time" - - "github.com/go-fuego/fuego/internal" ) // Run starts the server. @@ -68,77 +66,87 @@ func HTTPHandler[ReturnType, Body any](s *Server, controller func(c ContextWithB } return func(w http.ResponseWriter, r *http.Request) { - w.Header().Set("X-Powered-By", "Fuego") - w.Header().Set("Trailer", "Server-Timing") - - // CONTEXT INITIALIZATION - timeCtxInit := time.Now() var templates *template.Template if s.template != nil { templates = template.Must(s.template.Clone()) } - ctx := &netHttpContext[Body]{ - CommonContext: internal.CommonContext[Body]{ - CommonCtx: r.Context(), - UrlValues: r.URL.Query(), - OpenAPIParams: route.Params, - }, - Req: r, - Res: w, - readOptions: readOptions{ - DisallowUnknownFields: s.DisallowUnknownFields, - MaxBodySize: s.maxBodySize, - }, - fs: s.fs, - templates: templates, - } + // CONTEXT INITIALIZATION + ctx := NewNetHTTPContext[Body](*route, w, r, readOptions{ + DisallowUnknownFields: s.DisallowUnknownFields, + MaxBodySize: s.maxBodySize, + }) + ctx.serializer = s.Serialize + ctx.errorSerializer = s.SerializeError + ctx.fs = s.fs + ctx.templates = templates + + Flow(s.Engine, ctx, controller) + } +} - // PARAMS VALIDATION - err := ValidateParams(ctx) - if err != nil { - err = s.ErrorHandler(err) - s.SerializeError(w, r, err) - return - } +// Contains the logic for the flow of a Fuego controller. +// Extends ContextWithBody with methods not exposed in the Controllers. +type ContextFlowable[B any] interface { + ContextWithBody[B] + + // SetDefaultStatusCode sets the status code of the response defined in the options. + SetDefaultStatusCode() + // Serialize serializes the given data to the response. + Serialize(data any) error + // SerializeError serializes the given error to the response. + SerializeError(err error) +} - timeController := time.Now() - w.Header().Set("Server-Timing", Timing{"fuegoReqInit", timeController.Sub(timeCtxInit), ""}.String()) +// Generic handler for Fuego controllers. +func Flow[B, T any](s *Engine, ctx ContextFlowable[B], controller func(c ContextWithBody[B]) (T, error)) { + ctx.SetHeader("X-Powered-By", "Fuego") + ctx.SetHeader("Trailer", "Server-Timing") - // CONTROLLER - ans, err := controller(ctx) - if err != nil { - err = s.ErrorHandler(err) - s.SerializeError(w, r, err) - return - } - w.Header().Add("Server-Timing", Timing{"controller", time.Since(timeController), ""}.String()) + timeCtxInit := time.Now() - if route.DefaultStatusCode != 0 { - w.WriteHeader(route.DefaultStatusCode) - } + // PARAMS VALIDATION + err := ValidateParams(ctx) + if err != nil { + err = s.ErrorHandler(err) + ctx.SerializeError(err) + return + } - if reflect.TypeOf(ans) == nil { - return - } + timeController := time.Now() + ctx.SetHeader("Server-Timing", Timing{"fuegoReqInit", timeController.Sub(timeCtxInit), ""}.String()) - // TRANSFORM OUT - timeTransformOut := time.Now() - ans, err = transformOut(r.Context(), ans) - if err != nil { - err = s.ErrorHandler(err) - s.SerializeError(w, r, err) - return - } - timeAfterTransformOut := time.Now() - w.Header().Add("Server-Timing", Timing{"transformOut", timeAfterTransformOut.Sub(timeTransformOut), "transformOut"}.String()) - - // SERIALIZATION - err = s.Serialize(w, r, ans) - if err != nil { - err = s.ErrorHandler(err) - s.SerializeError(w, r, err) - } - w.Header().Add("Server-Timing", Timing{"serialize", time.Since(timeAfterTransformOut), ""}.String()) + // CONTROLLER + ans, err := controller(ctx) + if err != nil { + err = s.ErrorHandler(err) + ctx.SerializeError(err) + return + } + ctx.SetHeader("Server-Timing", Timing{"controller", time.Since(timeController), ""}.String()) + + ctx.SetDefaultStatusCode() + + if reflect.TypeOf(ans) == nil { + return + } + + // TRANSFORM OUT + timeTransformOut := time.Now() + ans, err = transformOut(ctx.Context(), ans) + if err != nil { + err = s.ErrorHandler(err) + ctx.SerializeError(err) + return + } + timeAfterTransformOut := time.Now() + ctx.SetHeader("Server-Timing", Timing{"transformOut", timeAfterTransformOut.Sub(timeTransformOut), "transformOut"}.String()) + + // SERIALIZATION + err = ctx.Serialize(ans) + if err != nil { + err = s.ErrorHandler(err) + ctx.SerializeError(err) } + ctx.SetHeader("Server-Timing", Timing{"serialize", time.Since(timeAfterTransformOut), ""}.String()) } diff --git a/serve_test.go b/serve_test.go index 603b5260..76686750 100644 --- a/serve_test.go +++ b/serve_test.go @@ -349,7 +349,7 @@ func TestIni(t *testing.T) { t.Run("can initialize ContextNoBody", func(t *testing.T) { req := httptest.NewRequest("GET", "/ctx/error-in-rendering", nil) w := httptest.NewRecorder() - ctx := NewNetHTTPContext[any](w, req, readOptions{}) + ctx := NewNetHTTPContext[any](BaseRoute{}, w, req, readOptions{}) require.NotNil(t, ctx) require.NotNil(t, ctx.Request()) @@ -359,7 +359,7 @@ func TestIni(t *testing.T) { t.Run("can initialize ContextNoBody", func(t *testing.T) { req := httptest.NewRequest("GET", "/ctx/error-in-rendering", nil) w := httptest.NewRecorder() - ctx := NewNetHTTPContext[any](w, req, readOptions{}) + ctx := NewNetHTTPContext[any](BaseRoute{}, w, req, readOptions{}) require.NotNil(t, ctx) require.NotNil(t, ctx.Request()) @@ -369,7 +369,7 @@ func TestIni(t *testing.T) { t.Run("can initialize ContextWithBody[string]", func(t *testing.T) { req := httptest.NewRequest("GET", "/ctx/error-in-rendering", nil) w := httptest.NewRecorder() - ctx := NewNetHTTPContext[any](w, req, readOptions{}) + ctx := NewNetHTTPContext[any](BaseRoute{}, w, req, readOptions{}) require.NotNil(t, ctx) require.NotNil(t, ctx.Request()) @@ -379,7 +379,7 @@ func TestIni(t *testing.T) { t.Run("can initialize ContextWithBody[struct]", func(t *testing.T) { req := httptest.NewRequest("GET", "/ctx/error-in-rendering", nil) w := httptest.NewRecorder() - ctx := NewNetHTTPContext[any](w, req, readOptions{}) + ctx := NewNetHTTPContext[any](BaseRoute{}, w, req, readOptions{}) require.NotNil(t, ctx) require.NotNil(t, ctx.Request()) From ab8f736f8575e252a327d901194a88b4bc807453 Mon Sep 17 00:00:00 2001 From: EwenQuim Date: Sun, 22 Dec 2024 13:06:59 +0100 Subject: [PATCH 136/138] Makes BaseRoute non-optional in HTTPHandler Non optional in code, shouldn't be optional in the signature, even for the tests --- mux.go | 2 +- security_test.go | 6 +++--- serve.go | 8 ++------ serve_test.go | 22 +++++++++++----------- 4 files changed, 17 insertions(+), 21 deletions(-) diff --git a/mux.go b/mux.go index ed8fee16..e5dfa929 100644 --- a/mux.go +++ b/mux.go @@ -148,7 +148,7 @@ func registerFuegoController[T, B any](s *Server, method, path string, controlle acceptHeaderParameter.Schema = openapi3.NewStringSchema().NewRef() route.Operation.AddParameter(acceptHeaderParameter) - return Register(s, route, HTTPHandler(s, controller, &route.BaseRoute)) + return Register(s, route, HTTPHandler(s, controller, route.BaseRoute)) } func registerStdController(s *Server, method, path string, controller func(http.ResponseWriter, *http.Request), options ...func(*BaseRoute)) *Route[any, any] { diff --git a/security_test.go b/security_test.go index 7c8be676..02892348 100644 --- a/security_test.go +++ b/security_test.go @@ -416,7 +416,7 @@ func TestSecurity_LoginHandler(t *testing.T) { w := httptest.NewRecorder() s := NewServer() - truc := HTTPHandler(s, loginHandler, nil) + truc := HTTPHandler(s, loginHandler, BaseRoute{}) truc.ServeHTTP(w, r) cookies := w.Result().Cookies() @@ -429,7 +429,7 @@ func TestSecurity_LoginHandler(t *testing.T) { w := httptest.NewRecorder() s := NewServer() - truc := HTTPHandler(s, loginHandler, nil) + truc := HTTPHandler(s, loginHandler, BaseRoute{}) truc.ServeHTTP(w, r) cookies := w.Result().Cookies() @@ -442,7 +442,7 @@ func TestSecurity_LoginHandler(t *testing.T) { w := httptest.NewRecorder() s := NewServer() - truc := HTTPHandler(s, loginHandler, nil) + truc := HTTPHandler(s, loginHandler, BaseRoute{}) truc.ServeHTTP(w, r) cookies := w.Result().Cookies() diff --git a/serve.go b/serve.go index d1dacdc5..33e76e11 100644 --- a/serve.go +++ b/serve.go @@ -60,11 +60,7 @@ func (s *Server) url() string { // HTTPHandler converts a Fuego controller into a http.HandlerFunc. // Uses Server for configuration. // Uses Route for route configuration. Optional. -func HTTPHandler[ReturnType, Body any](s *Server, controller func(c ContextWithBody[Body]) (ReturnType, error), route *BaseRoute) http.HandlerFunc { - if route == nil { - route = &BaseRoute{} - } - +func HTTPHandler[ReturnType, Body any](s *Server, controller func(c ContextWithBody[Body]) (ReturnType, error), route BaseRoute) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { var templates *template.Template if s.template != nil { @@ -72,7 +68,7 @@ func HTTPHandler[ReturnType, Body any](s *Server, controller func(c ContextWithB } // CONTEXT INITIALIZATION - ctx := NewNetHTTPContext[Body](*route, w, r, readOptions{ + ctx := NewNetHTTPContext[Body](route, w, r, readOptions{ DisallowUnknownFields: s.DisallowUnknownFields, MaxBodySize: s.maxBodySize, }) diff --git a/serve_test.go b/serve_test.go index 76686750..a0a1aedf 100644 --- a/serve_test.go +++ b/serve_test.go @@ -83,14 +83,14 @@ func TestHttpHandler(t *testing.T) { s := NewServer() t.Run("can create std http handler from fuego controller", func(t *testing.T) { - handler := HTTPHandler(s, testController, nil) + handler := HTTPHandler(s, testController, BaseRoute{}) if handler == nil { t.Error("handler is nil") } }) t.Run("can run http handler from fuego controller", func(t *testing.T) { - handler := HTTPHandler(s, testController, nil) + handler := HTTPHandler(s, testController, BaseRoute{}) req := httptest.NewRequest("GET", "/testing", nil) w := httptest.NewRecorder() @@ -101,7 +101,7 @@ func TestHttpHandler(t *testing.T) { }) t.Run("can handle errors in http handler from fuego controller", func(t *testing.T) { - handler := HTTPHandler(s, testControllerWithError, nil) + handler := HTTPHandler(s, testControllerWithError, BaseRoute{}) if handler == nil { t.Error("handler is nil") } @@ -115,7 +115,7 @@ func TestHttpHandler(t *testing.T) { }) t.Run("can outTransform before serializing a value", func(t *testing.T) { - handler := HTTPHandler(s, testControllerWithOutTransformer, nil) + handler := HTTPHandler(s, testControllerWithOutTransformer, BaseRoute{}) req := httptest.NewRequest("GET", "/testing", nil) w := httptest.NewRecorder() @@ -126,7 +126,7 @@ func TestHttpHandler(t *testing.T) { }) t.Run("can outTransform before serializing a pointer value", func(t *testing.T) { - handler := HTTPHandler(s, testControllerWithOutTransformerStar, nil) + handler := HTTPHandler(s, testControllerWithOutTransformerStar, BaseRoute{}) req := httptest.NewRequest("GET", "/testing", nil) w := httptest.NewRecorder() @@ -137,7 +137,7 @@ func TestHttpHandler(t *testing.T) { }) t.Run("can handle errors in outTransform", func(t *testing.T) { - handler := HTTPHandler(s, testControllerWithOutTransformerStarError, nil) + handler := HTTPHandler(s, testControllerWithOutTransformerStarError, BaseRoute{}) req := httptest.NewRequest("GET", "/testing", nil) w := httptest.NewRecorder() @@ -148,7 +148,7 @@ func TestHttpHandler(t *testing.T) { }) t.Run("can handle nil in outTransform", func(t *testing.T) { - handler := HTTPHandler(s, testControllerWithOutTransformerStarNil, nil) + handler := HTTPHandler(s, testControllerWithOutTransformerStarNil, BaseRoute{}) req := httptest.NewRequest("GET", "/testing", nil) w := httptest.NewRecorder() @@ -159,7 +159,7 @@ func TestHttpHandler(t *testing.T) { }) t.Run("returns correct content-type when returning string", func(t *testing.T) { - handler := HTTPHandler(s, testControllerReturningString, nil) + handler := HTTPHandler(s, testControllerReturningString, BaseRoute{}) req := httptest.NewRequest("GET", "/testing", nil) w := httptest.NewRecorder() @@ -169,7 +169,7 @@ func TestHttpHandler(t *testing.T) { }) t.Run("returns correct content-type when returning ptr to string", func(t *testing.T) { - handler := HTTPHandler(s, testControllerReturningPtrToString, nil) + handler := HTTPHandler(s, testControllerReturningPtrToString, BaseRoute{}) req := httptest.NewRequest("GET", "/testing", nil) req.Header.Set("Accept", "text/plain") @@ -187,7 +187,7 @@ func TestSetStatusBeforeSend(t *testing.T) { handler := HTTPHandler(s, func(c ContextNoBody) (ans, error) { c.Response().WriteHeader(201) return ans{Ans: "Hello World"}, nil - }, nil) + }, BaseRoute{}) req := httptest.NewRequest("GET", "/testing", nil) w := httptest.NewRecorder() @@ -203,7 +203,7 @@ func TestSetStatusBeforeSend(t *testing.T) { handler := HTTPHandler(s, func(c ContextNoBody) (ans, error) { c.SetStatus(202) return ans{Ans: "Hello World"}, nil - }, nil) + }, BaseRoute{}) req := httptest.NewRequest("GET", "/testing", nil) w := httptest.NewRecorder() From d556b3b579cd801b9765f75199c19cb64216f6c8 Mon Sep 17 00:00:00 2001 From: EwenQuim Date: Sun, 22 Dec 2024 13:09:27 +0100 Subject: [PATCH 137/138] Moves route.Hidden check to RegisterOpenAPIOperation --- mux.go | 4 ---- openapi.go | 4 ++++ 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/mux.go b/mux.go index e5dfa929..2cff9bf3 100644 --- a/mux.go +++ b/mux.go @@ -86,10 +86,6 @@ func Register[T, B any](s *Server, route Route[T, B], controller http.Handler, o route.Middlewares = append(s.middlewares, route.Middlewares...) s.Mux.Handle(fullPath, withMiddlewares(route.Handler, route.Middlewares...)) - if route.Hidden || route.Method == "" { - return &route - } - err := route.RegisterOpenAPIOperation(s.OpenAPI) if err != nil { slog.Warn("error documenting openapi operation", "error", err) diff --git a/openapi.go b/openapi.go index a30ce75a..8f3a0839 100644 --- a/openapi.go +++ b/openapi.go @@ -208,6 +208,10 @@ func validateSwaggerUrl(swaggerUrl string) bool { // RegisterOpenAPIOperation registers the route to the OpenAPI description. // Modifies the route's Operation. func (route *Route[ResponseBody, RequestBody]) RegisterOpenAPIOperation(openapi *OpenAPI) error { + if route.Hidden || route.Method == "" { + return nil + } + operation, err := RegisterOpenAPIOperation(openapi, *route) route.Operation = operation return err From a0f00d5cb1bcbc823c6810066884deee6f629228 Mon Sep 17 00:00:00 2001 From: EwenQuim Date: Sun, 22 Dec 2024 14:35:41 +0100 Subject: [PATCH 138/138] Removes confusing handler field in BaseRoute It was not used as real handler and was net/http specific --- mux.go | 4 ++-- route.go | 3 --- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/mux.go b/mux.go index 2cff9bf3..854d57ad 100644 --- a/mux.go +++ b/mux.go @@ -74,7 +74,7 @@ func Register[T, B any](s *Server, route Route[T, B], controller http.Handler, o for _, o := range options { o(&route.BaseRoute) } - route.Handler = controller + route.Path = s.basePath + route.Path fullPath := route.Path @@ -84,7 +84,7 @@ func Register[T, B any](s *Server, route Route[T, B], controller http.Handler, o slog.Debug("registering controller " + fullPath) route.Middlewares = append(s.middlewares, route.Middlewares...) - s.Mux.Handle(fullPath, withMiddlewares(route.Handler, route.Middlewares...)) + s.Mux.Handle(fullPath, withMiddlewares(controller, route.Middlewares...)) err := route.RegisterOpenAPIOperation(s.OpenAPI) if err != nil { diff --git a/route.go b/route.go index b891ccb8..e718f79b 100644 --- a/route.go +++ b/route.go @@ -49,9 +49,6 @@ type BaseRoute struct { // URL path. Will be prefixed by the base path of the server and the group path if any Path string - // handler executed for this route - Handler http.Handler - // namespace and name of the function to execute FullName string Params map[string]OpenAPIParam