From f5cb23b30c64c1574669d9f956b697ad99f9d33e Mon Sep 17 00:00:00 2001 From: thomas-senechal Date: Tue, 7 Jan 2025 11:24:34 +0100 Subject: [PATCH 01/57] Add plugin .gitignore to exclude build artifacts and log files --- plugin/.gitignore | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 plugin/.gitignore diff --git a/plugin/.gitignore b/plugin/.gitignore new file mode 100644 index 00000000..e9fa34e1 --- /dev/null +++ b/plugin/.gitignore @@ -0,0 +1,2 @@ +build/ +*.log \ No newline at end of file From b30f28aed471e36528fe7a62c1ff0e644a4c34c4 Mon Sep 17 00:00:00 2001 From: thomas-senechal Date: Tue, 7 Jan 2025 11:27:45 +0100 Subject: [PATCH 02/57] Add PluginAPI to int/api with plugin registration and station middleware Will later be used to also to put a plugin specific front end page --- server/go.mod | 1 + server/go.sum | 2 + server/int/api/plugin.go | 97 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 100 insertions(+) create mode 100644 server/int/api/plugin.go diff --git a/server/go.mod b/server/go.mod index 7818cbe0..ebc5e7ea 100644 --- a/server/go.mod +++ b/server/go.mod @@ -15,6 +15,7 @@ require ( github.com/hashicorp/golang-lru/v2 v2.0.7 github.com/jessevdk/go-flags v1.6.1 github.com/massalabs/station v0.6.5 + github.com/massalabs/station-massa-hello-world v0.0.11-0.20240503070604-6b14a27fcdff github.com/massalabs/station-massa-wallet v0.4.5 golang.org/x/net v0.38.0 gopkg.in/yaml.v2 v2.4.0 diff --git a/server/go.sum b/server/go.sum index ef283d03..cf0b8818 100644 --- a/server/go.sum +++ b/server/go.sum @@ -89,6 +89,8 @@ github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0 github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/massalabs/station v0.6.5 h1:lkWWYB0/dPsRHSoAqN0wh/mFx8+InsVGMfraXQFZ76U= github.com/massalabs/station v0.6.5/go.mod h1:i9d/zAqeDYxY0Od5LEfEkP6V2osUhA13GwA72ByM8bQ= +github.com/massalabs/station-massa-hello-world v0.0.11-0.20240503070604-6b14a27fcdff h1:SZoRmXdbolVjhbsxO/3KWX8429Q1VnaQdQy0h718CqE= +github.com/massalabs/station-massa-hello-world v0.0.11-0.20240503070604-6b14a27fcdff/go.mod h1:QbRHQvJFrm4mO+vPzr4Uiwa5REL/CgBlV4PDFdhewa0= github.com/massalabs/station-massa-wallet v0.4.5 h1:0rTHxGPlJ5cKjgB/yQclOBHbWiZO5rOwO0lT7ZjFuVQ= github.com/massalabs/station-massa-wallet v0.4.5/go.mod h1:Eu6Zlijs0uAuGM5CxEUOxFrcIlWtuZVAbiWPCUni9XY= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= diff --git a/server/int/api/plugin.go b/server/int/api/plugin.go new file mode 100644 index 00000000..76b1343d --- /dev/null +++ b/server/int/api/plugin.go @@ -0,0 +1,97 @@ +package api + +import ( + "log" + "net/http" + + "github.com/go-openapi/loads" + "github.com/massalabs/deweb-server/api/read/restapi" + "github.com/massalabs/deweb-server/api/read/restapi/operations" + "github.com/massalabs/deweb-server/int/api/config" + "github.com/massalabs/station-massa-hello-world/pkg/plugin" + "github.com/massalabs/station/pkg/logger" +) + +type PluginAPI struct { + conf *config.ServerConfig + apiServer *restapi.Server + dewebAPI *operations.DeWebAPI +} + +func NewPluginAPI(conf *config.ServerConfig) *PluginAPI { + swaggerSpec, err := loads.Analyzed(restapi.SwaggerJSON, "") + if err != nil { + log.Fatalln(err) + } + + dewebAPI := operations.NewDeWebAPI(swaggerSpec) + server := restapi.NewServer(dewebAPI) + + return &PluginAPI{ + conf: conf, + apiServer: server, + dewebAPI: dewebAPI, + } +} + +// Start starts the API server. +func (a *PluginAPI) Start() { + defer func() { + if err := a.apiServer.Shutdown(); err != nil { + log.Fatalln(err) + } + }() + + a.apiServer.Port = a.conf.APIPort + + a.configurePluginAPI() + + a.apiServer.ConfigureAPI() + + a.apiServer.SetHandler(StationMiddleware(SubdomainMiddleware(a.dewebAPI.Serve(nil), a.conf))) + + listener, err := a.apiServer.HTTPListener() + if err != nil { + logger.Fatalf("Failed to get HTTP listener: %v", err) + } + + if err := plugin.RegisterPlugin(listener); err != nil { + logger.Fatalf("Failed to register plugin: %v", err) + } + + if err := a.apiServer.Serve(); err != nil { + log.Fatalln(err) + } +} + +// ConfigureAPI sets up the API handlers and error handling. +func (a *PluginAPI) configurePluginAPI() { + a.dewebAPI.ServeError = func(w http.ResponseWriter, r *http.Request, err error) { + log.Printf("ServeError: %v", err) + w.WriteHeader(http.StatusInternalServerError) + } + + a.dewebAPI.GetResourceHandler = operations.GetResourceHandlerFunc(getResourceHandler) + a.dewebAPI.DefaultPageHandler = operations.DefaultPageHandlerFunc(defaultPageHandler) +} + +// StationMiddleware handles station website serving. +// It is used by the plugin to serve massastation plugin page if the request domain is `station.massa`. +func StationMiddleware(handler http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + logger.Debugf("StationMiddleware: Handling request for %s", r.Host) + + if r.Host != "station.massa" { + logger.Debug("StationMiddleware: Request is not for station.massa. Proceeding with the next handler.") + handler.ServeHTTP(w, r) + + return + } + + path := cleanPath(r.URL.Path) + + logger.Debugf("StationMiddleware: Serving station.massa plugin page") + + localHandler(w, homeZip, path) + }) +} From 8ab5e765f6d99bbc16cfa72a3e83c4dd62695539 Mon Sep 17 00:00:00 2001 From: thomas-senechal Date: Tue, 7 Jan 2025 11:28:30 +0100 Subject: [PATCH 03/57] Add initial plugin implementation --- plugin/go.mod | 57 ++++++++++ plugin/go.sum | 279 +++++++++++++++++++++++++++++++++++++++++++++++++ plugin/main.go | 58 ++++++++++ 3 files changed, 394 insertions(+) create mode 100644 plugin/go.mod create mode 100644 plugin/go.sum create mode 100644 plugin/main.go diff --git a/plugin/go.mod b/plugin/go.mod new file mode 100644 index 00000000..78ce4832 --- /dev/null +++ b/plugin/go.mod @@ -0,0 +1,57 @@ +module github.com/massalabs/deweb-plugin + +go 1.22 + +replace github.com/massalabs/deweb-server => ../server + +require ( + github.com/massalabs/deweb-server v0.0.0 + github.com/massalabs/station v0.6.4 +) + +require ( + github.com/PuerkitoBio/purell v1.1.1 // indirect + github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect + github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d // indirect + github.com/awnumar/memcall v0.1.2 // indirect + github.com/awnumar/memguard v0.22.3 // indirect + github.com/btcsuite/btcutil v1.0.2 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/docker/go-units v0.4.0 // indirect + github.com/go-openapi/analysis v0.21.2 // indirect + github.com/go-openapi/errors v0.20.2 // indirect + github.com/go-openapi/jsonpointer v0.19.5 // indirect + github.com/go-openapi/jsonreference v0.19.6 // indirect + github.com/go-openapi/loads v0.21.1 // indirect + github.com/go-openapi/runtime v0.25.0 // indirect + github.com/go-openapi/spec v0.20.4 // indirect + github.com/go-openapi/strfmt v0.21.3 // indirect + github.com/go-openapi/swag v0.22.3 // indirect + github.com/go-openapi/validate v0.22.0 // indirect + github.com/gofrs/flock v0.12.1 // indirect + github.com/jessevdk/go-flags v1.5.0 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/klauspost/cpuid/v2 v2.1.0 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/massalabs/station-massa-hello-world v0.0.11-0.20240503070604-6b14a27fcdff // indirect + github.com/massalabs/station-massa-wallet v0.4.3 // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/oklog/ulid v1.3.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/shopspring/decimal v1.3.1 // indirect + github.com/stretchr/testify v1.9.0 // indirect + github.com/ybbus/jsonrpc/v3 v3.1.4 // indirect + go.mongodb.org/mongo-driver v1.11.3 // indirect + go.uber.org/atomic v1.10.0 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.24.0 // indirect + golang.org/x/crypto v0.14.0 // indirect + golang.org/x/net v0.17.0 // indirect + golang.org/x/sys v0.22.0 // indirect + golang.org/x/text v0.13.0 // indirect + gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + howett.net/plist v1.0.0 // indirect + lukechampine.com/blake3 v1.1.7 // indirect +) diff --git a/plugin/go.sum b/plugin/go.sum new file mode 100644 index 00000000..1b6b290d --- /dev/null +++ b/plugin/go.sum @@ -0,0 +1,279 @@ +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= +github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= +github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d h1:Byv0BzEl3/e6D5CLfI0j/7hiIEtvGVFPCZ7Ei2oq8iQ= +github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= +github.com/awnumar/memcall v0.1.2 h1:7gOfDTL+BJ6nnbtAp9+HQzUFjtP1hEseRQq8eP055QY= +github.com/awnumar/memcall v0.1.2/go.mod h1:S911igBPR9CThzd/hYQQmTc9SWNu3ZHIlCGaWsWsoJo= +github.com/awnumar/memguard v0.22.3 h1:b4sgUXtbUjhrGELPbuC62wU+BsPQy+8lkWed9Z+pj0Y= +github.com/awnumar/memguard v0.22.3/go.mod h1:mmGunnffnLHlxE5rRgQc3j+uwPZ27eYb61ccr8Clz2Y= +github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= +github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= +github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= +github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/btcutil v1.0.2 h1:9iZ1Terx9fMIOtq1VrwdqfsATL9MC2l8ZrUY6YZ2uts= +github.com/btcsuite/btcutil v1.0.2/go.mod h1:j9HUFwoQRsZL3V4n+qG+CUnEGHOarIxfC3Le2Yhbcts= +github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= +github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= +github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= +github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +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/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= +github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/go-openapi/analysis v0.21.2 h1:hXFrOYFHUAMQdu6zwAiKKJHJQ8kqZs1ux/ru1P1wLJU= +github.com/go-openapi/analysis v0.21.2/go.mod h1:HZwRk4RRisyG8vx2Oe6aqeSQcoxRp47Xkp3+K6q+LdY= +github.com/go-openapi/errors v0.19.8/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= +github.com/go-openapi/errors v0.19.9/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= +github.com/go-openapi/errors v0.20.2 h1:dxy7PGTqEh94zj2E3h1cUmQQWiM1+aeCROfAr02EmK8= +github.com/go-openapi/errors v0.20.2/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= +github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= +github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonreference v0.19.6 h1:UBIxjkht+AWIgYzCDSv2GN+E/togfwXUJFRTWhl2Jjs= +github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns= +github.com/go-openapi/loads v0.21.1 h1:Wb3nVZpdEzDTcly8S4HMkey6fjARRzb7iEaySimlDW0= +github.com/go-openapi/loads v0.21.1/go.mod h1:/DtAMXXneXFjbQMGEtbamCZb+4x7eGwkvZCvBmwUG+g= +github.com/go-openapi/runtime v0.25.0 h1:7yQTCdRbWhX8vnIjdzU8S00tBYf7Sg71EBeorlPHvhc= +github.com/go-openapi/runtime v0.25.0/go.mod h1:Ux6fikcHXyyob6LNWxtE96hWwjBPYF0DXgVFuMTneOs= +github.com/go-openapi/spec v0.20.4 h1:O8hJrt0UMnhHcluhIdUgCLRWyM2x7QkBXRvOs7m+O1M= +github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I= +github.com/go-openapi/strfmt v0.21.0/go.mod h1:ZRQ409bWMj+SOgXofQAGTIo2Ebu72Gs+WaRADcS5iNg= +github.com/go-openapi/strfmt v0.21.1/go.mod h1:I/XVKeLc5+MM5oPNN7P6urMOpuLXEcNrCX/rPGuWb0k= +github.com/go-openapi/strfmt v0.21.3 h1:xwhj5X6CjXEZZHMWy1zKJxvW9AfHC9pkyUjLvHtKG7o= +github.com/go-openapi/strfmt v0.21.3/go.mod h1:k+RzNO0Da+k3FrrynSNN8F7n/peCmQQqbbXjtDfvmGg= +github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= +github.com/go-openapi/swag v0.21.1/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= +github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= +github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-openapi/validate v0.22.0 h1:b0QecH6VslW/TxtpKgzpO1SNG7GU2FsaqKdP1E2T50Y= +github.com/go-openapi/validate v0.22.0/go.mod h1:rjnrwK57VJ7A8xqfpAOEKRH8yQSGUriMu5/zuPSQ1hg= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0= +github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY= +github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg= +github.com/gobuffalo/envy v1.6.15/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= +github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= +github.com/gobuffalo/flect v0.1.0/go.mod h1:d2ehjJqGOH/Kjqcoz+F7jHTBbmDb38yXA598Hb50EGs= +github.com/gobuffalo/flect v0.1.1/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= +github.com/gobuffalo/flect v0.1.3/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= +github.com/gobuffalo/genny v0.0.0-20190329151137-27723ad26ef9/go.mod h1:rWs4Z12d1Zbf19rlsn0nurr75KqhYp52EAGGxTbBhNk= +github.com/gobuffalo/genny v0.0.0-20190403191548-3ca520ef0d9e/go.mod h1:80lIj3kVJWwOrXWWMRzzdhW3DsrdjILVil/SFKBzF28= +github.com/gobuffalo/genny v0.1.0/go.mod h1:XidbUqzak3lHdS//TPu2OgiFB+51Ur5f7CSnXZ/JDvo= +github.com/gobuffalo/genny v0.1.1/go.mod h1:5TExbEyY48pfunL4QSXxlDOmdsD44RRq4mVZ0Ex28Xk= +github.com/gobuffalo/gitgen v0.0.0-20190315122116-cc086187d211/go.mod h1:vEHJk/E9DmhejeLeNt7UVvlSGv3ziL+djtTr3yyzcOw= +github.com/gobuffalo/gogen v0.0.0-20190315121717-8f38393713f5/go.mod h1:V9QVDIxsgKNZs6L2IYiGR8datgMhB577vzTDqypH360= +github.com/gobuffalo/gogen v0.1.0/go.mod h1:8NTelM5qd8RZ15VjQTFkAW6qOMx5wBbW4dSCS3BY8gg= +github.com/gobuffalo/gogen v0.1.1/go.mod h1:y8iBtmHmGc4qa3urIyo1shvOD8JftTtfcKi+71xfDNE= +github.com/gobuffalo/logger v0.0.0-20190315122211-86e12af44bc2/go.mod h1:QdxcLw541hSGtBnhUc4gaNIXRjiDppFGaDqzbrBd3v8= +github.com/gobuffalo/mapi v1.0.1/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= +github.com/gobuffalo/mapi v1.0.2/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= +github.com/gobuffalo/packd v0.0.0-20190315124812-a385830c7fc0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= +github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= +github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ= +github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0= +github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw= +github.com/gofrs/flock v0.12.1 h1:MTLVXXHf8ekldpJk3AKicLij9MdwOWkZ+a/jHHZby9E= +github.com/gofrs/flock v0.12.1/go.mod h1:9zxTsyu5xtJ9DK+1tFZyibEV7y3uwDxPPfbxeeHCoD0= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jessevdk/go-flags v1.5.0 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LFvc= +github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= +github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= +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/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4= +github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= +github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.1.0 h1:eyi1Ad2aNJMW95zcSbmGg7Cg6cq3ADwLpMAP96d8rF0= +github.com/klauspost/cpuid/v2 v2.1.0/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +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/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= +github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= +github.com/massalabs/station v0.6.4 h1:qAIj13cCQxboBBGdQwtcdoHCPPafOFM/+kO2+t2H2xo= +github.com/massalabs/station v0.6.4/go.mod h1:i9d/zAqeDYxY0Od5LEfEkP6V2osUhA13GwA72ByM8bQ= +github.com/massalabs/station-massa-hello-world v0.0.11-0.20240503070604-6b14a27fcdff h1:SZoRmXdbolVjhbsxO/3KWX8429Q1VnaQdQy0h718CqE= +github.com/massalabs/station-massa-hello-world v0.0.11-0.20240503070604-6b14a27fcdff/go.mod h1:QbRHQvJFrm4mO+vPzr4Uiwa5REL/CgBlV4PDFdhewa0= +github.com/massalabs/station-massa-wallet v0.4.3 h1:ch1+YSSr7ar56GzoTLNp++dl5J0MCfD3x6bGeA1fs38= +github.com/massalabs/station-massa-wallet v0.4.3/go.mod h1:RJcPhvJUkcsA8NhHJEeZGmLSb+DqqhVY3ljiQ8vCe4c= +github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= +github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +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.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.8.1 h1:geMPLpDpQOgVyCg5z5GoRwLHepNdb71NXb67XFkP+Eg= +github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= +github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= +github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= +github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +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/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= +github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= +github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= +github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= +github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g= +github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= +github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8= +github.com/ybbus/jsonrpc/v3 v3.1.4 h1:pPmgfWXnqR2GdIlealyCzmV6LV3nxm3w9gwA1B3cP3Y= +github.com/ybbus/jsonrpc/v3 v3.1.4/go.mod h1:4HQTl0UzErqWGa6bSXhp8rIjifMAMa55E4D5wdhe768= +github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= +go.mongodb.org/mongo-driver v1.7.3/go.mod h1:NqaYOwnXWr5Pm7AOpO5QFxKJ503nbMse/R79oO62zWg= +go.mongodb.org/mongo-driver v1.7.5/go.mod h1:VXEWRZ6URJIkUq2SCAyapmhH0ZLRBP+FT4xhp5Zvxng= +go.mongodb.org/mongo-driver v1.10.0/go.mod h1:wsihk0Kdgv8Kqu1Anit4sfK+22vSFbUrAVEYRhCXrA8= +go.mongodb.org/mongo-driver v1.11.3 h1:Ql6K6qYHEzB6xvu4+AU0BoRoqf9vFPcc4o7MUIdPW8Y= +go.mongodb.org/mongo-driver v1.11.3/go.mod h1:PTSz5yu21bkT/wXpkS7WR5f0ddqw5quethTUn9WM+2g= +go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= +go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= +go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= +go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +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.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= +go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= +golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= +golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= +golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= +golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/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/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= +gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0/go.mod h1:WDnlLJ4WF5VGsH/HVa3CI79GS0ol3YnhVnKP89i0kNg= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +howett.net/plist v1.0.0 h1:7CrbWYbPPO/PyNy38b2EB/+gYbjCe2DXBxgtOOZbSQM= +howett.net/plist v1.0.0/go.mod h1:lqaXoTrLY4hg8tnEzNru53gicrbv7rrk+2xJA/7hw9g= +lukechampine.com/blake3 v1.1.7 h1:GgRMhmdsuK8+ii6UZFDL8Nb+VyMwadAgcJyfYHxG6n0= +lukechampine.com/blake3 v1.1.7/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= diff --git a/plugin/main.go b/plugin/main.go new file mode 100644 index 00000000..ee29d3db --- /dev/null +++ b/plugin/main.go @@ -0,0 +1,58 @@ +package main + +import ( + "fmt" + "log" + "os" + "path/filepath" + + "github.com/massalabs/deweb-server/int/api" + "github.com/massalabs/deweb-server/int/api/config" + pkgConfig "github.com/massalabs/deweb-server/pkg/config" + "github.com/massalabs/station/pkg/logger" +) + +const directoryName = "station-deweb-plugin" + +func main() { + pluginDir, err := PluginDir() + if err != nil { + log.Fatalf("failed to get plugin directory: %v", err) + } + + logPath := filepath.Join(pluginDir, "./deweb-plugin.log") + + err = logger.InitializeGlobal(logPath) + if err != nil { + log.Fatalf("failed to initialize logger: %v", err) + } + + conf := config.ServerConfig{ + APIPort: 0, + Domain: "localhost", + NetworkInfos: pkgConfig.NewNetworkConfig("https://buildnet.massa.net/api/v2"), + CacheDir: filepath.Join(pluginDir, "websiteCache"), + } + + api := api.NewPluginAPI(&conf) + api.Start() +} + +func PluginDir() (string, error) { + configDir, err := os.UserConfigDir() + if err != nil { + return "", fmt.Errorf("getting user config directory: %w", err) + } + + path := filepath.Join(configDir, directoryName) + + // create the directory if it doesn't exist + if _, err := os.Stat(path); os.IsNotExist(err) { + err = os.MkdirAll(path, os.ModePerm) + if err != nil { + return "", fmt.Errorf("creating account directory '%s': %w", path, err) + } + } + + return path, nil +} From a89ecce928aec2280d28057827ec3da18027f943 Mon Sep 17 00:00:00 2001 From: thomas-senechal Date: Tue, 7 Jan 2025 11:29:14 +0100 Subject: [PATCH 04/57] Add plugin manifest file and favicon --- plugin/favicon.png | Bin 0 -> 5032 bytes plugin/manifest.json | 9 +++++++++ 2 files changed, 9 insertions(+) create mode 100644 plugin/favicon.png create mode 100644 plugin/manifest.json diff --git a/plugin/favicon.png b/plugin/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..297aa0c6c30b9cf4a5e2b28526c9736747b6893a GIT binary patch literal 5032 zcmb_gXH*kix1K-md?6cNHpkxpodfP^9-BE1OGOHis1 z5dtW^DJ`KWf+AHE1ibNn>s{;K-}nC5>zwn<-gDN>?ERc)PrSLQ0gM^J3;+Pk$WZq> z0D#~$lZHZQ$O~N|0&QTz7~1*)01L-o0|D7NyfhHxcilh-s2M`8(H3C0%O;lrpgx)9 z$e95EI5drPFIxnGHs;N|INh?z+hw3d@i$ZkhPe7B8!?fO1I}5A;r6`EE}>12SAZc$ zsh4*@RV^gOF=M5OXPgsp%{|5a5ZW7Q&dXc38a^O5{$YM2 zqOEe_XLZG_ub)OTWbKK4-r}^Xkh)Hbl4vSw- znq)T!>yF6+&OAk*+>Y+ihUt={0t{t%KV#z%&7aFm7w1GGcxxl>RU}fL^6c?p&!5e@an#B;WGt?k zV?SCY+WPtgJ!g=URJFFGRKBjr(yfWztQSAI0;0vT%eMcF(b3V@ z6=#rt{Su>qZr3za{b_LQCYoZx$_hu%nT&|^O;(bbSPP6k?OfpF5B<`}_7BCrLet^v z_4`ScGHSXWa!NRS^1#NdW-MeRnndaz4PL2d3%b5C`K0N@IU_*~QFLUR4JC|@y4-c& zNd*jXaEGD%NNRnsT?ge_>5{a^fPbQdKsGxt2E7CItGlD zT01}>pL>#XEy*tviti|g8lOUFABKcdR9CZWcfH&u>#LXQ+R}h*X^^x`N zjt7;5goNeH9}5L)`*hTy(yIh-?h1_TYd zk6{jeMHh5H&1HV2M-Np*lf5ALg@J2R2M{j0=L%4O`Ja@fyp5ciYbNY^gO|6dT3M`_2CRc5;cVod~SXpSlrr^T&RYP zY2H@2nN9`XEN+VSXtkPP(g~`EpENavpxEKarVXyGuOcVgQ?Zk&yIab{8HdWQ4}>Dr`K|1@qNxV z^WcDI^y`KU8tg2JN~!4SvA)Lse(;zxF7CDd{wbtktQCAF{~=lw{>YQ7$Gf>D_!kte zBo2qbz?xQ8js_jj4K7rh)dD*mOu6*gkS$+J*R}DYFqB1 z%-Kj$*sM;o%Om9~tc?qM;A1BMoS|C4aV+tgNOs*h`|1;Y>`4>Beg#5iK zEX`{9pTOr47cBZA(e%m(yeh<3jZW$;P&ha)L5v>?pU~|DHL)Yh#xnE%Y|d-~zg^jPI+`hb9dmU~u;7Jt_yVHC~bulv77 z3v>HN@t%@86b?-NZv)3P$$Y$w5$1i59Hhkt_{MWivLk`2Q~w9s;J7oiv?TlVS*Ww% zE&abVrkh+@=~J{iyEbIkdhV9b=I^oTX~B8J*0R-bP_`ZhY)Zd4lv^q-{dx74Zt}jC z%d&6aev7g35wGTSZU>DZ`#v@bd`5|5VbNme?G%j7&NPhzApXvYS^$i_l@--}U@-lluW?G`*qV*sB}i)UjUO|0LR$((JA>G(mBR&LNsH7PsehSGn+bpw9-+g)oK}r>_VC7^Wr2?>o?QMgb z<1LR19@p-zuBUHJPEL=F?_MTy>rH1VsVQ8YZul}h@?!nx_iG@Li(rF9fA^gp9*Sxc zt|as1gno3GUqF+)<27cnTUyDk!>=8lKk%tcQCY8%yV}_{oMlfJ$(v=Sp`@lhyV9G) zan1bEqcBcO-fA3fEI``22Kl7zfmUXr$lbW2V6eesV!rRmQH<_yzV2>=Vv%@U9NcIu zd#75Y1aunD;gnc-g~MOb`uceNazqc6nmXwE{d;Ef*Uj;*krv4Z-_Np)NXx*l8sTwP zXYD-PoqpMj)o_ttQBHCg?$_z`IE(a;m?IF@wStrx3$oO)pL_9>11WbfmqAP#99GJ| z8q1ETN4>?)vm;@KVoLrIIEcPsXr!mRdl1kjf(kq}3^7UbMpPZcV1$vtk7HWnTU&U# z2{dM+aQ8xQFSmrzVNFd3_`W_)?QFCE3t48>0`BNyT#&vyLd&}LcI@jjbwj&O!`CKs zFcSrZg;K#|4T@`5WC^LME_4=Xj78z#h^Y?I7imJnaTnt zOTr%Y_phidy(mf2KR&Pvs8i?N!BRhzOzPW7HJ!|zob0=2y^%0o0g*&}e7bUQK^%gb zGqX&v6?&2gKh23aGcsaxi-$W!M3q?x>0!k$Bbe@TF*a%Len=YYTOu?{1CK}NVbm|vk9MeHOU!B&h4W4b3H9eb)Ns&NjLMN$ow zRHs7To#%C2_?qhhaW~n7eVF-?a%OjNGJVh9z%A|NxXKg~+RxnSDYU*m_B#8z(Iz+B zijhbR`ezSj%}vXt;^Ize3Td%{&Png=PI(H+cQbFcddnW32=FlTA?3;P0u|R;{sT#{gz6u&a$o$Jbgmhm$hG5ta#=x$IT%3y(04n<4jw=_ZvzR^tG^8GV~XY)uAy~WIfytLnI;}CvMJC74nz7#PJ zeR3yNHO`CB3TKNhRycYvK+u60_|(oikU##R4@UPa0-Gg${4#Jxe>&dBT`5v=tc2IE z1AUW1E58vigM`0Ne=9Q}T>i<~+eP+)oPh%^U)B5kmOWOONQ+Q(#=L?>Kj968OyixU zv^-8ZAOBoEut6ZF3W_+q7}4Ayt}VzJVjCW*6;4PwPmxe(7C`dIA-SIHy>)7i){yqc ze37u7?#_7eqAX3K<`uYLy$|A6}T0V#{m2G zUoo+LZtlYBP=ZNKCA_2cx}4VI6k3^qtyI{N&xq@o@HkhmZ_ekXu1IG;8U@(YjuV`TV9b@`mYN-CydE8lq{9_934UPiL1eJJZzx$|0fn7)Hu*<@k%4 z)-+4Jn9;GVGDVy$ z5tl4zK)>f;eKk;MIb29dNniicOvuI|nwxNfgoh5ww$s0d-{BT|fh=uT6|TKJ5r6(64Usbq$Twy8a3N~$}B1dTXj1+}e4kPQDrDE%v#{{P47 zMd}vD2eml0Z!U3WtuMR}Eyl9f);LvLL0^8CZ*6g%KO+QgWRkh`+ zS+oRgGlHlKw7P$*%7H9p@Q9XNcnd~zcS%&M47hIcNOK!ws?J?~+)EaEccjs11hUpC zS26CWpRn*#dXCPd9DNQw6u{EkEi#(l=e<|WfFBz{MV^2%7*j-Z8x>SuN=MnaUqq$j z$Sr=mdm30ycdhL=ag3)4!%C=yHhHE|-HFO`tPa>aU!K)l?SV{MAMF$ow~yL7pRx(0 z70}vBMH+jmssCgF)a_i|#gw|Z)-H(V=PkV2ZolJL#by{yj4#GR`bI`ht$kG&20X_r zbVB2zAo|}Tf1vGskA}j2#grJzvcZyRnrdwJchufqyS(;jPowtc{LPHDwNI>7^s=yo zuzx}?puF=G^MBE*X^Xlbt)XPz+PeRYtl~jy&BHI9tR5oz8k#9(Q3dLO=j2|eK6vQ6J?fQzd4HvGwH4@sf8FHdnvGtbR?GF*2dEAg zGUO|~1e#AWfUcXT{hY%Z! zD;H5OWuGyxZ2Dreiv8^uaQ*uRfcm-qS%z|!XXKq;mwx2EpZqO3GZm3^XKee71kkO@ Rv>$7Lk)Ek;jgC|Fe*rCbIN<;Q literal 0 HcmV?d00001 diff --git a/plugin/manifest.json b/plugin/manifest.json new file mode 100644 index 00000000..9817a092 --- /dev/null +++ b/plugin/manifest.json @@ -0,0 +1,9 @@ +{ + "author": "Massa Labs", + "name": "DeWeb Plugin", + "description": "DeWeb is your gateway to the decentralized web, enabling seamless access to websites stored on-chain from any device, anywhere in the world.", + "logo": "favicon.png", + "home": "", + "version": "0.0.1", + "apispec": "" +} \ No newline at end of file From 5de4a88d6896ab475e74bf5b4c4836d53d1bb265 Mon Sep 17 00:00:00 2001 From: thomas-senechal Date: Tue, 7 Jan 2025 11:29:26 +0100 Subject: [PATCH 05/57] Add Taskfile for plugin --- plugin/Taskfile.yml | 92 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 plugin/Taskfile.yml diff --git a/plugin/Taskfile.yml b/plugin/Taskfile.yml new file mode 100644 index 00000000..13df31e3 --- /dev/null +++ b/plugin/Taskfile.yml @@ -0,0 +1,92 @@ +version: "3" + +tasks: + install: + cmds: + - cmd: go install github.com/go-swagger/go-swagger/cmd/swagger@latest + + generate: + cmds: + - cmd: go generate ./... + - cmd: mv pages/*.zip int/api/resources/ + platforms: [linux, darwin] + # Workaround because no support for builtins commands on Windows https://github.com/go-task/task/issues/197 + - cmd: cmd /C 'for %f in (pages\*.zip) do move %f int\api\resources\' + platforms: [windows] + + run: + cmds: + - cmd: go run ./main.go + + build: + cmds: + - task: build:internal + vars: + APP_NAME: plugin + BIN_DIR: build + + build:internal: + build: + desc: Internal build task + internal: true + cmds: + - cmd: echo Building DeWeb {{.APP_NAME}} for {{.OS | default OS}}/{{.ARCH | default ARCH}} + silent: true + - cmd: 'echo Mode: {{if eq .PRODUCTION "true"}}Production{{else}}Development{{end}}' + silent: true + - cmd: 'echo Version: {{.VERSION | default "Development"}}' + silent: true + - cmd: go build {{.BUILD_FLAGS}} -o {{.BIN_DIR}}/deweb-{{.APP_NAME}}{{.BIN_EXT}} ./main.go + vars: + # We need this check for nil and empty string because a simple check for empty string doesn't work as expected + VERSION_FLAG: '{{if ne .VERSION nil}}{{if ne .VERSION ""}}-X github.com/massalabs/deweb-plugin/int/config.Version=v{{.VERSION}}{{end}}{{end}}' + BUILD_FLAGS: '{{if eq .PRODUCTION "true"}}-tags production {{end}}-ldflags="{{.VERSION_FLAG}}{{if eq .PRODUCTION "true"}} -w -s{{end}}"' + BIN_EXT: '{{if eq .OS "windows"}}.exe{{end}}' + env: + GOOS: "{{.OS | default OS}}" + GOARCH: "{{.ARCH | default ARCH}}" + PRODUCTION: '{{.PRODUCTION | default "false"}}' + VERSION: "{{.VERSION | default nil}}" + + clean: + cmds: + - cmd: rm -rf build + + install-plugin: + cmds: + - cmd: mkdir -p /usr/local/share/massastation/plugins/deweb-plugin + platforms: [linux, darwin] + - cmd: cp build/deweb-plugin /usr/local/share/massastation/plugins/deweb-plugin + platforms: [linux, darwin] + - cmd: cp favicon.png /usr/local/share/massastation/plugins/deweb-plugin + platforms: [linux, darwin] + - cmd: cp manifest.json /usr/local/share/massastation/plugins/deweb-plugin + platforms: [linux, darwin] + - cmd: mkdir -p "C:/Program Files (x86)/MassaStation/plugins/deweb-plugin" + platforms: [windows] + - cmd: cp build/deweb-plugin.exe "C:/Program Files (x86)/MassaStation/plugins/deweb-plugin" + platforms: [windows] + - cmd: cp favicon.png "C:/Program Files (x86)/MassaStation/plugins/deweb-plugin" + platforms: [windows] + - cmd: cp manifest.json "C:/Program Files (x86)/MassaStation/plugins/deweb-plugin" + platforms: [windows] + + test: + cmds: + - cmd: go test ./... + + install:tools: + cmds: + - cmd: go install mvdan.cc/gofumpt@latest + - cmd: go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest + + lint: + cmds: + - cmd: golangci-lint run + + fmt: + cmds: + - cmd: go mod tidy + - cmd: gofumpt -l -w . + - cmd: gci write . --skip-generated + - cmd: golangci-lint run --fix From ae264ebef4917e6eec64c4c26f66b481e043204a Mon Sep 17 00:00:00 2001 From: thomas-senechal Date: Tue, 7 Jan 2025 11:29:35 +0100 Subject: [PATCH 06/57] Add README.md for DeWeb Station Plugin with setup and installation instructions --- plugin/README.md | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 plugin/README.md diff --git a/plugin/README.md b/plugin/README.md new file mode 100644 index 00000000..36b8d297 --- /dev/null +++ b/plugin/README.md @@ -0,0 +1,39 @@ +# DeWeb Station Plugin + +The DeWeb Station Plugin is a plugin for the DeWeb Station that allows you to install and run the DeWeb Server really easily on your computer. + +## Developer guide + +### Prerequisites + +Ensure you have `task` installed. Follow the instructions [here](https://taskfile.dev/installation/). + +### Setup + +1. Install required tools: + + ```bash + task install + ``` + +2. Generate: + + ```bash + task generate + ``` + +3. Build the plugin binary: + + ```bash + task build + ``` + +4. The binary will be stored in the `./build` directory. + +### Install + +To install the plugin, you can use the following command: + +```bash +task install-plugin +``` From 4021258922fc1c878a0a7fff5a96b1c789749753 Mon Sep 17 00:00:00 2001 From: thomas-senechal Date: Wed, 12 Mar 2025 16:39:12 +0100 Subject: [PATCH 07/57] Add basic plugin frontend --- plugin/home/.env | 1 + plugin/home/.gitignore | 24 + plugin/home/README.md | 54 + plugin/home/build.mjs | 32 + plugin/home/eslint.config.js | 28 + plugin/home/gen.go | 4 + plugin/home/index.html | 13 + plugin/home/package-lock.json | 5065 ++++++++++++++++++++++++++++++++ plugin/home/package.json | 37 + plugin/home/postcss.config.js | 6 + plugin/home/src/App.tsx | 59 + plugin/home/src/index.css | 3 + plugin/home/src/main.tsx | 10 + plugin/home/src/vite-env.d.ts | 1 + plugin/home/tailwind.config.js | 7 + plugin/home/tsconfig.app.json | 26 + plugin/home/tsconfig.json | 7 + plugin/home/tsconfig.node.json | 24 + plugin/home/vite.config.ts | 13 + 19 files changed, 5414 insertions(+) create mode 100644 plugin/home/.env create mode 100644 plugin/home/.gitignore create mode 100644 plugin/home/README.md create mode 100644 plugin/home/build.mjs create mode 100644 plugin/home/eslint.config.js create mode 100644 plugin/home/gen.go create mode 100644 plugin/home/index.html create mode 100644 plugin/home/package-lock.json create mode 100644 plugin/home/package.json create mode 100644 plugin/home/postcss.config.js create mode 100644 plugin/home/src/App.tsx create mode 100644 plugin/home/src/index.css create mode 100644 plugin/home/src/main.tsx create mode 100644 plugin/home/src/vite-env.d.ts create mode 100644 plugin/home/tailwind.config.js create mode 100644 plugin/home/tsconfig.app.json create mode 100644 plugin/home/tsconfig.json create mode 100644 plugin/home/tsconfig.node.json create mode 100644 plugin/home/vite.config.ts diff --git a/plugin/home/.env b/plugin/home/.env new file mode 100644 index 00000000..d5999655 --- /dev/null +++ b/plugin/home/.env @@ -0,0 +1 @@ +BASE_URL=/plugin/massa-labs/deweb-plugin/ \ No newline at end of file diff --git a/plugin/home/.gitignore b/plugin/home/.gitignore new file mode 100644 index 00000000..a547bf36 --- /dev/null +++ b/plugin/home/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/plugin/home/README.md b/plugin/home/README.md new file mode 100644 index 00000000..40ede56e --- /dev/null +++ b/plugin/home/README.md @@ -0,0 +1,54 @@ +# React + TypeScript + Vite + +This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. + +Currently, two official plugins are available: + +- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh +- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh + +## Expanding the ESLint configuration + +If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules: + +```js +export default tseslint.config({ + extends: [ + // Remove ...tseslint.configs.recommended and replace with this + ...tseslint.configs.recommendedTypeChecked, + // Alternatively, use this for stricter rules + ...tseslint.configs.strictTypeChecked, + // Optionally, add this for stylistic rules + ...tseslint.configs.stylisticTypeChecked, + ], + languageOptions: { + // other options... + parserOptions: { + project: ['./tsconfig.node.json', './tsconfig.app.json'], + tsconfigRootDir: import.meta.dirname, + }, + }, +}) +``` + +You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules: + +```js +// eslint.config.js +import reactX from 'eslint-plugin-react-x' +import reactDom from 'eslint-plugin-react-dom' + +export default tseslint.config({ + plugins: { + // Add the react-x and react-dom plugins + 'react-x': reactX, + 'react-dom': reactDom, + }, + rules: { + // other rules... + // Enable its recommended typescript rules + ...reactX.configs['recommended-typescript'].rules, + ...reactDom.configs.recommended.rules, + }, +}) +``` diff --git a/plugin/home/build.mjs b/plugin/home/build.mjs new file mode 100644 index 00000000..97491700 --- /dev/null +++ b/plugin/home/build.mjs @@ -0,0 +1,32 @@ +import { execSync } from "child_process"; +import fs from "fs"; +import archiver from "archiver"; + +console.log(`Building home...`); +execSync(`npm run build`, { + stdio: "inherit", + env: { + ...process.env, + BASE_URL: "/plugin/massa-labs/deweb-plugin/", + }, +}); + +console.log(`Zipping home.zip...`); +const output = fs.createWriteStream(`./dist/home.zip`); +const archive = archiver('zip', { + zlib: { level: 9 } // Sets the compression level. +}); + +output.on('close', function () { + console.log(`home.zip has been created and contains ${archive.pointer()} total bytes`); +}); + +archive.on('error', function (err) { + throw err; +}); + +archive.pipe(output); + +archive.directory(`dist/`, false); + +archive.finalize(); diff --git a/plugin/home/eslint.config.js b/plugin/home/eslint.config.js new file mode 100644 index 00000000..092408a9 --- /dev/null +++ b/plugin/home/eslint.config.js @@ -0,0 +1,28 @@ +import js from '@eslint/js' +import globals from 'globals' +import reactHooks from 'eslint-plugin-react-hooks' +import reactRefresh from 'eslint-plugin-react-refresh' +import tseslint from 'typescript-eslint' + +export default tseslint.config( + { ignores: ['dist'] }, + { + extends: [js.configs.recommended, ...tseslint.configs.recommended], + files: ['**/*.{ts,tsx}'], + languageOptions: { + ecmaVersion: 2020, + globals: globals.browser, + }, + plugins: { + 'react-hooks': reactHooks, + 'react-refresh': reactRefresh, + }, + rules: { + ...reactHooks.configs.recommended.rules, + 'react-refresh/only-export-components': [ + 'warn', + { allowConstantExport: true }, + ], + }, + }, +) diff --git a/plugin/home/gen.go b/plugin/home/gen.go new file mode 100644 index 00000000..e30bf5e7 --- /dev/null +++ b/plugin/home/gen.go @@ -0,0 +1,4 @@ +package main + +//go:generate npm ci +//go:generate npm run build:plugin diff --git a/plugin/home/index.html b/plugin/home/index.html new file mode 100644 index 00000000..948a803a --- /dev/null +++ b/plugin/home/index.html @@ -0,0 +1,13 @@ + + + + + + + DeWeb Plugin + + +
+ + + diff --git a/plugin/home/package-lock.json b/plugin/home/package-lock.json new file mode 100644 index 00000000..3365820c --- /dev/null +++ b/plugin/home/package-lock.json @@ -0,0 +1,5065 @@ +{ + "name": "home", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "home", + "version": "0.0.0", + "dependencies": { + "deweb-pages": "file:../../server/pages/", + "react": "^19.0.0", + "react-dom": "^19.0.0", + "react-icons": "^5.5.0" + }, + "devDependencies": { + "@eslint/js": "^9.21.0", + "@types/node": "^22.13.10", + "@types/react": "^19.0.10", + "@types/react-dom": "^19.0.4", + "@vitejs/plugin-react": "^4.3.4", + "archiver": "^7.0.1", + "autoprefixer": "^10.4.21", + "eslint": "^9.21.0", + "eslint-plugin-react-hooks": "^5.1.0", + "eslint-plugin-react-refresh": "^0.4.19", + "globals": "^15.15.0", + "postcss": "^8.5.3", + "tailwindcss": "^3.4.17", + "typescript": "~5.7.2", + "typescript-eslint": "^8.24.1", + "vite": "^6.2.0" + } + }, + "../../server/pages": { + "version": "0.0.0", + "dependencies": { + "react": "^18.3.1", + "react-dom": "^18.3.1", + "react-icons": "^5.3.0", + "tw-colors": "^3.3.2" + }, + "devDependencies": { + "@eslint/js": "^9.8.0", + "@types/node": "^22.8.4", + "@types/react": "^18.3.3", + "@types/react-dom": "^18.3.0", + "@vitejs/plugin-react": "^4.3.1", + "archiver": "^7.0.1", + "autoprefixer": "^10.4.20", + "eslint": "^9.8.0", + "eslint-plugin-react-hooks": "^5.1.0-rc.0", + "eslint-plugin-react-refresh": "^0.4.9", + "globals": "^15.9.0", + "postcss": "^8.4.41", + "tailwindcss": "^3.4.10", + "typescript": "^5.5.3", + "typescript-eslint": "^8.0.0", + "vite": "^5.4.0", + "vite-plugin-image-optimizer": "^1.1.8", + "vite-plugin-singlefile": "^2.0.2", + "vite-plugin-svgr": "^4.2.0" + } + }, + "../server/pages": { + "extraneous": true + }, + "node_modules/@alloc/quick-lru": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.26.8", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.8.tgz", + "integrity": "sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.9.tgz", + "integrity": "sha512-lWBYIrF7qK5+GjY5Uy+/hEgp8OJWOD/rpy74GplYRhEauvbHDeFB8t5hPOZxCZ0Oxf4Cc36tK51/l3ymJysrKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.26.2", + "@babel/generator": "^7.26.9", + "@babel/helper-compilation-targets": "^7.26.5", + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helpers": "^7.26.9", + "@babel/parser": "^7.26.9", + "@babel/template": "^7.26.9", + "@babel/traverse": "^7.26.9", + "@babel/types": "^7.26.9", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.9.tgz", + "integrity": "sha512-kEWdzjOAUMW4hAyrzJ0ZaTOu9OmpyDIQicIh0zg0EEcEkYXZb2TjtBhnHi2ViX7PKwZqF4xwqfAm299/QMP3lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.26.9", + "@babel/types": "^7.26.9", + "@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-compilation-targets": { + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.26.5.tgz", + "integrity": "sha512-IXuyn5EkouFJscIDuFF5EsiSolseme1s0CZB+QxVugqJLYmKdxI1VfIBOst0SUu4rnk2Z7kqTwmoO1lp3HIfnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.26.5", + "@babel/helper-validator-option": "^7.25.9", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", + "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.26.5.tgz", + "integrity": "sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", + "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.9.tgz", + "integrity": "sha512-Mz/4+y8udxBKdmzt/UjPACs4G3j5SshJJEFFKxlCGPydG4JAHXxjWjAwjd09tf6oINvl1VfMJo+nB7H2YKQ0dA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.26.9", + "@babel/types": "^7.26.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.9.tgz", + "integrity": "sha512-81NWa1njQblgZbQHxWHpxxCzNsa3ZwvFqpUg7P+NNUU6f3UU2jBEg4OlF/J6rl8+PQGh1q6/zWScd001YwcA5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.26.9" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.25.9.tgz", + "integrity": "sha512-y8quW6p0WHkEhmErnfe58r7x0A70uKphQm8Sp8cV7tjNQwK56sNVK0M73LK3WuYmsuyrftut4xAkjjgU0twaMg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.25.9.tgz", + "integrity": "sha512-+iqjT8xmXhhYv4/uiYd8FNQsraMFZIfxVSqxxVSZP0WbbSAWvBXAul0m/zu+7Vv4O/3WtApy9pmaTMiumEZgfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.26.9.tgz", + "integrity": "sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.26.2", + "@babel/parser": "^7.26.9", + "@babel/types": "^7.26.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.9.tgz", + "integrity": "sha512-ZYW7L+pL8ahU5fXmNbPF+iZFHCv5scFak7MZ9bwaRPLUhHh7QQEMjZUg0HevihoqCM5iSYHN61EyCoZvqC+bxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.26.2", + "@babel/generator": "^7.26.9", + "@babel/parser": "^7.26.9", + "@babel/template": "^7.26.9", + "@babel/types": "^7.26.9", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/types": { + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.9.tgz", + "integrity": "sha512-Y3IR1cRnOxOCDvMmNiym7XpXQ93iGDDPHx+Zj+NM+rg0fBaShfQLkg+hKPaZCEvg5N/LeCo4+Rj/i3FuJsIQaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.1.tgz", + "integrity": "sha512-kfYGy8IdzTGy+z0vFGvExZtxkFlA4zAxgKEahG9KE1ScBjpQnFsNOX8KTU5ojNru5ed5CVoJYXFtoxaq5nFbjQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.1.tgz", + "integrity": "sha512-dp+MshLYux6j/JjdqVLnMglQlFu+MuVeNrmT5nk6q07wNhCdSnB7QZj+7G8VMUGh1q+vj2Bq8kRsuyA00I/k+Q==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.1.tgz", + "integrity": "sha512-50tM0zCJW5kGqgG7fQ7IHvQOcAn9TKiVRuQ/lN0xR+T2lzEFvAi1ZcS8DiksFcEpf1t/GYOeOfCAgDHFpkiSmA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.1.tgz", + "integrity": "sha512-GCj6WfUtNldqUzYkN/ITtlhwQqGWu9S45vUXs7EIYf+7rCiiqH9bCloatO9VhxsL0Pji+PF4Lz2XXCES+Q8hDw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.1.tgz", + "integrity": "sha512-5hEZKPf+nQjYoSr/elb62U19/l1mZDdqidGfmFutVUjjUZrOazAtwK+Kr+3y0C/oeJfLlxo9fXb1w7L+P7E4FQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.1.tgz", + "integrity": "sha512-hxVnwL2Dqs3fM1IWq8Iezh0cX7ZGdVhbTfnOy5uURtao5OIVCEyj9xIzemDi7sRvKsuSdtCAhMKarxqtlyVyfA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.1.tgz", + "integrity": "sha512-1MrCZs0fZa2g8E+FUo2ipw6jw5qqQiH+tERoS5fAfKnRx6NXH31tXBKI3VpmLijLH6yriMZsxJtaXUyFt/8Y4A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.1.tgz", + "integrity": "sha512-0IZWLiTyz7nm0xuIs0q1Y3QWJC52R8aSXxe40VUxm6BB1RNmkODtW6LHvWRrGiICulcX7ZvyH6h5fqdLu4gkww==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.1.tgz", + "integrity": "sha512-NdKOhS4u7JhDKw9G3cY6sWqFcnLITn6SqivVArbzIaf3cemShqfLGHYMx8Xlm/lBit3/5d7kXvriTUGa5YViuQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.1.tgz", + "integrity": "sha512-jaN3dHi0/DDPelk0nLcXRm1q7DNJpjXy7yWaWvbfkPvI+7XNSc/lDOnCLN7gzsyzgu6qSAmgSvP9oXAhP973uQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.1.tgz", + "integrity": "sha512-OJykPaF4v8JidKNGz8c/q1lBO44sQNUQtq1KktJXdBLn1hPod5rE/Hko5ugKKZd+D2+o1a9MFGUEIUwO2YfgkQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.1.tgz", + "integrity": "sha512-nGfornQj4dzcq5Vp835oM/o21UMlXzn79KobKlcs3Wz9smwiifknLy4xDCLUU0BWp7b/houtdrgUz7nOGnfIYg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.1.tgz", + "integrity": "sha512-1osBbPEFYwIE5IVB/0g2X6i1qInZa1aIoj1TdL4AaAb55xIIgbg8Doq6a5BzYWgr+tEcDzYH67XVnTmUzL+nXg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.1.tgz", + "integrity": "sha512-/6VBJOwUf3TdTvJZ82qF3tbLuWsscd7/1w+D9LH0W/SqUgM5/JJD0lrJ1fVIfZsqB6RFmLCe0Xz3fmZc3WtyVg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.1.tgz", + "integrity": "sha512-nSut/Mx5gnilhcq2yIMLMe3Wl4FK5wx/o0QuuCLMtmJn+WeWYoEGDN1ipcN72g1WHsnIbxGXd4i/MF0gTcuAjQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.1.tgz", + "integrity": "sha512-cEECeLlJNfT8kZHqLarDBQso9a27o2Zd2AQ8USAEoGtejOrCYHNtKP8XQhMDJMtthdF4GBmjR2au3x1udADQQQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.1.tgz", + "integrity": "sha512-xbfUhu/gnvSEg+EGovRc+kjBAkrvtk38RlerAzQxvMzlB4fXpCFCeUAYzJvrnhFtdeyVCDANSjJvOvGYoeKzFA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.1.tgz", + "integrity": "sha512-O96poM2XGhLtpTh+s4+nP7YCCAfb4tJNRVZHfIE7dgmax+yMP2WgMd2OecBuaATHKTHsLWHQeuaxMRnCsH8+5g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.1.tgz", + "integrity": "sha512-X53z6uXip6KFXBQ+Krbx25XHV/NCbzryM6ehOAeAil7X7oa4XIq+394PWGnwaSQ2WRA0KI6PUO6hTO5zeF5ijA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.1.tgz", + "integrity": "sha512-Na9T3szbXezdzM/Kfs3GcRQNjHzM6GzFBeU1/6IV/npKP5ORtp9zbQjvkDJ47s6BCgaAZnnnu/cY1x342+MvZg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.1.tgz", + "integrity": "sha512-T3H78X2h1tszfRSf+txbt5aOp/e7TAz3ptVKu9Oyir3IAOFPGV6O9c2naym5TOriy1l0nNf6a4X5UXRZSGX/dw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.1.tgz", + "integrity": "sha512-2H3RUvcmULO7dIE5EWJH8eubZAI4xw54H1ilJnRNZdeo8dTADEZ21w6J22XBkXqGJbe0+wnNJtw3UXRoLJnFEg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.1.tgz", + "integrity": "sha512-GE7XvrdOzrb+yVKB9KsRMq+7a2U/K5Cf/8grVFRAGJmfADr/e/ODQ134RK2/eeHqYV5eQRFxb1hY7Nr15fv1NQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.1.tgz", + "integrity": "sha512-uOxSJCIcavSiT6UnBhBzE8wy3n0hOkJsBOzy7HDAuTDE++1DJMRRVCPGisULScHL+a/ZwdXPpXD3IyFKjA7K8A==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.1.tgz", + "integrity": "sha512-Y1EQdcfwMSeQN/ujR5VayLOJ1BHaK+ssyk0AEzPjC+t1lITgsnccPqFjb6V+LsTp/9Iov4ysfjxLaGJ9RPtkVg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", + "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.2.tgz", + "integrity": "sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.6", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.1.0.tgz", + "integrity": "sha512-kLrdPDJE1ckPo94kmPPf9Hfd0DU0Jw6oKYrhe+pwSC0iTUInmTa+w6fw8sGgcfkFJGNdWOUeOaDM4quW4a7OkA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.12.0.tgz", + "integrity": "sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.0.tgz", + "integrity": "sha512-yaVPAiNAalnCZedKLdR21GOGILMLKPyqSLWaAjQFvYA2i/ciDi8ArYVr69Anohb6cH2Ukhqti4aFnYyPm8wdwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/js": { + "version": "9.22.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.22.0.tgz", + "integrity": "sha512-vLFajx9o8d1/oL2ZkpMYbkLv8nDB6yaIwFNt7nI4+I80U/z03SxmfOMsLbvWr3p7C+Wnoh//aOu2pQW8cS0HCQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", + "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.7.tgz", + "integrity": "sha512-JubJ5B2pJ4k4yGxaNLdbjrnk9d/iDz6/q8wOilpIowd6PJPgaxCuHBnBszq7Ce2TyMrywm5r4PnKm6V3iiZF+g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.12.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.6", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", + "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.3.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", + "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.2.tgz", + "integrity": "sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "@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/@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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "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==", + "dev": true, + "license": "MIT" + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.35.0.tgz", + "integrity": "sha512-uYQ2WfPaqz5QtVgMxfN6NpLD+no0MYHDBywl7itPYd3K5TjjSghNKmX8ic9S8NU8w81NVhJv/XojcHptRly7qQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.35.0.tgz", + "integrity": "sha512-FtKddj9XZudurLhdJnBl9fl6BwCJ3ky8riCXjEw3/UIbjmIY58ppWwPEvU3fNu+W7FUsAsB1CdH+7EQE6CXAPA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.35.0.tgz", + "integrity": "sha512-Uk+GjOJR6CY844/q6r5DR/6lkPFOw0hjfOIzVx22THJXMxktXG6CbejseJFznU8vHcEBLpiXKY3/6xc+cBm65Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.35.0.tgz", + "integrity": "sha512-3IrHjfAS6Vkp+5bISNQnPogRAW5GAV1n+bNCrDwXmfMHbPl5EhTmWtfmwlJxFRUCBZ+tZ/OxDyU08aF6NI/N5Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.35.0.tgz", + "integrity": "sha512-sxjoD/6F9cDLSELuLNnY0fOrM9WA0KrM0vWm57XhrIMf5FGiN8D0l7fn+bpUeBSU7dCgPV2oX4zHAsAXyHFGcQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.35.0.tgz", + "integrity": "sha512-2mpHCeRuD1u/2kruUiHSsnjWtHjqVbzhBkNVQ1aVD63CcexKVcQGwJ2g5VphOd84GvxfSvnnlEyBtQCE5hxVVw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.35.0.tgz", + "integrity": "sha512-mrA0v3QMy6ZSvEuLs0dMxcO2LnaCONs1Z73GUDBHWbY8tFFocM6yl7YyMu7rz4zS81NDSqhrUuolyZXGi8TEqg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.35.0.tgz", + "integrity": "sha512-DnYhhzcvTAKNexIql8pFajr0PiDGrIsBYPRvCKlA5ixSS3uwo/CWNZxB09jhIapEIg945KOzcYEAGGSmTSpk7A==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.35.0.tgz", + "integrity": "sha512-uagpnH2M2g2b5iLsCTZ35CL1FgyuzzJQ8L9VtlJ+FckBXroTwNOaD0z0/UF+k5K3aNQjbm8LIVpxykUOQt1m/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.35.0.tgz", + "integrity": "sha512-XQxVOCd6VJeHQA/7YcqyV0/88N6ysSVzRjJ9I9UA/xXpEsjvAgDTgH3wQYz5bmr7SPtVK2TsP2fQ2N9L4ukoUg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loongarch64-gnu": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.35.0.tgz", + "integrity": "sha512-5pMT5PzfgwcXEwOaSrqVsz/LvjDZt+vQ8RT/70yhPU06PTuq8WaHhfT1LW+cdD7mW6i/J5/XIkX/1tCAkh1W6g==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.35.0.tgz", + "integrity": "sha512-c+zkcvbhbXF98f4CtEIP1EBA/lCic5xB0lToneZYvMeKu5Kamq3O8gqrxiYYLzlZH6E3Aq+TSW86E4ay8iD8EA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.35.0.tgz", + "integrity": "sha512-s91fuAHdOwH/Tad2tzTtPX7UZyytHIRR6V4+2IGlV0Cej5rkG0R61SX4l4y9sh0JBibMiploZx3oHKPnQBKe4g==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.35.0.tgz", + "integrity": "sha512-hQRkPQPLYJZYGP+Hj4fR9dDBMIM7zrzJDWFEMPdTnTy95Ljnv0/4w/ixFw3pTBMEuuEuoqtBINYND4M7ujcuQw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.35.0.tgz", + "integrity": "sha512-Pim1T8rXOri+0HmV4CdKSGrqcBWX0d1HoPnQ0uw0bdp1aP5SdQVNBy8LjYncvnLgu3fnnCt17xjWGd4cqh8/hA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.35.0.tgz", + "integrity": "sha512-QysqXzYiDvQWfUiTm8XmJNO2zm9yC9P/2Gkrwg2dH9cxotQzunBHYr6jk4SujCTqnfGxduOmQcI7c2ryuW8XVg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.35.0.tgz", + "integrity": "sha512-OUOlGqPkVJCdJETKOCEf1mw848ZyJ5w50/rZ/3IBQVdLfR5jk/6Sr5m3iO2tdPgwo0x7VcncYuOvMhBWZq8ayg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.35.0.tgz", + "integrity": "sha512-2/lsgejMrtwQe44glq7AFFHLfJBPafpsTa6JvP2NGef/ifOa4KBoglVf7AKN7EV9o32evBPRqfg96fEHzWo5kw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.35.0.tgz", + "integrity": "sha512-PIQeY5XDkrOysbQblSW7v3l1MDZzkTEzAfTPkj5VAu3FW8fS4ynyLg2sINp0fp3SjZ8xkRYpLqoKcYqAkhU1dw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.8", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", + "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", + "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.20.7" + } + }, + "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==", + "dev": true, + "license": "MIT" + }, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "22.13.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.10.tgz", + "integrity": "sha512-I6LPUvlRH+O6VRUqYOcMudhaIdUVWfsjnZavnsraHvpBwaEyMN29ry+0UVJhImYL16xsscu0aske3yA+uPOWfw==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.20.0" + } + }, + "node_modules/@types/react": { + "version": "19.0.10", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.0.10.tgz", + "integrity": "sha512-JuRQ9KXLEjaUNjTWpzuR231Z2WpIwczOkBEIvbHNCzQefFIT0L8IqE6NV6ULLyC1SI/i234JnDoMkfg+RjQj2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "19.0.4", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.0.4.tgz", + "integrity": "sha512-4fSQ8vWFkg+TGhePfUzVmat3eC14TXYSsiiDSLI0dVLsrm9gZFABjPy/Qu6TKgl1tq1Bu1yDsuQgY3A3DOjCcg==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^19.0.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.26.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.26.0.tgz", + "integrity": "sha512-cLr1J6pe56zjKYajK6SSSre6nl1Gj6xDp1TY0trpgPzjVbgDwd09v2Ws37LABxzkicmUjhEeg/fAUjPJJB1v5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "8.26.0", + "@typescript-eslint/type-utils": "8.26.0", + "@typescript-eslint/utils": "8.26.0", + "@typescript-eslint/visitor-keys": "8.26.0", + "graphemer": "^1.4.0", + "ignore": "^5.3.1", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.0.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.26.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.26.0.tgz", + "integrity": "sha512-mNtXP9LTVBy14ZF3o7JG69gRPBK/2QWtQd0j0oH26HcY/foyJJau6pNUez7QrM5UHnSvwlQcJXKsk0I99B9pOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/scope-manager": "8.26.0", + "@typescript-eslint/types": "8.26.0", + "@typescript-eslint/typescript-estree": "8.26.0", + "@typescript-eslint/visitor-keys": "8.26.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.26.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.26.0.tgz", + "integrity": "sha512-E0ntLvsfPqnPwng8b8y4OGuzh/iIOm2z8U3S9zic2TeMLW61u5IH2Q1wu0oSTkfrSzwbDJIB/Lm8O3//8BWMPA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.26.0", + "@typescript-eslint/visitor-keys": "8.26.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.26.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.26.0.tgz", + "integrity": "sha512-ruk0RNChLKz3zKGn2LwXuVoeBcUMh+jaqzN461uMMdxy5H9epZqIBtYj7UiPXRuOpaALXGbmRuZQhmwHhaS04Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/typescript-estree": "8.26.0", + "@typescript-eslint/utils": "8.26.0", + "debug": "^4.3.4", + "ts-api-utils": "^2.0.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.26.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.26.0.tgz", + "integrity": "sha512-89B1eP3tnpr9A8L6PZlSjBvnJhWXtYfZhECqlBl1D9Lme9mHO6iWlsprBtVenQvY1HMhax1mWOjhtL3fh/u+pA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.26.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.26.0.tgz", + "integrity": "sha512-tiJ1Hvy/V/oMVRTbEOIeemA2XoylimlDQ03CgPPNaHYZbpsc78Hmngnt+WXZfJX1pjQ711V7g0H7cSJThGYfPQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.26.0", + "@typescript-eslint/visitor-keys": "8.26.0", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^2.0.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.26.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.26.0.tgz", + "integrity": "sha512-2L2tU3FVwhvU14LndnQCA2frYC8JnPDVKyQtWFPf8IYFMt/ykEN1bPolNhNbCVgOmdzTlWdusCTKA/9nKrf8Ig==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "8.26.0", + "@typescript-eslint/types": "8.26.0", + "@typescript-eslint/typescript-estree": "8.26.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.26.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.26.0.tgz", + "integrity": "sha512-2z8JQJWAzPdDd51dRQ/oqIJxe99/hoLIqmf8RMCAJQtYDc535W/Jt2+RTP4bP0aKeBG1F65yjIZuczOXCmbWwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.26.0", + "eslint-visitor-keys": "^4.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@vitejs/plugin-react": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.3.4.tgz", + "integrity": "sha512-SCCPBJtYLdE8PX/7ZQAs1QAZ8Jqwih+0VBLum1EGqmCCQal+MIUqLCzj3ZUy8ufbC0cAM4LRlSTm7IQJwWT4ug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.26.0", + "@babel/plugin-transform-react-jsx-self": "^7.25.9", + "@babel/plugin-transform-react-jsx-source": "^7.25.9", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.14.2" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0" + } + }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "dev": true, + "license": "MIT", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/acorn": { + "version": "8.14.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", + "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "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/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true, + "license": "MIT" + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/archiver": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-7.0.1.tgz", + "integrity": "sha512-ZcbTaIqJOfCc03QwD468Unz/5Ir8ATtvAHsK+FdXbDIbGfihqh9mrvdcYunQzqn4HrvWWaFyaxJhGZagaJJpPQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "archiver-utils": "^5.0.2", + "async": "^3.2.4", + "buffer-crc32": "^1.0.0", + "readable-stream": "^4.0.0", + "readdir-glob": "^1.1.2", + "tar-stream": "^3.0.0", + "zip-stream": "^6.0.1" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/archiver-utils": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-5.0.2.tgz", + "integrity": "sha512-wuLJMmIBQYCsGZgYLTy5FIB2pF6Lfb6cXMSF8Qywwk3t20zWnAi7zLcQFdKQmIB8wyZpY5ER38x08GbwtR2cLA==", + "dev": true, + "license": "MIT", + "dependencies": { + "glob": "^10.0.0", + "graceful-fs": "^4.2.0", + "is-stream": "^2.0.1", + "lazystream": "^1.0.0", + "lodash": "^4.17.15", + "normalize-path": "^3.0.0", + "readable-stream": "^4.0.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "dev": true, + "license": "MIT" + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/async": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", + "dev": true, + "license": "MIT" + }, + "node_modules/autoprefixer": { + "version": "10.4.21", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.21.tgz", + "integrity": "sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "browserslist": "^4.24.4", + "caniuse-lite": "^1.0.30001702", + "fraction.js": "^4.3.7", + "normalize-range": "^0.1.2", + "picocolors": "^1.1.1", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/b4a": { + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.7.tgz", + "integrity": "sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/bare-events": { + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.5.4.tgz", + "integrity": "sha512-+gFfDkR8pj4/TrWCGUGWmJIkBwuxPS5F+a5yWjOHQt2hHvNZd5YLzadjmDUtFmMM4y429bnKLa8bYBMHcYdnQA==", + "dev": true, + "license": "Apache-2.0", + "optional": true + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.24.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz", + "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "caniuse-lite": "^1.0.30001688", + "electron-to-chromium": "^1.5.73", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.1" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/buffer-crc32": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-1.0.0.tgz", + "integrity": "sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001703", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001703.tgz", + "integrity": "sha512-kRlAGTRWgPsOj7oARC9m1okJEXdL/8fekFVcxA8Hl7GH4r/sN4OJn/i6Flde373T50KS7Y37oFbMwlE8+F42kQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/compress-commons": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-6.0.2.tgz", + "integrity": "sha512-6FqVXeETqWPoGcfzrXb37E50NP0LXT8kAMu5ooZayhWWdgEY4lBEEcbQNXtkuKQsGduxiIcI4gOTsxTmuq/bSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "crc-32": "^1.2.0", + "crc32-stream": "^6.0.0", + "is-stream": "^2.0.1", + "normalize-path": "^3.0.0", + "readable-stream": "^4.0.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/crc-32": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", + "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "crc32": "bin/crc32.njs" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/crc32-stream": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-6.0.0.tgz", + "integrity": "sha512-piICUB6ei4IlTv1+653yq5+KoqfBYmj9bw6LqXoOneTMDXk5nM1qt12mFW1caG3LlJXEKW1Bp0WggEmIfQB34g==", + "dev": true, + "license": "MIT", + "dependencies": { + "crc-32": "^1.2.0", + "readable-stream": "^4.0.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "dev": true, + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/detect-libc": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", + "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/deweb-pages": { + "resolved": "../../server/pages", + "link": true + }, + "node_modules/didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", + "dev": true, + "license": "MIT" + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" + }, + "node_modules/electron-to-chromium": { + "version": "1.5.114", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.114.tgz", + "integrity": "sha512-DFptFef3iktoKlFQK/afbo274/XNWD00Am0xa7M8FZUepHlHT8PEuiNBoRfFHbH1okqN58AlhbJ4QTkcnXorjA==", + "dev": true, + "license": "ISC" + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/esbuild": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.1.tgz", + "integrity": "sha512-BGO5LtrGC7vxnqucAe/rmvKdJllfGaYWdyABvyMoXQlfYMb2bbRuReWR5tEGE//4LcNJj9XrkovTqNYRFZHAMQ==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.1", + "@esbuild/android-arm": "0.25.1", + "@esbuild/android-arm64": "0.25.1", + "@esbuild/android-x64": "0.25.1", + "@esbuild/darwin-arm64": "0.25.1", + "@esbuild/darwin-x64": "0.25.1", + "@esbuild/freebsd-arm64": "0.25.1", + "@esbuild/freebsd-x64": "0.25.1", + "@esbuild/linux-arm": "0.25.1", + "@esbuild/linux-arm64": "0.25.1", + "@esbuild/linux-ia32": "0.25.1", + "@esbuild/linux-loong64": "0.25.1", + "@esbuild/linux-mips64el": "0.25.1", + "@esbuild/linux-ppc64": "0.25.1", + "@esbuild/linux-riscv64": "0.25.1", + "@esbuild/linux-s390x": "0.25.1", + "@esbuild/linux-x64": "0.25.1", + "@esbuild/netbsd-arm64": "0.25.1", + "@esbuild/netbsd-x64": "0.25.1", + "@esbuild/openbsd-arm64": "0.25.1", + "@esbuild/openbsd-x64": "0.25.1", + "@esbuild/sunos-x64": "0.25.1", + "@esbuild/win32-arm64": "0.25.1", + "@esbuild/win32-ia32": "0.25.1", + "@esbuild/win32-x64": "0.25.1" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "9.22.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.22.0.tgz", + "integrity": "sha512-9V/QURhsRN40xuHXWjV64yvrzMjcz7ZyNoF2jJFmy9j/SLk0u1OLSZgXi28MrXjymnjEGSR80WCdab3RGMDveQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.19.2", + "@eslint/config-helpers": "^0.1.0", + "@eslint/core": "^0.12.0", + "@eslint/eslintrc": "^3.3.0", + "@eslint/js": "9.22.0", + "@eslint/plugin-kit": "^0.2.7", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.3.0", + "eslint-visitor-keys": "^4.2.0", + "espree": "^10.3.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.2.0.tgz", + "integrity": "sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" + } + }, + "node_modules/eslint-plugin-react-refresh": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.19.tgz", + "integrity": "sha512-eyy8pcr/YxSYjBoqIFSrlbn9i/xvxUFa8CjzAYo9cFjgGXqq1hyjihcpZvxRLalpaWmueWR81xn7vuKmAFijDQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "eslint": ">=8.40" + } + }, + "node_modules/eslint-scope": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.3.0.tgz", + "integrity": "sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", + "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.14.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-fifo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", + "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "dev": true, + "license": "ISC" + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/fraction.js": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/globals": { + "version": "15.15.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz", + "integrity": "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true, + "license": "MIT" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC" + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "dev": true, + "license": "MIT", + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jiti": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz", + "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "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==", + "dev": true, + "license": "MIT" + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "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==", + "dev": true, + "license": "MIT" + }, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/lazystream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", + "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "readable-stream": "^2.0.5" + }, + "engines": { + "node": ">= 0.6.3" + } + }, + "node_modules/lazystream/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==", + "dev": true, + "license": "MIT", + "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" + } + }, + "node_modules/lazystream/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==", + "dev": true, + "license": "MIT" + }, + "node_modules/lazystream/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lightningcss": { + "version": "1.29.2", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.29.2.tgz", + "integrity": "sha512-6b6gd/RUXKaw5keVdSEtqFVdzWnU5jMxTUjA2bVcMNPLwSQ08Sv/UodBVtETLCn7k4S1Ibxwh7k68IwLZPgKaA==", + "dev": true, + "license": "MPL-2.0", + "optional": true, + "peer": true, + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-darwin-arm64": "1.29.2", + "lightningcss-darwin-x64": "1.29.2", + "lightningcss-freebsd-x64": "1.29.2", + "lightningcss-linux-arm-gnueabihf": "1.29.2", + "lightningcss-linux-arm64-gnu": "1.29.2", + "lightningcss-linux-arm64-musl": "1.29.2", + "lightningcss-linux-x64-gnu": "1.29.2", + "lightningcss-linux-x64-musl": "1.29.2", + "lightningcss-win32-arm64-msvc": "1.29.2", + "lightningcss-win32-x64-msvc": "1.29.2" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.29.2", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.29.2.tgz", + "integrity": "sha512-cK/eMabSViKn/PG8U/a7aCorpeKLMlK0bQeNHmdb7qUnBkNPnL+oV5DjJUo0kqWsJUapZsM4jCfYItbqBDvlcA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "peer": true, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.29.2", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.29.2.tgz", + "integrity": "sha512-j5qYxamyQw4kDXX5hnnCKMf3mLlHvG44f24Qyi2965/Ycz829MYqjrVg2H8BidybHBp9kom4D7DR5VqCKDXS0w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "peer": true, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.29.2", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.29.2.tgz", + "integrity": "sha512-wDk7M2tM78Ii8ek9YjnY8MjV5f5JN2qNVO+/0BAGZRvXKtQrBC4/cn4ssQIpKIPP44YXw6gFdpUF+Ps+RGsCwg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "peer": true, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.29.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.29.2.tgz", + "integrity": "sha512-IRUrOrAF2Z+KExdExe3Rz7NSTuuJ2HvCGlMKoquK5pjvo2JY4Rybr+NrKnq0U0hZnx5AnGsuFHjGnNT14w26sg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.29.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.29.2.tgz", + "integrity": "sha512-KKCpOlmhdjvUTX/mBuaKemp0oeDIBBLFiU5Fnqxh1/DZ4JPZi4evEH7TKoSBFOSOV3J7iEmmBaw/8dpiUvRKlQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.29.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.29.2.tgz", + "integrity": "sha512-Q64eM1bPlOOUgxFmoPUefqzY1yV3ctFPE6d/Vt7WzLW4rKTv7MyYNky+FWxRpLkNASTnKQUaiMJ87zNODIrrKQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.29.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.29.2.tgz", + "integrity": "sha512-0v6idDCPG6epLXtBH/RPkHvYx74CVziHo6TMYga8O2EiQApnUPZsbR9nFNrg2cgBzk1AYqEd95TlrsL7nYABQg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.29.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.29.2.tgz", + "integrity": "sha512-rMpz2yawkgGT8RULc5S4WiZopVMOFWjiItBT7aSfDX4NQav6M44rhn5hjtkKzB+wMTRlLLqxkeYEtQ3dd9696w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.29.2", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.29.2.tgz", + "integrity": "sha512-nL7zRW6evGQqYVu/bKGK+zShyz8OVzsCotFgc7judbt6wnB2KbiKKJwBE4SGoDBQ1O94RjW4asrCjQL4i8Fhbw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "peer": true, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.29.2", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.29.2.tgz", + "integrity": "sha512-EdIUW3B2vLuHmv7urfzMI/h2fmlnOQBk1xlsDxkN1tCWKjNFjfLhGxYk8C8mzpSfr+A6jFFIi8fU6LbQGsRWjA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "peer": true, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, + "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==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.9", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.9.tgz", + "integrity": "sha512-SppoicMGpZvbF1l3z4x7No3OlIjP7QJvC9XR7AhZr1kL133KHnKPztkKDc+Ir4aJ/1VhTySrtKhrsycmrMQfvg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-releases": { + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", + "dev": true, + "license": "MIT" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pirates": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/postcss": { + "version": "8.5.3", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz", + "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==", + "dev": true, + "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" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.8", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-import": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", + "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-js": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", + "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", + "dev": true, + "license": "MIT", + "dependencies": { + "camelcase-css": "^2.0.1" + }, + "engines": { + "node": "^12 || ^14 || >= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.4.21" + } + }, + "node_modules/postcss-load-config": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz", + "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "lilconfig": "^3.0.0", + "yaml": "^2.3.4" + }, + "engines": { + "node": ">= 14" + }, + "peerDependencies": { + "postcss": ">=8.0.9", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/postcss-nested": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", + "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.1.1" + }, + "engines": { + "node": ">=12.0" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/postcss-selector-parser": { + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true, + "license": "MIT" + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/react": { + "version": "19.0.0", + "resolved": "https://registry.npmjs.org/react/-/react-19.0.0.tgz", + "integrity": "sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.0.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.0.0.tgz", + "integrity": "sha512-4GV5sHFG0e/0AD4X+ySy6UJd3jVl1iNsNHdpad0qhABJ11twS3TTBnseqsKurKcsNqCEFeGL3uLpVChpIO3QfQ==", + "license": "MIT", + "dependencies": { + "scheduler": "^0.25.0" + }, + "peerDependencies": { + "react": "^19.0.0" + } + }, + "node_modules/react-icons": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.5.0.tgz", + "integrity": "sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw==", + "license": "MIT", + "peerDependencies": { + "react": "*" + } + }, + "node_modules/react-refresh": { + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz", + "integrity": "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pify": "^2.3.0" + } + }, + "node_modules/readable-stream": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz", + "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==", + "dev": true, + "license": "MIT", + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/readdir-glob": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.3.tgz", + "integrity": "sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "minimatch": "^5.1.0" + } + }, + "node_modules/readdir-glob/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/readdir-glob/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rollup": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.35.0.tgz", + "integrity": "sha512-kg6oI4g+vc41vePJyO6dHt/yl0Rz3Thv0kJeVQ3D1kS3E5XSuKbPc29G4IpT/Kv1KQwgHVcN+HtyS+HYLNSvQg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.6" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.35.0", + "@rollup/rollup-android-arm64": "4.35.0", + "@rollup/rollup-darwin-arm64": "4.35.0", + "@rollup/rollup-darwin-x64": "4.35.0", + "@rollup/rollup-freebsd-arm64": "4.35.0", + "@rollup/rollup-freebsd-x64": "4.35.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.35.0", + "@rollup/rollup-linux-arm-musleabihf": "4.35.0", + "@rollup/rollup-linux-arm64-gnu": "4.35.0", + "@rollup/rollup-linux-arm64-musl": "4.35.0", + "@rollup/rollup-linux-loongarch64-gnu": "4.35.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.35.0", + "@rollup/rollup-linux-riscv64-gnu": "4.35.0", + "@rollup/rollup-linux-s390x-gnu": "4.35.0", + "@rollup/rollup-linux-x64-gnu": "4.35.0", + "@rollup/rollup-linux-x64-musl": "4.35.0", + "@rollup/rollup-win32-arm64-msvc": "4.35.0", + "@rollup/rollup-win32-ia32-msvc": "4.35.0", + "@rollup/rollup-win32-x64-msvc": "4.35.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/scheduler": { + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.25.0.tgz", + "integrity": "sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA==", + "license": "MIT" + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/source-map-js": { + "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==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/streamx": { + "version": "2.22.0", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.22.0.tgz", + "integrity": "sha512-sLh1evHOzBy/iWRiR6d1zRcLao4gGZr3C1kzNz4fopCOKJb6xD9ub8Mpi9Mr1R6id5o43S+d93fI48UC5uM9aw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-fifo": "^1.3.2", + "text-decoder": "^1.1.0" + }, + "optionalDependencies": { + "bare-events": "^2.2.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/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==", + "dev": true, + "license": "MIT" + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/sucrase": { + "version": "3.35.0", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", + "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "glob": "^10.3.10", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tailwindcss": { + "version": "3.4.17", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.17.tgz", + "integrity": "sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==", + "dev": true, + "license": "MIT", + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "arg": "^5.0.2", + "chokidar": "^3.6.0", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.3.2", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "jiti": "^1.21.6", + "lilconfig": "^3.1.3", + "micromatch": "^4.0.8", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.1.1", + "postcss": "^8.4.47", + "postcss-import": "^15.1.0", + "postcss-js": "^4.0.1", + "postcss-load-config": "^4.0.2", + "postcss-nested": "^6.2.0", + "postcss-selector-parser": "^6.1.2", + "resolve": "^1.22.8", + "sucrase": "^3.35.0" + }, + "bin": { + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tailwindcss/node_modules/jiti": { + "version": "1.21.7", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", + "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/tar-stream": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", + "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "b4a": "^1.6.4", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" + } + }, + "node_modules/text-decoder": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.3.tgz", + "integrity": "sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "b4a": "^1.6.4" + } + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/ts-api-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.0.1.tgz", + "integrity": "sha512-dnlgjFSVetynI8nzgJ+qF62efpglpWRk8isUEWZGWlJYySCTD6aKvbUDu+zbPeDakk3bg5H4XpitHukgfL1m9w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, + "node_modules/ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/typescript": { + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", + "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/typescript-eslint": { + "version": "8.26.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.26.0.tgz", + "integrity": "sha512-PtVz9nAnuNJuAVeUFvwztjuUgSnJInODAUx47VDwWPXzd5vismPOtPtt83tzNXyOjVQbPRp786D6WFW/M2koIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.26.0", + "@typescript-eslint/parser": "8.26.0", + "@typescript-eslint/utils": "8.26.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/undici-types": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "dev": true, + "license": "MIT" + }, + "node_modules/update-browserslist-db": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", + "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/vite": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.2.1.tgz", + "integrity": "sha512-n2GnqDb6XPhlt9B8olZPrgMD/es/Nd1RdChF6CBD/fHW6pUyUTt2sQW2fPRX5GiD9XEa6+8A6A4f2vT6pSsE7Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.25.0", + "postcss": "^8.5.3", + "rollup": "^4.30.1" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "jiti": ">=1.21.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "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==", + "dev": true, + "license": "MIT", + "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/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/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==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/yaml": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.0.tgz", + "integrity": "sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==", + "dev": true, + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zip-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-6.0.1.tgz", + "integrity": "sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==", + "dev": true, + "license": "MIT", + "dependencies": { + "archiver-utils": "^5.0.0", + "compress-commons": "^6.0.2", + "readable-stream": "^4.0.0" + }, + "engines": { + "node": ">= 14" + } + } + } +} diff --git a/plugin/home/package.json b/plugin/home/package.json new file mode 100644 index 00000000..465ed662 --- /dev/null +++ b/plugin/home/package.json @@ -0,0 +1,37 @@ +{ + "name": "home", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc -b && vite build", + "build:plugin": "node ./build.mjs", + "lint": "eslint .", + "preview": "vite preview" + }, + "dependencies": { + "deweb-pages": "file:../../server/pages/", + "react": "^19.0.0", + "react-dom": "^19.0.0", + "react-icons": "^5.5.0" + }, + "devDependencies": { + "@eslint/js": "^9.21.0", + "@types/node": "^22.13.10", + "@types/react": "^19.0.10", + "@types/react-dom": "^19.0.4", + "@vitejs/plugin-react": "^4.3.4", + "archiver": "^7.0.1", + "autoprefixer": "^10.4.21", + "eslint": "^9.21.0", + "eslint-plugin-react-hooks": "^5.1.0", + "eslint-plugin-react-refresh": "^0.4.19", + "globals": "^15.15.0", + "postcss": "^8.5.3", + "tailwindcss": "^3.4.17", + "typescript": "~5.7.2", + "typescript-eslint": "^8.24.1", + "vite": "^6.2.0" + } +} diff --git a/plugin/home/postcss.config.js b/plugin/home/postcss.config.js new file mode 100644 index 00000000..2e7af2b7 --- /dev/null +++ b/plugin/home/postcss.config.js @@ -0,0 +1,6 @@ +export default { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +} diff --git a/plugin/home/src/App.tsx b/plugin/home/src/App.tsx new file mode 100644 index 00000000..9d19e5b5 --- /dev/null +++ b/plugin/home/src/App.tsx @@ -0,0 +1,59 @@ +import { FiSearch } from "react-icons/fi"; +import { useEffect, useState } from "react"; +import { GenerateTheme } from "deweb-pages/src/hooks/GenerateTheme"; + +export default function App() { + const [searchQuery, setSearchQuery] = useState(""); + const [port, setPort] = useState(""); + + // On mount, get the port from the API by hitting /port + useEffect(() => { + const url = window.location.href.endsWith("/") + ? window.location.href + : `${window.location.href}/`; + + fetch(`${url}port`) + .then((res) => res.text()) + .then((port) => setPort(port)); + }, []); + + // Redirect the user to the requested website. + // If the user is on `station.massa`..., we redirect to localhost:{port} + // Otherwise, we redirect to {searchQuery}.{host} (very likely dev mode) + const handleSearch = (e: React.FormEvent) => { + e.preventDefault(); + const { host } = new URL(window.location.href); + if (host === "station.massa") { + // We have to force http because the plugin has a random localhost address and port + const redirectUrl = `http://${searchQuery}.localhost:${port}`; + window.location.href = redirectUrl; + } else { + const redirectUrl = `//${searchQuery}.${host}`; + window.location.href = redirectUrl; + } + }; + + const theme = GenerateTheme(); + + return ( +
+

Search on DeWeb

+
+ + setSearchQuery(e.target.value)} + className="px-3 py-2 text-primary w-full bg-secondary outline-none placeholder-primary" + placeholder="Enter domain" + /> + .massa + +
+ ); +} diff --git a/plugin/home/src/index.css b/plugin/home/src/index.css new file mode 100644 index 00000000..bd6213e1 --- /dev/null +++ b/plugin/home/src/index.css @@ -0,0 +1,3 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; \ No newline at end of file diff --git a/plugin/home/src/main.tsx b/plugin/home/src/main.tsx new file mode 100644 index 00000000..bef5202a --- /dev/null +++ b/plugin/home/src/main.tsx @@ -0,0 +1,10 @@ +import { StrictMode } from 'react' +import { createRoot } from 'react-dom/client' +import './index.css' +import App from './App.tsx' + +createRoot(document.getElementById('root')!).render( + + + , +) diff --git a/plugin/home/src/vite-env.d.ts b/plugin/home/src/vite-env.d.ts new file mode 100644 index 00000000..11f02fe2 --- /dev/null +++ b/plugin/home/src/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/plugin/home/tailwind.config.js b/plugin/home/tailwind.config.js new file mode 100644 index 00000000..550ed618 --- /dev/null +++ b/plugin/home/tailwind.config.js @@ -0,0 +1,7 @@ +/** @type {import('tailwindcss').Config} */ + +export default { + content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"], + + presets: [require("../../server/pages/src/colors/preset.js")], +}; diff --git a/plugin/home/tsconfig.app.json b/plugin/home/tsconfig.app.json new file mode 100644 index 00000000..358ca9ba --- /dev/null +++ b/plugin/home/tsconfig.app.json @@ -0,0 +1,26 @@ +{ + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", + "target": "ES2020", + "useDefineForClassFields": true, + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "module": "ESNext", + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "isolatedModules": true, + "moduleDetection": "force", + "noEmit": true, + "jsx": "react-jsx", + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedSideEffectImports": true + }, + "include": ["src"] +} diff --git a/plugin/home/tsconfig.json b/plugin/home/tsconfig.json new file mode 100644 index 00000000..1ffef600 --- /dev/null +++ b/plugin/home/tsconfig.json @@ -0,0 +1,7 @@ +{ + "files": [], + "references": [ + { "path": "./tsconfig.app.json" }, + { "path": "./tsconfig.node.json" } + ] +} diff --git a/plugin/home/tsconfig.node.json b/plugin/home/tsconfig.node.json new file mode 100644 index 00000000..db0becc8 --- /dev/null +++ b/plugin/home/tsconfig.node.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", + "target": "ES2022", + "lib": ["ES2023"], + "module": "ESNext", + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "isolatedModules": true, + "moduleDetection": "force", + "noEmit": true, + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedSideEffectImports": true + }, + "include": ["vite.config.ts"] +} diff --git a/plugin/home/vite.config.ts b/plugin/home/vite.config.ts new file mode 100644 index 00000000..54abef61 --- /dev/null +++ b/plugin/home/vite.config.ts @@ -0,0 +1,13 @@ +import { defineConfig, loadEnv } from 'vite' +import react from '@vitejs/plugin-react' + +export default ({ mode }: any) => { + // loadEnv(mode, process.cwd()) will load the .env files depending on the mode + // import.meta.env.BASE_URL available here with: process.env.BASE_URL + process.env = { ...process.env, ...loadEnv(mode, process.cwd()) }; + + return defineConfig({ + plugins: [react()], + base: process.env.BASE_URL, + }) +} From 6ecdb0574ab5dec78086e738acab834ecade1972 Mon Sep 17 00:00:00 2001 From: thomas-senechal Date: Wed, 12 Mar 2025 16:46:29 +0100 Subject: [PATCH 08/57] Add homePage serving from plugin --- plugin/go.mod | 43 ++++---- plugin/go.sum | 223 ++++++++------------------------------- plugin/main.go | 6 +- server/int/api/plugin.go | 30 ++++-- 4 files changed, 93 insertions(+), 209 deletions(-) diff --git a/plugin/go.mod b/plugin/go.mod index 78ce4832..694ff4d8 100644 --- a/plugin/go.mod +++ b/plugin/go.mod @@ -6,49 +6,48 @@ replace github.com/massalabs/deweb-server => ../server require ( github.com/massalabs/deweb-server v0.0.0 - github.com/massalabs/station v0.6.4 + github.com/massalabs/station v0.6.5 ) require ( - github.com/PuerkitoBio/purell v1.1.1 // indirect - github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect - github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d // indirect + github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect github.com/awnumar/memcall v0.1.2 // indirect github.com/awnumar/memguard v0.22.3 // indirect github.com/btcsuite/btcutil v1.0.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/docker/go-units v0.4.0 // indirect - github.com/go-openapi/analysis v0.21.2 // indirect - github.com/go-openapi/errors v0.20.2 // indirect - github.com/go-openapi/jsonpointer v0.19.5 // indirect - github.com/go-openapi/jsonreference v0.19.6 // indirect - github.com/go-openapi/loads v0.21.1 // indirect - github.com/go-openapi/runtime v0.25.0 // indirect - github.com/go-openapi/spec v0.20.4 // indirect - github.com/go-openapi/strfmt v0.21.3 // indirect - github.com/go-openapi/swag v0.22.3 // indirect - github.com/go-openapi/validate v0.22.0 // indirect + github.com/docker/go-units v0.5.0 // indirect + github.com/go-openapi/analysis v0.23.0 // indirect + github.com/go-openapi/errors v0.22.0 // indirect + github.com/go-openapi/jsonpointer v0.21.0 // indirect + github.com/go-openapi/jsonreference v0.21.0 // indirect + github.com/go-openapi/loads v0.22.0 // indirect + github.com/go-openapi/runtime v0.28.0 // indirect + github.com/go-openapi/spec v0.21.0 // indirect + github.com/go-openapi/strfmt v0.23.0 // indirect + github.com/go-openapi/swag v0.23.0 // indirect + github.com/go-openapi/validate v0.24.0 // indirect github.com/gofrs/flock v0.12.1 // indirect - github.com/jessevdk/go-flags v1.5.0 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/jessevdk/go-flags v1.6.1 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/klauspost/cpuid/v2 v2.1.0 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/massalabs/station-massa-hello-world v0.0.11-0.20240503070604-6b14a27fcdff // indirect - github.com/massalabs/station-massa-wallet v0.4.3 // indirect + github.com/massalabs/station-massa-wallet v0.4.5 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/oklog/ulid v1.3.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/shopspring/decimal v1.3.1 // indirect github.com/stretchr/testify v1.9.0 // indirect github.com/ybbus/jsonrpc/v3 v3.1.4 // indirect - go.mongodb.org/mongo-driver v1.11.3 // indirect + go.mongodb.org/mongo-driver v1.14.0 // indirect go.uber.org/atomic v1.10.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.24.0 // indirect - golang.org/x/crypto v0.14.0 // indirect - golang.org/x/net v0.17.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/text v0.13.0 // indirect + golang.org/x/crypto v0.32.0 // indirect + golang.org/x/net v0.34.0 // indirect + golang.org/x/sync v0.10.0 // indirect + golang.org/x/sys v0.29.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/plugin/go.sum b/plugin/go.sum index 1b6b290d..b07a03f1 100644 --- a/plugin/go.sum +++ b/plugin/go.sum @@ -1,12 +1,6 @@ -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= -github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= -github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= -github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= -github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= -github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d h1:Byv0BzEl3/e6D5CLfI0j/7hiIEtvGVFPCZ7Ei2oq8iQ= -github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= +github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= +github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/awnumar/memcall v0.1.2 h1:7gOfDTL+BJ6nnbtAp9+HQzUFjtP1hEseRQq8eP055QY= github.com/awnumar/memcall v0.1.2/go.mod h1:S911igBPR9CThzd/hYQQmTc9SWNu3ZHIlCGaWsWsoJo= github.com/awnumar/memguard v0.22.3 h1:b4sgUXtbUjhrGELPbuC62wU+BsPQy+8lkWed9Z+pj0Y= @@ -23,174 +17,86 @@ github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVa github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= -github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= +github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/go-openapi/analysis v0.21.2 h1:hXFrOYFHUAMQdu6zwAiKKJHJQ8kqZs1ux/ru1P1wLJU= -github.com/go-openapi/analysis v0.21.2/go.mod h1:HZwRk4RRisyG8vx2Oe6aqeSQcoxRp47Xkp3+K6q+LdY= -github.com/go-openapi/errors v0.19.8/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= -github.com/go-openapi/errors v0.19.9/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= -github.com/go-openapi/errors v0.20.2 h1:dxy7PGTqEh94zj2E3h1cUmQQWiM1+aeCROfAr02EmK8= -github.com/go-openapi/errors v0.20.2/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= -github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= -github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonreference v0.19.6 h1:UBIxjkht+AWIgYzCDSv2GN+E/togfwXUJFRTWhl2Jjs= -github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns= -github.com/go-openapi/loads v0.21.1 h1:Wb3nVZpdEzDTcly8S4HMkey6fjARRzb7iEaySimlDW0= -github.com/go-openapi/loads v0.21.1/go.mod h1:/DtAMXXneXFjbQMGEtbamCZb+4x7eGwkvZCvBmwUG+g= -github.com/go-openapi/runtime v0.25.0 h1:7yQTCdRbWhX8vnIjdzU8S00tBYf7Sg71EBeorlPHvhc= -github.com/go-openapi/runtime v0.25.0/go.mod h1:Ux6fikcHXyyob6LNWxtE96hWwjBPYF0DXgVFuMTneOs= -github.com/go-openapi/spec v0.20.4 h1:O8hJrt0UMnhHcluhIdUgCLRWyM2x7QkBXRvOs7m+O1M= -github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I= -github.com/go-openapi/strfmt v0.21.0/go.mod h1:ZRQ409bWMj+SOgXofQAGTIo2Ebu72Gs+WaRADcS5iNg= -github.com/go-openapi/strfmt v0.21.1/go.mod h1:I/XVKeLc5+MM5oPNN7P6urMOpuLXEcNrCX/rPGuWb0k= -github.com/go-openapi/strfmt v0.21.3 h1:xwhj5X6CjXEZZHMWy1zKJxvW9AfHC9pkyUjLvHtKG7o= -github.com/go-openapi/strfmt v0.21.3/go.mod h1:k+RzNO0Da+k3FrrynSNN8F7n/peCmQQqbbXjtDfvmGg= -github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= -github.com/go-openapi/swag v0.21.1/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= -github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= -github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= -github.com/go-openapi/validate v0.22.0 h1:b0QecH6VslW/TxtpKgzpO1SNG7GU2FsaqKdP1E2T50Y= -github.com/go-openapi/validate v0.22.0/go.mod h1:rjnrwK57VJ7A8xqfpAOEKRH8yQSGUriMu5/zuPSQ1hg= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0= -github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY= -github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg= -github.com/gobuffalo/envy v1.6.15/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= -github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= -github.com/gobuffalo/flect v0.1.0/go.mod h1:d2ehjJqGOH/Kjqcoz+F7jHTBbmDb38yXA598Hb50EGs= -github.com/gobuffalo/flect v0.1.1/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= -github.com/gobuffalo/flect v0.1.3/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= -github.com/gobuffalo/genny v0.0.0-20190329151137-27723ad26ef9/go.mod h1:rWs4Z12d1Zbf19rlsn0nurr75KqhYp52EAGGxTbBhNk= -github.com/gobuffalo/genny v0.0.0-20190403191548-3ca520ef0d9e/go.mod h1:80lIj3kVJWwOrXWWMRzzdhW3DsrdjILVil/SFKBzF28= -github.com/gobuffalo/genny v0.1.0/go.mod h1:XidbUqzak3lHdS//TPu2OgiFB+51Ur5f7CSnXZ/JDvo= -github.com/gobuffalo/genny v0.1.1/go.mod h1:5TExbEyY48pfunL4QSXxlDOmdsD44RRq4mVZ0Ex28Xk= -github.com/gobuffalo/gitgen v0.0.0-20190315122116-cc086187d211/go.mod h1:vEHJk/E9DmhejeLeNt7UVvlSGv3ziL+djtTr3yyzcOw= -github.com/gobuffalo/gogen v0.0.0-20190315121717-8f38393713f5/go.mod h1:V9QVDIxsgKNZs6L2IYiGR8datgMhB577vzTDqypH360= -github.com/gobuffalo/gogen v0.1.0/go.mod h1:8NTelM5qd8RZ15VjQTFkAW6qOMx5wBbW4dSCS3BY8gg= -github.com/gobuffalo/gogen v0.1.1/go.mod h1:y8iBtmHmGc4qa3urIyo1shvOD8JftTtfcKi+71xfDNE= -github.com/gobuffalo/logger v0.0.0-20190315122211-86e12af44bc2/go.mod h1:QdxcLw541hSGtBnhUc4gaNIXRjiDppFGaDqzbrBd3v8= -github.com/gobuffalo/mapi v1.0.1/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= -github.com/gobuffalo/mapi v1.0.2/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= -github.com/gobuffalo/packd v0.0.0-20190315124812-a385830c7fc0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= -github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= -github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ= -github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0= -github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw= +github.com/go-openapi/analysis v0.23.0 h1:aGday7OWupfMs+LbmLZG4k0MYXIANxcuBTYUC03zFCU= +github.com/go-openapi/analysis v0.23.0/go.mod h1:9mz9ZWaSlV8TvjQHLl2mUW2PbZtemkE8yA5v22ohupo= +github.com/go-openapi/errors v0.22.0 h1:c4xY/OLxUBSTiepAg3j/MHuAv5mJhnf53LLMWFB+u/w= +github.com/go-openapi/errors v0.22.0/go.mod h1:J3DmZScxCDufmIMsdOuDHxJbdOGC0xtUynjIx092vXE= +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/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ= +github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4= +github.com/go-openapi/loads v0.22.0 h1:ECPGd4jX1U6NApCGG1We+uEozOAvXvJSF4nnwHZ8Aco= +github.com/go-openapi/loads v0.22.0/go.mod h1:yLsaTCS92mnSAZX5WWoxszLj0u+Ojl+Zs5Stn1oF+rs= +github.com/go-openapi/runtime v0.28.0 h1:gpPPmWSNGo214l6n8hzdXYhPuJcGtziTOgUpvsFWGIQ= +github.com/go-openapi/runtime v0.28.0/go.mod h1:QN7OzcS+XuYmkQLw05akXk0jRH/eZ3kb18+1KwW9gyc= +github.com/go-openapi/spec v0.21.0 h1:LTVzPc3p/RzRnkQqLRndbAzjY0d0BCL72A6j3CdL9ZY= +github.com/go-openapi/spec v0.21.0/go.mod h1:78u6VdPw81XU44qEWGhtr982gJ5BWg2c0I5XwVMotYk= +github.com/go-openapi/strfmt v0.23.0 h1:nlUS6BCqcnAk0pyhi9Y+kdDVZdZMHfEKQiS4HaMgO/c= +github.com/go-openapi/strfmt v0.23.0/go.mod h1:NrtIpfKtWIygRkKVsxh7XQMDQW5HKQl6S5ik2elW+K4= +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-openapi/validate v0.24.0 h1:LdfDKwNbpB6Vn40xhTdNZAnfLECL81w+VX3BumrGD58= +github.com/go-openapi/validate v0.24.0/go.mod h1:iyeX1sEufmv3nPbBdX3ieNviWnOZaJ1+zquzJEf2BAQ= github.com/gofrs/flock v0.12.1 h1:MTLVXXHf8ekldpJk3AKicLij9MdwOWkZ+a/jHHZby9E= github.com/gofrs/flock v0.12.1/go.mod h1:9zxTsyu5xtJ9DK+1tFZyibEV7y3uwDxPPfbxeeHCoD0= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jessevdk/go-flags v1.5.0 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LFvc= -github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= -github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= +github.com/jessevdk/go-flags v1.6.1 h1:Cvu5U8UGrLay1rZfv/zP7iLpSHGUZ/Ou68T0iX1bBK4= +github.com/jessevdk/go-flags v1.6.1/go.mod h1:Mk8T1hIAWpOiJiHa9rJASDK2UGWji0EuPGBnNLMooyc= 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/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= -github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4= -github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= -github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.1.0 h1:eyi1Ad2aNJMW95zcSbmGg7Cg6cq3ADwLpMAP96d8rF0= github.com/klauspost/cpuid/v2 v2.1.0/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= 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/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= -github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= -github.com/massalabs/station v0.6.4 h1:qAIj13cCQxboBBGdQwtcdoHCPPafOFM/+kO2+t2H2xo= -github.com/massalabs/station v0.6.4/go.mod h1:i9d/zAqeDYxY0Od5LEfEkP6V2osUhA13GwA72ByM8bQ= +github.com/massalabs/station v0.6.5 h1:lkWWYB0/dPsRHSoAqN0wh/mFx8+InsVGMfraXQFZ76U= +github.com/massalabs/station v0.6.5/go.mod h1:i9d/zAqeDYxY0Od5LEfEkP6V2osUhA13GwA72ByM8bQ= github.com/massalabs/station-massa-hello-world v0.0.11-0.20240503070604-6b14a27fcdff h1:SZoRmXdbolVjhbsxO/3KWX8429Q1VnaQdQy0h718CqE= github.com/massalabs/station-massa-hello-world v0.0.11-0.20240503070604-6b14a27fcdff/go.mod h1:QbRHQvJFrm4mO+vPzr4Uiwa5REL/CgBlV4PDFdhewa0= -github.com/massalabs/station-massa-wallet v0.4.3 h1:ch1+YSSr7ar56GzoTLNp++dl5J0MCfD3x6bGeA1fs38= -github.com/massalabs/station-massa-wallet v0.4.3/go.mod h1:RJcPhvJUkcsA8NhHJEeZGmLSb+DqqhVY3ljiQ8vCe4c= -github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/massalabs/station-massa-wallet v0.4.5 h1:0rTHxGPlJ5cKjgB/yQclOBHbWiZO5rOwO0lT7ZjFuVQ= +github.com/massalabs/station-massa-wallet v0.4.5/go.mod h1:Eu6Zlijs0uAuGM5CxEUOxFrcIlWtuZVAbiWPCUni9XY= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 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.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.8.1 h1:geMPLpDpQOgVyCg5z5GoRwLHepNdb71NXb67XFkP+Eg= -github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= +github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= +github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= -github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= -github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= 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/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= -github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= -github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= -github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= -github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g= -github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= -github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8= github.com/ybbus/jsonrpc/v3 v3.1.4 h1:pPmgfWXnqR2GdIlealyCzmV6LV3nxm3w9gwA1B3cP3Y= github.com/ybbus/jsonrpc/v3 v3.1.4/go.mod h1:4HQTl0UzErqWGa6bSXhp8rIjifMAMa55E4D5wdhe768= -github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= -go.mongodb.org/mongo-driver v1.7.3/go.mod h1:NqaYOwnXWr5Pm7AOpO5QFxKJ503nbMse/R79oO62zWg= -go.mongodb.org/mongo-driver v1.7.5/go.mod h1:VXEWRZ6URJIkUq2SCAyapmhH0ZLRBP+FT4xhp5Zvxng= -go.mongodb.org/mongo-driver v1.10.0/go.mod h1:wsihk0Kdgv8Kqu1Anit4sfK+22vSFbUrAVEYRhCXrA8= -go.mongodb.org/mongo-driver v1.11.3 h1:Ql6K6qYHEzB6xvu4+AU0BoRoqf9vFPcc4o7MUIdPW8Y= -go.mongodb.org/mongo-driver v1.11.3/go.mod h1:PTSz5yu21bkT/wXpkS7WR5f0ddqw5quethTUn9WM+2g= +go.mongodb.org/mongo-driver v1.14.0 h1:P98w8egYRjYe3XDjxhYJagTokP/H6HzlsnojRgZRd80= +go.mongodb.org/mongo-driver v1.14.0/go.mod h1:Vzb0Mk/pa7e6cWw85R4F/endUC3u0U9jGcNU603k65c= go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= @@ -200,77 +106,36 @@ go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN8 go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= -golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= +golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= +golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= +golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +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.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= +golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/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/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0/go.mod h1:WDnlLJ4WF5VGsH/HVa3CI79GS0ol3YnhVnKP89i0kNg= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= howett.net/plist v1.0.0 h1:7CrbWYbPPO/PyNy38b2EB/+gYbjCe2DXBxgtOOZbSQM= diff --git a/plugin/main.go b/plugin/main.go index ee29d3db..cc1d0d0f 100644 --- a/plugin/main.go +++ b/plugin/main.go @@ -1,6 +1,7 @@ package main import ( + _ "embed" "fmt" "log" "os" @@ -14,6 +15,9 @@ import ( const directoryName = "station-deweb-plugin" +//go:embed home/dist/home.zip +var homeZip []byte + func main() { pluginDir, err := PluginDir() if err != nil { @@ -34,7 +38,7 @@ func main() { CacheDir: filepath.Join(pluginDir, "websiteCache"), } - api := api.NewPluginAPI(&conf) + api := api.NewPluginAPI(&conf, homeZip) api.Start() } diff --git a/server/int/api/plugin.go b/server/int/api/plugin.go index 76b1343d..e3a8ce24 100644 --- a/server/int/api/plugin.go +++ b/server/int/api/plugin.go @@ -1,7 +1,9 @@ package api import ( + "fmt" "log" + "net" "net/http" "github.com/go-openapi/loads" @@ -16,9 +18,10 @@ type PluginAPI struct { conf *config.ServerConfig apiServer *restapi.Server dewebAPI *operations.DeWebAPI + homeZip []byte } -func NewPluginAPI(conf *config.ServerConfig) *PluginAPI { +func NewPluginAPI(conf *config.ServerConfig, homeZip []byte) *PluginAPI { swaggerSpec, err := loads.Analyzed(restapi.SwaggerJSON, "") if err != nil { log.Fatalln(err) @@ -31,6 +34,7 @@ func NewPluginAPI(conf *config.ServerConfig) *PluginAPI { conf: conf, apiServer: server, dewebAPI: dewebAPI, + homeZip: homeZip, } } @@ -48,13 +52,16 @@ func (a *PluginAPI) Start() { a.apiServer.ConfigureAPI() - a.apiServer.SetHandler(StationMiddleware(SubdomainMiddleware(a.dewebAPI.Serve(nil), a.conf))) + a.apiServer.SetHandler(StationMiddleware(SubdomainMiddleware(a.dewebAPI.Serve(nil), a.conf), a.homeZip, a.conf)) listener, err := a.apiServer.HTTPListener() if err != nil { logger.Fatalf("Failed to get HTTP listener: %v", err) } + // We get the port from the listener in case the port was set to 0 and the OS assigned a port + a.conf.APIPort = listener.Addr().(*net.TCPAddr).Port + if err := plugin.RegisterPlugin(listener); err != nil { logger.Fatalf("Failed to register plugin: %v", err) } @@ -70,14 +77,11 @@ func (a *PluginAPI) configurePluginAPI() { log.Printf("ServeError: %v", err) w.WriteHeader(http.StatusInternalServerError) } - - a.dewebAPI.GetResourceHandler = operations.GetResourceHandlerFunc(getResourceHandler) - a.dewebAPI.DefaultPageHandler = operations.DefaultPageHandlerFunc(defaultPageHandler) } // StationMiddleware handles station website serving. // It is used by the plugin to serve massastation plugin page if the request domain is `station.massa`. -func StationMiddleware(handler http.Handler) http.Handler { +func StationMiddleware(handler http.Handler, homePageZip []byte, conf *config.ServerConfig) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { logger.Debugf("StationMiddleware: Handling request for %s", r.Host) @@ -90,8 +94,20 @@ func StationMiddleware(handler http.Handler) http.Handler { path := cleanPath(r.URL.Path) + // FIXME: Following if is a hack. We should make a clean API for the plugin + if path == "port" { + w.WriteHeader(http.StatusOK) + + _, err := w.Write([]byte(fmt.Sprintf("%d", conf.APIPort))) + if err != nil { + logger.Errorf("Failed to write port: %v", err) + } + + return + } + logger.Debugf("StationMiddleware: Serving station.massa plugin page") - localHandler(w, homeZip, path) + localHandler(w, homePageZip, path) }) } From 59edd73e7f5fce860ab43d0474d954cb1983d313 Mon Sep 17 00:00:00 2001 From: thomas-senechal Date: Wed, 12 Mar 2025 16:46:59 +0100 Subject: [PATCH 09/57] Remove useless commands for moving zip files in Taskfile.yml --- plugin/Taskfile.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/plugin/Taskfile.yml b/plugin/Taskfile.yml index 13df31e3..22b4f3f6 100644 --- a/plugin/Taskfile.yml +++ b/plugin/Taskfile.yml @@ -8,11 +8,6 @@ tasks: generate: cmds: - cmd: go generate ./... - - cmd: mv pages/*.zip int/api/resources/ - platforms: [linux, darwin] - # Workaround because no support for builtins commands on Windows https://github.com/go-task/task/issues/197 - - cmd: cmd /C 'for %f in (pages\*.zip) do move %f int\api\resources\' - platforms: [windows] run: cmds: From 73bc9710b371a16064a6f1034ab0823ad7287b39 Mon Sep 17 00:00:00 2001 From: thomas-senechal Date: Wed, 12 Mar 2025 16:48:29 +0100 Subject: [PATCH 10/57] Add GitHub Actions workflow to build and upload plugin artifacts for multiple OS targets --- .github/workflows/build.yml | 62 +++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index caa694ef..5fe7db7a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -76,3 +76,65 @@ jobs: with: name: deweb-server_${{ matrix.target }}_${{ matrix.arch }} path: server/build/deweb-server_${{ matrix.target }}_${{ matrix.arch }}${{ matrix.ext }} + + build-plugin: + name: build and upload plugin artifact + strategy: + matrix: + include: + - os: windows-2022 + arch: amd64 + target: windows + ext: .exe + - os: ubuntu-20.04 + arch: amd64 + target: linux + - os: ubuntu-20.04 + arch: arm64 + target: linux + - os: macos-13 + arch: amd64 + target: darwin + - os: macos-14 + arch: arm64 + target: darwin + + runs-on: ${{ matrix.os }} + + defaults: + run: + working-directory: ./plugin + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: installing dependencies + uses: ./.github/actions/install + with: + os: ${{ matrix.os }} + repo-token: ${{ secrets.GITHUB_TOKEN }} + + - name: Check if VERSION exists + shell: bash + id: check_version + run: | + if [ ! -z "${{ env.VERSION }}" ]; then + echo "PRODUCTION=true" >> $GITHUB_ENV + fi + + - name: Build Plugin + shell: bash + run: task build + env: + OS: ${{ matrix.target }} + ARCH: ${{ matrix.arch }} + + - name: Rename Plugin artifact + run: mv build/deweb-plugin${{ matrix.ext }} build/deweb-plugin_${{ matrix.target }}_${{ matrix.arch }}${{ matrix.ext }} + + - name: Upload Plugin artifact + uses: actions/upload-artifact@v4 + with: + name: deweb-plugin_${{ matrix.target }}_${{ matrix.arch }} + path: plugin/build/deweb-plugin_${{ matrix.target }}_${{ matrix.arch }}${{ matrix.ext }} From 6ee5656b14e991c2cdc6b6f1927861952ec80167 Mon Sep 17 00:00:00 2001 From: thomas-senechal Date: Wed, 12 Mar 2025 16:57:33 +0100 Subject: [PATCH 11/57] Add working-directory input to GitHub Actions install action and update workflows to utilize it --- .github/workflows/build.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5fe7db7a..7504a1e3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -115,6 +115,16 @@ jobs: os: ${{ matrix.os }} repo-token: ${{ secrets.GITHUB_TOKEN }} + - name: Install Plugin Go Dependencies + run: task install + shell: bash + working-directory: ./plugin + + - name: Go Generate Plugin + run: task generate + shell: bash + working-directory: ./plugin + - name: Check if VERSION exists shell: bash id: check_version From 7a8b8d9996a34b92ae1fd919dd4ff9b5c17483cb Mon Sep 17 00:00:00 2001 From: thomas-senechal Date: Wed, 12 Mar 2025 17:44:06 +0100 Subject: [PATCH 12/57] Improve plugin favicon --- plugin/favicon.png | Bin 5032 -> 6128 bytes plugin/home/index.html | 2 +- plugin/home/public/favicon.png | Bin 0 -> 5032 bytes 3 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 plugin/home/public/favicon.png diff --git a/plugin/favicon.png b/plugin/favicon.png index 297aa0c6c30b9cf4a5e2b28526c9736747b6893a..baa5d9b102378cddc1b008cd9fcb5b90e5824887 100644 GIT binary patch literal 6128 zcmeHLXH-+`whf5V!3aViG(knwPy|5@MFIu|1QjfF2rURfL7H@=g^~m=3erUm^-x4Z zKtk`zL4rU6NRLVvB2oi#cQ|*9_kO&8?~eQHW{f@d-fMq7YpuEFjJsuGz|SMj0|J5g zZ(P^E0|K#)vM#P8fTidwwi38;KfZ491O(z0VqI*Yj4TLXWP5VQ00FA_Bry-XaJcH; z)CGa62)w%vhe04w_Z#}U<^gQW<2MtZ->qwA(C1$8RzdS4iha~*)N>Oi7<#zPn2+J&X)Zk0GL42OnP(8gbU?DbD(zq3!j zKX<=k_ufl!@L)l~Vq`PVxvz1j5O_kYca^5m_J1{lPL@n6|LlFhvprw^Pg%y z7diK1oLsGJ6Xo~pntfl+UP;#FHTu+LN)u#WO1nPf=-BkAQp!!V{NVN)?PH1AWTsS1 ze8-v1xqjMV|5onhsJJ&$@Qrc>6#9C*pMyiD?-=(fqR>fXRTrT$<8;iCj$-v^(0uFD z2^16TKv5XP`1m1ALNbPfHs|Nfwal@#Mc;=dBdmZ?-+dcA~MTAcLlVIN6aaYk~3yz;xD zEVj87J>x4%-eK~2p8vA@O$m-kdYD8}KP?OY;d8J4st$AMW<<0~hj(wB(ET8*E*$w# zM>kbFjx_8$mh`e!T;r`5X5zlxvarR2*ho%0$$I>b_}xwy7_Fzq01X94Xa#L_UBJIQ z{rhXm<&|d+hkk|N-0P?P+8rDu%O!E3363LnJ*kRC!@^X;o3?YGXk8 z^4RbhUi1#8)XOv%RSKO6$eRp#F*l4^> zt@0?bs{i~id6(xiiVtj5L#%c3%7;IG%y#`f_CWeVMs(=%mrd_^J&E4y4N)Xietp2$ zpT~A+G|UomTf^{jDPYozA9>{q6PW>Chr)!5 zuKD&3dW{3kdwObex1TTr91anvG%PiyIFK7tfE4Qo)~5CSyZQ@lV0mejdk>$B;=r)M z{7M>qVL>VS3imR{V?F<31G~zuOpTk8G(*<-SW;!l*(m~Q)=S!0l4is*koUbU$| z{WOVk@1p?1UKmMS|2u8sRIeSrrSb1csY=4(T@S37)md6hv-eNea-AIk^J>EL zq7{7B7shojrKLR*L{>7~Wnw9<90|$uy_roDgohmKp9`!A5>?v0ySv}n6HU;04sA)u zt8{RmTrq>Ga=1QOZU{(IyvkSdqGPP<1M($w8m|OQtou|-b}35%w%zSMolR2CS)#HO z=e?_XJBitp)_^Dx@z1j{C-b5iTrf2!KT^|BPPtXNTFa$_4_Io2BZNRf=#}*&f&j~a z!K#ZZ&c(qR!Hb)Bl!$f+K4{o5C=N?BMMo4} z@a3ZmS)%^}Qt9W5W?jnKdC{G`=t?8)!KCCr|e8#Ws4}0&ZBHBCrSl8Vy3P> zxF~U9VJJvi$*%G4r<^^vRZSE*Xw%4f|94u?M1vJC1vpRFqxqk?77L8rBMFQ}KJe<= zY$d;x%IJ8_BlpVzt3$fM5$fD9%}(VCAju0NvqOUS9DE%A2>La*7`ciJkMQGyX`Xyt zNA%ePoYM&U9)A{D*M$#(b9p8{4r4CYuoHFB({{3NicCT#d*;?Hu05s)ag3fI8aIfr z^Ae5F>6YxgKDy}iD^))NcefVoQ@~f%^PEfD*GpC6%bin%l((Z&OO(f|-7_F_8I%i* zL{x+}H%#bUYv975U{mZy*FR1O;IWlp8cCqb_b4+?l+i5$>jW2rpnnf5b` zHo>Nm)sh)5S1f#~eeNO(dK))MAg^dbhGKQJZ|ss8SUC~Lc&o<_Z@FMXr>KsmSr1@P z7)qQF9gT?$=rmv5-A!%LNw^-fo}(+Vzn3CEDK1e3f!3hR1&F5TbV!luev-H5bi|>` zF*|=;t-y+0=BY+15bt~y>kR=6B-`jl5xbC#+*|Mf*27pxP;gD!Gx(#3-E4x=gj8_I zD-6PD?X4`_IuP1;HyOU`=Ku{EjRc$NKmu4=7%Oc=#X6w{#a$9T-`75WmEK%(QvPvv77cmBs zp=#5;b2wMtnyGSHT!lxao(^7Z(J@Tr@<>F>eW&U~;7$|Gl?oG81&0Z>or;d|zz9Bs z(U9yL*H2%^YPI-^5*+~#I+9oLuu75Kzxg7B;y*bK>(kn_X6u$Enx8|yOV`jP;7p}M zeq|^)%DkZ5DKE3>)T>fw)-;WK+v_A5qD$^H=ZiSs6!;T9!W7%8<0QV(O&* z0+mFip0#NV{?jR;dPHMli@=_A16^WbEaqyf0T*_E=Ox4zZj3PURkW_Pt+N*rrX0>I zIP3LewIe~pkTlG7Jo8mqANxpDYN=0^I#hNJYyrndcp!}KrluN052ai~ml)oc8-;xM z)QbTU-ycGjrC>OYJdDv)Q>9nxB=wn!msSBW?elHoI<=Q0JQ!hg5eW3OiuS>(%ngtY zu+;vc9Scn*bd}-8lX!){@znc zQ|utl0kt;|;a^6>vH?Gxkl+T86WFqJz!%+@+jK8LlLl=AQu&a@gJIh`ryWT5Nus&@ zkFNvk#eQCl+0Xx|Fi1yM1E5l1Xh3MRt@B~b;9UG@ohP6`K;H^i2aYlxj7f8q?)t?@ zSJg=!?dblQPiR!Iv9j4K0MUVoe1Xcez{oCi+ib|}4@N@>;NOAUQa4#BnEFssbL-)3 z{-|SDBkbaW>f2^uC3hDC&7ow1J9(@qrkh6-z{L{F#E0aGh~Sy_hZh~S0mbi3L`&o^S{5c``?CPFR8($MFP8K|vE%v$syma%*t$_Dx%|{)Bnur2 zxK&D*y&cW5R&&0RU#0_>0FIEBQCkH9W^zMhiTM8fYE|G4{<1k?HSeVFzp-Q*S$UW4 zmGpOKF_q|DMi<OZ;1v=_S9>z;?=1-6^vy|udW$^S$w*4S9C%Tex` zkS^}AL37v0s+#Ir@O%dUZRH$M9<}dleUpkSO--MBxX#T$2-v;V&-t!4aQv-~IiQTG zep?%WS$cfUsV_Uob#?!hkzH5_ndLa3d{&lPtOjRjD}}__3()S&&T0svpx}(mFFyNE zP>1?^GxsHe35@s9^@beH?eA0W$j4*}XYqcZl1V*%Z5ZWb)pknROW~F#if&H2q~Jc; zn8w*h=Ql_T+t^ZN&wqzBdWSL>mHVPiJ;ywn9J0EKuh<_0wl0-d;5KmV%OOtN?KW-; z8@u}+`Ul(9NW{>l=MD8YZqtr-0kMX{jTDO@0T7D1fm^1_LU$k?@Dn^NLn79rokUpl zP(6R%BWT9$feitzXPv`?n9e{so2x6i>53`Z!3WXP9hu7h5FUjXFL7s9vrZMd_&GC{!EJST)L zi{nm7N}VJM*#o(aZD9(hBq%h>JvFX6*tVD)3-FoM)|kLy)t0s>KXz*Xia@?wJMKo8 zcj0;2Ab>H{C&U;A(0hQd2Igw*avAgqwy`{fMr(T=3vc^f}Q*B~F3*J0K~MfliaC(p-xA)KtrT-sZM? z?njXnbs5E)s%f@>mu_@*E{q&rDx?9#*MX)Iy`X>`q4HV_;Qee|6TvlrsBlc_JUodl ze*_RE^iZ5XKcqZ5ZXbBf9_R8!mWYc>d2M{6?bj9WuNU)2I=L{BfWq*}O<6e_^>O%H z=rVW|*&+NkvfUxD{fzpA(|}YS#=MM{1K-3a!;B-a9`zHL7>^W+`gs(yL-dg#)g%0a zFeg>tsl10|gqFX$bai*>okqh^ht~FtvToAKzZ5a9`;`+gfJ4}Q0x&w8=N$4qHvHi<(QKwQdhy##2h`bZ z9%%tka3B_5bs~$nJjS98?B&xaCV56_)Q>-ZX184Tcm9U&SM;%mPy^bXpOXDBV4A`S zA|J9AK%JnYW1P~{(}ZT}Ysz$Q@=k3C?r- tY;fPwOjuTQEFi-RI6t`Ia`PtWEbz<)T&&+`vlQ0t#x)cD3WWW$e*)@P`P~2j literal 5032 zcmb_gXH*kix1K-md?6cNHpkxpodfP^9-BE1OGOHis1 z5dtW^DJ`KWf+AHE1ibNn>s{;K-}nC5>zwn<-gDN>?ERc)PrSLQ0gM^J3;+Pk$WZq> z0D#~$lZHZQ$O~N|0&QTz7~1*)01L-o0|D7NyfhHxcilh-s2M`8(H3C0%O;lrpgx)9 z$e95EI5drPFIxnGHs;N|INh?z+hw3d@i$ZkhPe7B8!?fO1I}5A;r6`EE}>12SAZc$ zsh4*@RV^gOF=M5OXPgsp%{|5a5ZW7Q&dXc38a^O5{$YM2 zqOEe_XLZG_ub)OTWbKK4-r}^Xkh)Hbl4vSw- znq)T!>yF6+&OAk*+>Y+ihUt={0t{t%KV#z%&7aFm7w1GGcxxl>RU}fL^6c?p&!5e@an#B;WGt?k zV?SCY+WPtgJ!g=URJFFGRKBjr(yfWztQSAI0;0vT%eMcF(b3V@ z6=#rt{Su>qZr3za{b_LQCYoZx$_hu%nT&|^O;(bbSPP6k?OfpF5B<`}_7BCrLet^v z_4`ScGHSXWa!NRS^1#NdW-MeRnndaz4PL2d3%b5C`K0N@IU_*~QFLUR4JC|@y4-c& zNd*jXaEGD%NNRnsT?ge_>5{a^fPbQdKsGxt2E7CItGlD zT01}>pL>#XEy*tviti|g8lOUFABKcdR9CZWcfH&u>#LXQ+R}h*X^^x`N zjt7;5goNeH9}5L)`*hTy(yIh-?h1_TYd zk6{jeMHh5H&1HV2M-Np*lf5ALg@J2R2M{j0=L%4O`Ja@fyp5ciYbNY^gO|6dT3M`_2CRc5;cVod~SXpSlrr^T&RYP zY2H@2nN9`XEN+VSXtkPP(g~`EpENavpxEKarVXyGuOcVgQ?Zk&yIab{8HdWQ4}>Dr`K|1@qNxV z^WcDI^y`KU8tg2JN~!4SvA)Lse(;zxF7CDd{wbtktQCAF{~=lw{>YQ7$Gf>D_!kte zBo2qbz?xQ8js_jj4K7rh)dD*mOu6*gkS$+J*R}DYFqB1 z%-Kj$*sM;o%Om9~tc?qM;A1BMoS|C4aV+tgNOs*h`|1;Y>`4>Beg#5iK zEX`{9pTOr47cBZA(e%m(yeh<3jZW$;P&ha)L5v>?pU~|DHL)Yh#xnE%Y|d-~zg^jPI+`hb9dmU~u;7Jt_yVHC~bulv77 z3v>HN@t%@86b?-NZv)3P$$Y$w5$1i59Hhkt_{MWivLk`2Q~w9s;J7oiv?TlVS*Ww% zE&abVrkh+@=~J{iyEbIkdhV9b=I^oTX~B8J*0R-bP_`ZhY)Zd4lv^q-{dx74Zt}jC z%d&6aev7g35wGTSZU>DZ`#v@bd`5|5VbNme?G%j7&NPhzApXvYS^$i_l@--}U@-lluW?G`*qV*sB}i)UjUO|0LR$((JA>G(mBR&LNsH7PsehSGn+bpw9-+g)oK}r>_VC7^Wr2?>o?QMgb z<1LR19@p-zuBUHJPEL=F?_MTy>rH1VsVQ8YZul}h@?!nx_iG@Li(rF9fA^gp9*Sxc zt|as1gno3GUqF+)<27cnTUyDk!>=8lKk%tcQCY8%yV}_{oMlfJ$(v=Sp`@lhyV9G) zan1bEqcBcO-fA3fEI``22Kl7zfmUXr$lbW2V6eesV!rRmQH<_yzV2>=Vv%@U9NcIu zd#75Y1aunD;gnc-g~MOb`uceNazqc6nmXwE{d;Ef*Uj;*krv4Z-_Np)NXx*l8sTwP zXYD-PoqpMj)o_ttQBHCg?$_z`IE(a;m?IF@wStrx3$oO)pL_9>11WbfmqAP#99GJ| z8q1ETN4>?)vm;@KVoLrIIEcPsXr!mRdl1kjf(kq}3^7UbMpPZcV1$vtk7HWnTU&U# z2{dM+aQ8xQFSmrzVNFd3_`W_)?QFCE3t48>0`BNyT#&vyLd&}LcI@jjbwj&O!`CKs zFcSrZg;K#|4T@`5WC^LME_4=Xj78z#h^Y?I7imJnaTnt zOTr%Y_phidy(mf2KR&Pvs8i?N!BRhzOzPW7HJ!|zob0=2y^%0o0g*&}e7bUQK^%gb zGqX&v6?&2gKh23aGcsaxi-$W!M3q?x>0!k$Bbe@TF*a%Len=YYTOu?{1CK}NVbm|vk9MeHOU!B&h4W4b3H9eb)Ns&NjLMN$ow zRHs7To#%C2_?qhhaW~n7eVF-?a%OjNGJVh9z%A|NxXKg~+RxnSDYU*m_B#8z(Iz+B zijhbR`ezSj%}vXt;^Ize3Td%{&Png=PI(H+cQbFcddnW32=FlTA?3;P0u|R;{sT#{gz6u&a$o$Jbgmhm$hG5ta#=x$IT%3y(04n<4jw=_ZvzR^tG^8GV~XY)uAy~WIfytLnI;}CvMJC74nz7#PJ zeR3yNHO`CB3TKNhRycYvK+u60_|(oikU##R4@UPa0-Gg${4#Jxe>&dBT`5v=tc2IE z1AUW1E58vigM`0Ne=9Q}T>i<~+eP+)oPh%^U)B5kmOWOONQ+Q(#=L?>Kj968OyixU zv^-8ZAOBoEut6ZF3W_+q7}4Ayt}VzJVjCW*6;4PwPmxe(7C`dIA-SIHy>)7i){yqc ze37u7?#_7eqAX3K<`uYLy$|A6}T0V#{m2G zUoo+LZtlYBP=ZNKCA_2cx}4VI6k3^qtyI{N&xq@o@HkhmZ_ekXu1IG;8U@(YjuV`TV9b@`mYN-CydE8lq{9_934UPiL1eJJZzx$|0fn7)Hu*<@k%4 z)-+4Jn9;GVGDVy$ z5tl4zK)>f;eKk;MIb29dNniicOvuI|nwxNfgoh5ww$s0d-{BT|fh=uT6|TKJ5r6(64Usbq$Twy8a3N~$}B1dTXj1+}e4kPQDrDE%v#{{P47 zMd}vD2eml0Z!U3WtuMR}Eyl9f);LvLL0^8CZ*6g%KO+QgWRkh`+ zS+oRgGlHlKw7P$*%7H9p@Q9XNcnd~zcS%&M47hIcNOK!ws?J?~+)EaEccjs11hUpC zS26CWpRn*#dXCPd9DNQw6u{EkEi#(l=e<|WfFBz{MV^2%7*j-Z8x>SuN=MnaUqq$j z$Sr=mdm30ycdhL=ag3)4!%C=yHhHE|-HFO`tPa>aU!K)l?SV{MAMF$ow~yL7pRx(0 z70}vBMH+jmssCgF)a_i|#gw|Z)-H(V=PkV2ZolJL#by{yj4#GR`bI`ht$kG&20X_r zbVB2zAo|}Tf1vGskA}j2#grJzvcZyRnrdwJchufqyS(;jPowtc{LPHDwNI>7^s=yo zuzx}?puF=G^MBE*X^Xlbt)XPz+PeRYtl~jy&BHI9tR5oz8k#9(Q3dLO=j2|eK6vQ6J?fQzd4HvGwH4@sf8FHdnvGtbR?GF*2dEAg zGUO|~1e#AWfUcXT{hY%Z! zD;H5OWuGyxZ2Dreiv8^uaQ*uRfcm-qS%z|!XXKq;mwx2EpZqO3GZm3^XKee71kkO@ Rv>$7Lk)Ek;jgC|Fe*rCbIN<;Q diff --git a/plugin/home/index.html b/plugin/home/index.html index 948a803a..89174c47 100644 --- a/plugin/home/index.html +++ b/plugin/home/index.html @@ -2,7 +2,7 @@ - + DeWeb Plugin diff --git a/plugin/home/public/favicon.png b/plugin/home/public/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..297aa0c6c30b9cf4a5e2b28526c9736747b6893a GIT binary patch literal 5032 zcmb_gXH*kix1K-md?6cNHpkxpodfP^9-BE1OGOHis1 z5dtW^DJ`KWf+AHE1ibNn>s{;K-}nC5>zwn<-gDN>?ERc)PrSLQ0gM^J3;+Pk$WZq> z0D#~$lZHZQ$O~N|0&QTz7~1*)01L-o0|D7NyfhHxcilh-s2M`8(H3C0%O;lrpgx)9 z$e95EI5drPFIxnGHs;N|INh?z+hw3d@i$ZkhPe7B8!?fO1I}5A;r6`EE}>12SAZc$ zsh4*@RV^gOF=M5OXPgsp%{|5a5ZW7Q&dXc38a^O5{$YM2 zqOEe_XLZG_ub)OTWbKK4-r}^Xkh)Hbl4vSw- znq)T!>yF6+&OAk*+>Y+ihUt={0t{t%KV#z%&7aFm7w1GGcxxl>RU}fL^6c?p&!5e@an#B;WGt?k zV?SCY+WPtgJ!g=URJFFGRKBjr(yfWztQSAI0;0vT%eMcF(b3V@ z6=#rt{Su>qZr3za{b_LQCYoZx$_hu%nT&|^O;(bbSPP6k?OfpF5B<`}_7BCrLet^v z_4`ScGHSXWa!NRS^1#NdW-MeRnndaz4PL2d3%b5C`K0N@IU_*~QFLUR4JC|@y4-c& zNd*jXaEGD%NNRnsT?ge_>5{a^fPbQdKsGxt2E7CItGlD zT01}>pL>#XEy*tviti|g8lOUFABKcdR9CZWcfH&u>#LXQ+R}h*X^^x`N zjt7;5goNeH9}5L)`*hTy(yIh-?h1_TYd zk6{jeMHh5H&1HV2M-Np*lf5ALg@J2R2M{j0=L%4O`Ja@fyp5ciYbNY^gO|6dT3M`_2CRc5;cVod~SXpSlrr^T&RYP zY2H@2nN9`XEN+VSXtkPP(g~`EpENavpxEKarVXyGuOcVgQ?Zk&yIab{8HdWQ4}>Dr`K|1@qNxV z^WcDI^y`KU8tg2JN~!4SvA)Lse(;zxF7CDd{wbtktQCAF{~=lw{>YQ7$Gf>D_!kte zBo2qbz?xQ8js_jj4K7rh)dD*mOu6*gkS$+J*R}DYFqB1 z%-Kj$*sM;o%Om9~tc?qM;A1BMoS|C4aV+tgNOs*h`|1;Y>`4>Beg#5iK zEX`{9pTOr47cBZA(e%m(yeh<3jZW$;P&ha)L5v>?pU~|DHL)Yh#xnE%Y|d-~zg^jPI+`hb9dmU~u;7Jt_yVHC~bulv77 z3v>HN@t%@86b?-NZv)3P$$Y$w5$1i59Hhkt_{MWivLk`2Q~w9s;J7oiv?TlVS*Ww% zE&abVrkh+@=~J{iyEbIkdhV9b=I^oTX~B8J*0R-bP_`ZhY)Zd4lv^q-{dx74Zt}jC z%d&6aev7g35wGTSZU>DZ`#v@bd`5|5VbNme?G%j7&NPhzApXvYS^$i_l@--}U@-lluW?G`*qV*sB}i)UjUO|0LR$((JA>G(mBR&LNsH7PsehSGn+bpw9-+g)oK}r>_VC7^Wr2?>o?QMgb z<1LR19@p-zuBUHJPEL=F?_MTy>rH1VsVQ8YZul}h@?!nx_iG@Li(rF9fA^gp9*Sxc zt|as1gno3GUqF+)<27cnTUyDk!>=8lKk%tcQCY8%yV}_{oMlfJ$(v=Sp`@lhyV9G) zan1bEqcBcO-fA3fEI``22Kl7zfmUXr$lbW2V6eesV!rRmQH<_yzV2>=Vv%@U9NcIu zd#75Y1aunD;gnc-g~MOb`uceNazqc6nmXwE{d;Ef*Uj;*krv4Z-_Np)NXx*l8sTwP zXYD-PoqpMj)o_ttQBHCg?$_z`IE(a;m?IF@wStrx3$oO)pL_9>11WbfmqAP#99GJ| z8q1ETN4>?)vm;@KVoLrIIEcPsXr!mRdl1kjf(kq}3^7UbMpPZcV1$vtk7HWnTU&U# z2{dM+aQ8xQFSmrzVNFd3_`W_)?QFCE3t48>0`BNyT#&vyLd&}LcI@jjbwj&O!`CKs zFcSrZg;K#|4T@`5WC^LME_4=Xj78z#h^Y?I7imJnaTnt zOTr%Y_phidy(mf2KR&Pvs8i?N!BRhzOzPW7HJ!|zob0=2y^%0o0g*&}e7bUQK^%gb zGqX&v6?&2gKh23aGcsaxi-$W!M3q?x>0!k$Bbe@TF*a%Len=YYTOu?{1CK}NVbm|vk9MeHOU!B&h4W4b3H9eb)Ns&NjLMN$ow zRHs7To#%C2_?qhhaW~n7eVF-?a%OjNGJVh9z%A|NxXKg~+RxnSDYU*m_B#8z(Iz+B zijhbR`ezSj%}vXt;^Ize3Td%{&Png=PI(H+cQbFcddnW32=FlTA?3;P0u|R;{sT#{gz6u&a$o$Jbgmhm$hG5ta#=x$IT%3y(04n<4jw=_ZvzR^tG^8GV~XY)uAy~WIfytLnI;}CvMJC74nz7#PJ zeR3yNHO`CB3TKNhRycYvK+u60_|(oikU##R4@UPa0-Gg${4#Jxe>&dBT`5v=tc2IE z1AUW1E58vigM`0Ne=9Q}T>i<~+eP+)oPh%^U)B5kmOWOONQ+Q(#=L?>Kj968OyixU zv^-8ZAOBoEut6ZF3W_+q7}4Ayt}VzJVjCW*6;4PwPmxe(7C`dIA-SIHy>)7i){yqc ze37u7?#_7eqAX3K<`uYLy$|A6}T0V#{m2G zUoo+LZtlYBP=ZNKCA_2cx}4VI6k3^qtyI{N&xq@o@HkhmZ_ekXu1IG;8U@(YjuV`TV9b@`mYN-CydE8lq{9_934UPiL1eJJZzx$|0fn7)Hu*<@k%4 z)-+4Jn9;GVGDVy$ z5tl4zK)>f;eKk;MIb29dNniicOvuI|nwxNfgoh5ww$s0d-{BT|fh=uT6|TKJ5r6(64Usbq$Twy8a3N~$}B1dTXj1+}e4kPQDrDE%v#{{P47 zMd}vD2eml0Z!U3WtuMR}Eyl9f);LvLL0^8CZ*6g%KO+QgWRkh`+ zS+oRgGlHlKw7P$*%7H9p@Q9XNcnd~zcS%&M47hIcNOK!ws?J?~+)EaEccjs11hUpC zS26CWpRn*#dXCPd9DNQw6u{EkEi#(l=e<|WfFBz{MV^2%7*j-Z8x>SuN=MnaUqq$j z$Sr=mdm30ycdhL=ag3)4!%C=yHhHE|-HFO`tPa>aU!K)l?SV{MAMF$ow~yL7pRx(0 z70}vBMH+jmssCgF)a_i|#gw|Z)-H(V=PkV2ZolJL#by{yj4#GR`bI`ht$kG&20X_r zbVB2zAo|}Tf1vGskA}j2#grJzvcZyRnrdwJchufqyS(;jPowtc{LPHDwNI>7^s=yo zuzx}?puF=G^MBE*X^Xlbt)XPz+PeRYtl~jy&BHI9tR5oz8k#9(Q3dLO=j2|eK6vQ6J?fQzd4HvGwH4@sf8FHdnvGtbR?GF*2dEAg zGUO|~1e#AWfUcXT{hY%Z! zD;H5OWuGyxZ2Dreiv8^uaQ*uRfcm-qS%z|!XXKq;mwx2EpZqO3GZm3^XKee71kkO@ Rv>$7Lk)Ek;jgC|Fe*rCbIN<;Q literal 0 HcmV?d00001 From b7def0d72202ff9732973b1ac5b636bad26adb0e Mon Sep 17 00:00:00 2001 From: thomas-senechal Date: Wed, 12 Mar 2025 17:46:18 +0100 Subject: [PATCH 13/57] Add default route handling --- server/int/api/plugin.go | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/server/int/api/plugin.go b/server/int/api/plugin.go index e3a8ce24..580ed3ec 100644 --- a/server/int/api/plugin.go +++ b/server/int/api/plugin.go @@ -7,6 +7,8 @@ import ( "net/http" "github.com/go-openapi/loads" + "github.com/go-openapi/runtime" + "github.com/go-openapi/runtime/middleware" "github.com/massalabs/deweb-server/api/read/restapi" "github.com/massalabs/deweb-server/api/read/restapi/operations" "github.com/massalabs/deweb-server/int/api/config" @@ -77,6 +79,10 @@ func (a *PluginAPI) configurePluginAPI() { log.Printf("ServeError: %v", err) w.WriteHeader(http.StatusInternalServerError) } + + a.dewebAPI.GetResourceHandler = operations.GetResourceHandlerFunc(getPluginResourceHandler) + a.dewebAPI.DefaultPageHandler = operations.DefaultPageHandlerFunc(getPluginDefaultPageHandler) + } // StationMiddleware handles station website serving. @@ -111,3 +117,19 @@ func StationMiddleware(handler http.Handler, homePageZip []byte, conf *config.Se localHandler(w, homePageZip, path) }) } + +func getPluginResourceHandler(params operations.GetResourceParams) middleware.Responder { + return middleware.ResponderFunc(func(w http.ResponseWriter, _ runtime.Producer) { + logger.Debugf("getPluginResourceHandler: redirecting to plugin") + + http.Redirect(w, params.HTTPRequest, "https://station.massa/plugin/massa-labs/deweb-plugin", http.StatusSeeOther) + }) +} + +func getPluginDefaultPageHandler(params operations.DefaultPageParams) middleware.Responder { + return middleware.ResponderFunc(func(w http.ResponseWriter, _ runtime.Producer) { + logger.Debugf("getPluginDefaultPageHandler: redirecting to plugin") + + http.Redirect(w, params.HTTPRequest, "https://station.massa/plugin/massa-labs/deweb-plugin", http.StatusSeeOther) + }) +} From 4db1affb85e7f452d33bf74e1d72f325c07fcf53 Mon Sep 17 00:00:00 2001 From: thomas-senechal Date: Wed, 12 Mar 2025 18:13:40 +0100 Subject: [PATCH 14/57] Remove unnecessary blank line in configurePluginAPI function --- server/int/api/plugin.go | 1 - 1 file changed, 1 deletion(-) diff --git a/server/int/api/plugin.go b/server/int/api/plugin.go index 580ed3ec..971c1c5e 100644 --- a/server/int/api/plugin.go +++ b/server/int/api/plugin.go @@ -82,7 +82,6 @@ func (a *PluginAPI) configurePluginAPI() { a.dewebAPI.GetResourceHandler = operations.GetResourceHandlerFunc(getPluginResourceHandler) a.dewebAPI.DefaultPageHandler = operations.DefaultPageHandlerFunc(getPluginDefaultPageHandler) - } // StationMiddleware handles station website serving. From d61d5fd6df266de5720d5e6d7d9e04df5e4b6cc7 Mon Sep 17 00:00:00 2001 From: thomas-senechal Date: Wed, 12 Mar 2025 18:23:37 +0100 Subject: [PATCH 15/57] Update GitHub Actions workflow to include additional plugin files in artifact upload --- .github/workflows/build.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7504a1e3..3d6f8d5e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -146,5 +146,9 @@ jobs: - name: Upload Plugin artifact uses: actions/upload-artifact@v4 with: - name: deweb-plugin_${{ matrix.target }}_${{ matrix.arch }} - path: plugin/build/deweb-plugin_${{ matrix.target }}_${{ matrix.arch }}${{ matrix.ext }} + name: deweb_plugin_${{ matrix.target }}_${{ matrix.arch }} + path: | + plugin/build/deweb-plugin_${{ matrix.target }}_${{ matrix.arch }}${{ matrix.ext }} + plugin/favicon.png + plugin/manifest.json + From 8b7b57f6d0016fd550861441b7649443a3f3846e Mon Sep 17 00:00:00 2001 From: thomas-senechal Date: Wed, 12 Mar 2025 18:30:57 +0100 Subject: [PATCH 16/57] Update ubuntu to 22.04 in build workflow --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3d6f8d5e..c962c479 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -86,10 +86,10 @@ jobs: arch: amd64 target: windows ext: .exe - - os: ubuntu-20.04 + - os: ubuntu-22.04 arch: amd64 target: linux - - os: ubuntu-20.04 + - os: ubuntu-22.04 arch: arm64 target: linux - os: macos-13 From 0933d6123f0beb20bf011a3cd6e7eedd18c87260 Mon Sep 17 00:00:00 2001 From: thomas-senechal Date: Wed, 12 Mar 2025 18:31:11 +0100 Subject: [PATCH 17/57] Fix artifact naming and path in GitHub Actions build workflow --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c962c479..c0e91461 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -141,14 +141,14 @@ jobs: ARCH: ${{ matrix.arch }} - name: Rename Plugin artifact - run: mv build/deweb-plugin${{ matrix.ext }} build/deweb-plugin_${{ matrix.target }}_${{ matrix.arch }}${{ matrix.ext }} + run: mv build/deweb-plugin${{ matrix.ext }} deweb-plugin_${{ matrix.target }}_${{ matrix.arch }}${{ matrix.ext }} - name: Upload Plugin artifact uses: actions/upload-artifact@v4 with: name: deweb_plugin_${{ matrix.target }}_${{ matrix.arch }} path: | - plugin/build/deweb-plugin_${{ matrix.target }}_${{ matrix.arch }}${{ matrix.ext }} + plugin/deweb-plugin_${{ matrix.target }}_${{ matrix.arch }}${{ matrix.ext }} plugin/favicon.png plugin/manifest.json From bef2f76385723c590a3ed6f573e382984ad97f1f Mon Sep 17 00:00:00 2001 From: thomas-senechal Date: Thu, 13 Mar 2025 17:30:42 +0100 Subject: [PATCH 18/57] Add network info fetching and enhance UI in App component --- plugin/home/src/App.tsx | 98 +++++++++++++++++++++++++++++++++------- server/int/api/plugin.go | 18 +++++++- 2 files changed, 98 insertions(+), 18 deletions(-) diff --git a/plugin/home/src/App.tsx b/plugin/home/src/App.tsx index 9d19e5b5..23ee1a6b 100644 --- a/plugin/home/src/App.tsx +++ b/plugin/home/src/App.tsx @@ -1,12 +1,15 @@ -import { FiSearch } from "react-icons/fi"; +import { FiSearch, FiGlobe, FiUpload, FiHash, FiInfo } from "react-icons/fi"; import { useEffect, useState } from "react"; import { GenerateTheme } from "deweb-pages/src/hooks/GenerateTheme"; export default function App() { const [searchQuery, setSearchQuery] = useState(""); const [port, setPort] = useState(""); + const [networkName, setNetworkName] = useState(null); + const [networkVersion, setNetworkVersion] = useState(null); + const [loading, setLoading] = useState(true); - // On mount, get the port from the API by hitting /port + // On mount, get the port from the API by hitting /port and network info from /info useEffect(() => { const url = window.location.href.endsWith("/") ? window.location.href @@ -14,22 +17,37 @@ export default function App() { fetch(`${url}port`) .then((res) => res.text()) - .then((port) => setPort(port)); + .then((port) => setPort(port)) + .catch(err => console.error("Failed to fetch port:", err)); + + fetch(`${url}info`) + .then((res) => res.json()) + .then((info) => { + setNetworkName(info.Network || "Unknown Network"); + setNetworkVersion(info.Version || "Unknown Version"); + setLoading(false); + }) + .catch(err => { + console.error("Failed to fetch provider info:", err); + setNetworkName("Unknown Network"); + setNetworkVersion("Unknown Version"); + setLoading(false); + }); }, []); - // Redirect the user to the requested website. - // If the user is on `station.massa`..., we redirect to localhost:{port} - // Otherwise, we redirect to {searchQuery}.{host} (very likely dev mode) - const handleSearch = (e: React.FormEvent) => { - e.preventDefault(); + const redirectTo = (service: string) => { const { host } = new URL(window.location.href); if (host === "station.massa") { - // We have to force http because the plugin has a random localhost address and port - const redirectUrl = `http://${searchQuery}.localhost:${port}`; - window.location.href = redirectUrl; + window.location.href = `http://${service}.localhost:${port}`; } else { - const redirectUrl = `//${searchQuery}.${host}`; - window.location.href = redirectUrl; + window.location.href = `//${service}.${host}`; + } + }; + + const handleSearch = (e: React.FormEvent) => { + e.preventDefault(); + if (searchQuery.trim()) { + redirectTo(searchQuery); } }; @@ -37,23 +55,69 @@ export default function App() { return (
-

Search on DeWeb

+ {/* Network Status Indicator */} +
+ + {loading ? "Connecting..." : `Connected to ${networkName} ${networkVersion}`} +
+ +

Search on DeWeb

setSearchQuery(e.target.value)} - className="px-3 py-2 text-primary w-full bg-secondary outline-none placeholder-primary" + className="px-3 py-3 text-primary w-full bg-secondary outline-none placeholder-primary" placeholder="Enter domain" /> .massa + +

Quick Access

+ +
+ {/* DeWeb Homepage Card */} +
redirectTo('deweb')} + className="bg-secondary text-primary p-6 rounded-lg shadow-lg cursor-pointer hover:bg-opacity-90 transition-all" + > +
+ +
+

DeWeb

+

Search for websites and browse the list of websites uploaded on DeWeb

+
+ + {/* MNS Card */} +
redirectTo('mns')} + className="bg-secondary text-primary p-6 rounded-lg shadow-lg cursor-pointer hover:bg-opacity-90 transition-all" + > +
+ +
+

Massa Name System

+

Decentralized naming service for users and smart contracts on the Massa blockchain

+
+ + {/* DeWeb Uploader Card */} +
redirectTo('dws')} + className="bg-secondary text-primary p-6 rounded-lg shadow-lg cursor-pointer hover:bg-opacity-90 transition-all" + > +
+ +
+

DeWeb Uploader

+

Upload and manage your websites on DeWeb

+
+
); } diff --git a/server/int/api/plugin.go b/server/int/api/plugin.go index 971c1c5e..9ec619a3 100644 --- a/server/int/api/plugin.go +++ b/server/int/api/plugin.go @@ -1,6 +1,7 @@ package api import ( + "encoding/json" "fmt" "log" "net" @@ -99,7 +100,6 @@ func StationMiddleware(handler http.Handler, homePageZip []byte, conf *config.Se path := cleanPath(r.URL.Path) - // FIXME: Following if is a hack. We should make a clean API for the plugin if path == "port" { w.WriteHeader(http.StatusOK) @@ -111,6 +111,22 @@ func StationMiddleware(handler http.Handler, homePageZip []byte, conf *config.Se return } + if path == "info" { + w.WriteHeader(http.StatusOK) + + json, err := json.Marshal(conf.NetworkInfos) + if err != nil { + logger.Errorf("Failed to marshal network infos: %v", err) + } + + _, err = w.Write(json) + if err != nil { + logger.Errorf("Failed to write info: %v", err) + } + + return + } + logger.Debugf("StationMiddleware: Serving station.massa plugin page") localHandler(w, homePageZip, path) From 012e90a2fe552c9506728bcaf6b7849ea846a79c Mon Sep 17 00:00:00 2001 From: thomas-senechal Date: Thu, 13 Mar 2025 17:31:01 +0100 Subject: [PATCH 19/57] Remove useless public/ from favicon path in home index.html --- plugin/home/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin/home/index.html b/plugin/home/index.html index 89174c47..6ab080e8 100644 --- a/plugin/home/index.html +++ b/plugin/home/index.html @@ -2,7 +2,7 @@ - + DeWeb Plugin From c2f0d0913ee8da9b605470da103e6d71d6f36bc7 Mon Sep 17 00:00:00 2001 From: thomas-senechal Date: Thu, 13 Mar 2025 17:31:16 +0100 Subject: [PATCH 20/57] Set mainnet as default for deweb plugin --- plugin/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin/main.go b/plugin/main.go index cc1d0d0f..c89855d4 100644 --- a/plugin/main.go +++ b/plugin/main.go @@ -34,7 +34,7 @@ func main() { conf := config.ServerConfig{ APIPort: 0, Domain: "localhost", - NetworkInfos: pkgConfig.NewNetworkConfig("https://buildnet.massa.net/api/v2"), + NetworkInfos: pkgConfig.NewNetworkConfig("https://mainnet.massa.net/api/v2"), CacheDir: filepath.Join(pluginDir, "websiteCache"), } From 242953179c3067925ceb09d8ac9fc08a148908d3 Mon Sep 17 00:00:00 2001 From: thomas-senechal Date: Thu, 13 Mar 2025 18:27:15 +0100 Subject: [PATCH 21/57] Fix artifact naming convention in GitHub Actions build workflow --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c0e91461..8bf3bb87 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -146,7 +146,7 @@ jobs: - name: Upload Plugin artifact uses: actions/upload-artifact@v4 with: - name: deweb_plugin_${{ matrix.target }}_${{ matrix.arch }} + name: deweb-plugin_${{ matrix.target }}_${{ matrix.arch }} path: | plugin/deweb-plugin_${{ matrix.target }}_${{ matrix.arch }}${{ matrix.ext }} plugin/favicon.png From 51dabc35ebe27546c70485af5e9f60d7df4b3918 Mon Sep 17 00:00:00 2001 From: thomas-senechal Date: Fri, 14 Mar 2025 17:45:44 +0100 Subject: [PATCH 22/57] Add config file handling for DeWeb plugin --- plugin/config/config.go | 89 +++++++++++++++++++++++++++++++++++++++++ plugin/go.mod | 2 +- plugin/main.go | 23 ++++++++--- 3 files changed, 108 insertions(+), 6 deletions(-) create mode 100644 plugin/config/config.go diff --git a/plugin/config/config.go b/plugin/config/config.go new file mode 100644 index 00000000..c58289f0 --- /dev/null +++ b/plugin/config/config.go @@ -0,0 +1,89 @@ +package config + +import ( + "fmt" + "os" + "path/filepath" + + "gopkg.in/yaml.v3" +) + +const ( + DefaultNetworkURL = "https://mainnet.massa.net/api/v2" + DefaultCacheDir = "websiteCache" + ConfigFileName = "config.yaml" +) + +// PluginConfig represents the configuration for the DeWeb plugin +type PluginConfig struct { + APIPort int `yaml:"api_port"` + NetworkURL string `yaml:"network_url"` + CacheDir string `yaml:"cache_dir"` +} + +// LoadConfig loads the configuration from a YAML file +// It falls back to default values if the file doesn't exist or if values are missing +func LoadConfig(pluginDir string) (PluginConfig, error) { + config := PluginConfig{ + APIPort: 0, // Default port (0 means a random port will be assigned by OS) + NetworkURL: DefaultNetworkURL, + CacheDir: filepath.Join(pluginDir, DefaultCacheDir), + } + + configPath := filepath.Join(pluginDir, ConfigFileName) + fileConfig, err := loadFromFile(configPath) + if err != nil { + return config, fmt.Errorf("using default configuration: %w", err) + } + + mergeConfig(fileConfig, &config, pluginDir) + return config, nil +} + +// loadFromFile attempts to load config from a file +// Returns the loaded config and an error if loading failed +func loadFromFile(configPath string) (PluginConfig, error) { + var pluginConfig PluginConfig + + // Check if config file exists + _, err := os.Stat(configPath) + if os.IsNotExist(err) { + return pluginConfig, fmt.Errorf("config file not found at %s", configPath) + } else if err != nil { + return pluginConfig, fmt.Errorf("error checking config file: %w", err) + } + + // Read config file + yamlFile, err := os.ReadFile(configPath) + if err != nil { + return pluginConfig, fmt.Errorf("error reading config file: %w", err) + } + + // Parse YAML + err = yaml.Unmarshal(yamlFile, &pluginConfig) + if err != nil { + return pluginConfig, fmt.Errorf("error parsing config file: %w", err) + } + + return pluginConfig, nil +} + +// mergeConfig applies non-empty values from source to target +// Handles both absolute and relative paths for CacheDir +func mergeConfig(source PluginConfig, target *PluginConfig, pluginDir string) { + if source.APIPort != 0 { + target.APIPort = source.APIPort + } + + if source.NetworkURL != "" { + target.NetworkURL = source.NetworkURL + } + + if source.CacheDir != "" { + if filepath.IsAbs(source.CacheDir) { + target.CacheDir = source.CacheDir + } else { + target.CacheDir = filepath.Join(pluginDir, source.CacheDir) + } + } +} diff --git a/plugin/go.mod b/plugin/go.mod index 694ff4d8..1d9c9492 100644 --- a/plugin/go.mod +++ b/plugin/go.mod @@ -7,6 +7,7 @@ replace github.com/massalabs/deweb-server => ../server require ( github.com/massalabs/deweb-server v0.0.0 github.com/massalabs/station v0.6.5 + gopkg.in/yaml.v3 v3.0.1 ) require ( @@ -50,7 +51,6 @@ require ( golang.org/x/sys v0.29.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect howett.net/plist v1.0.0 // indirect lukechampine.com/blake3 v1.1.7 // indirect ) diff --git a/plugin/main.go b/plugin/main.go index c89855d4..1b94e1d4 100644 --- a/plugin/main.go +++ b/plugin/main.go @@ -7,6 +7,7 @@ import ( "os" "path/filepath" + pluginConfig "github.com/massalabs/deweb-plugin/config" "github.com/massalabs/deweb-server/int/api" "github.com/massalabs/deweb-server/int/api/config" pkgConfig "github.com/massalabs/deweb-server/pkg/config" @@ -31,14 +32,26 @@ func main() { log.Fatalf("failed to initialize logger: %v", err) } - conf := config.ServerConfig{ - APIPort: 0, + // Load configuration from YAML file with fallback to defaults + conf, err := pluginConfig.LoadConfig(pluginDir) + if err != nil { + logger.Warnf("%v", err) + } + + // Convert PluginConfig to ServerConfig + serverConfig := config.ServerConfig{ + APIPort: conf.APIPort, Domain: "localhost", - NetworkInfos: pkgConfig.NewNetworkConfig("https://mainnet.massa.net/api/v2"), - CacheDir: filepath.Join(pluginDir, "websiteCache"), + NetworkInfos: pkgConfig.NewNetworkConfig(conf.NetworkURL), + CacheDir: conf.CacheDir, } - api := api.NewPluginAPI(&conf, homeZip) + logger.Infof("Starting DeWeb plugin with configuration:") + logger.Infof(" API Port: %d", serverConfig.APIPort) + logger.Infof(" Network URL: %s", serverConfig.NetworkInfos.NodeURL) + logger.Infof(" Cache Directory: %s", serverConfig.CacheDir) + + api := api.NewPluginAPI(&serverConfig, homeZip) api.Start() } From 36ef4e7fc6c4456ec85823d8bbf8ff89eeb18cc4 Mon Sep 17 00:00:00 2001 From: thomas-senechal Date: Mon, 17 Mar 2025 16:41:08 +0100 Subject: [PATCH 23/57] Apply review suggestions --- plugin/Taskfile.yml | 2 +- plugin/home/src/App.tsx | 18 +++++++++++------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/plugin/Taskfile.yml b/plugin/Taskfile.yml index 22b4f3f6..308f2a06 100644 --- a/plugin/Taskfile.yml +++ b/plugin/Taskfile.yml @@ -11,7 +11,7 @@ tasks: run: cmds: - - cmd: go run ./main.go + - cmd: ./build/deweb-plugin build: cmds: diff --git a/plugin/home/src/App.tsx b/plugin/home/src/App.tsx index 23ee1a6b..23a462ea 100644 --- a/plugin/home/src/App.tsx +++ b/plugin/home/src/App.tsx @@ -25,23 +25,22 @@ export default function App() { .then((info) => { setNetworkName(info.Network || "Unknown Network"); setNetworkVersion(info.Version || "Unknown Version"); - setLoading(false); }) .catch(err => { console.error("Failed to fetch provider info:", err); setNetworkName("Unknown Network"); setNetworkVersion("Unknown Version"); + }).finally(() => { setLoading(false); }); }, []); const redirectTo = (service: string) => { const { host } = new URL(window.location.href); - if (host === "station.massa") { - window.location.href = `http://${service}.localhost:${port}`; - } else { - window.location.href = `//${service}.${host}`; - } + const url = host === "station.massa" && port + ? `http://${service}.localhost:${port}` + : `//${service}.${host}`; + window.open(url, '_blank'); }; const handleSearch = (e: React.FormEvent) => { @@ -68,7 +67,12 @@ export default function App() { onSubmit={handleSearch} className="flex items-center overflow-hidden w-full md:w-2/3 lg:w-1/2 xl:w-1/3 bg-secondary rounded-lg shadow-lg mb-8" > - + Date: Tue, 18 Mar 2025 17:43:56 +0100 Subject: [PATCH 24/57] Add missing font --- plugin/home/index.html | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/plugin/home/index.html b/plugin/home/index.html index 6ab080e8..4f7e5dfe 100644 --- a/plugin/home/index.html +++ b/plugin/home/index.html @@ -1,13 +1,25 @@ - - - - - DeWeb Plugin - - -
- - - + + + + + + DeWeb Plugin + + + + + + + + + + +
+ + + + \ No newline at end of file From 9696c00a3a21c89254e02ff7571820bc3674a164 Mon Sep 17 00:00:00 2001 From: thomas-senechal Date: Tue, 18 Mar 2025 17:44:10 +0100 Subject: [PATCH 25/57] Apply UI/UX review suggestions --- plugin/home/src/App.tsx | 103 +++++++++++++++++++++++----------------- 1 file changed, 60 insertions(+), 43 deletions(-) diff --git a/plugin/home/src/App.tsx b/plugin/home/src/App.tsx index 23a462ea..4254154c 100644 --- a/plugin/home/src/App.tsx +++ b/plugin/home/src/App.tsx @@ -1,7 +1,29 @@ -import { FiSearch, FiGlobe, FiUpload, FiHash, FiInfo } from "react-icons/fi"; +import { FiSearch, FiInfo } from "react-icons/fi"; import { useEffect, useState } from "react"; import { GenerateTheme } from "deweb-pages/src/hooks/GenerateTheme"; +type QuickAccessItemProps = { + path: string; + title: string; + description: string; + href: string; +}; + +const QuickAccessItem = ({ path, title, description, href }: QuickAccessItemProps) => ( + +
+ {path} +
+

{title}

+

{description}

+
+); + export default function App() { const [searchQuery, setSearchQuery] = useState(""); const [port, setPort] = useState(""); @@ -35,21 +57,42 @@ export default function App() { }); }, []); - const redirectTo = (service: string) => { + const generateUrl = (service: string, path: string = '') => { const { host } = new URL(window.location.href); - const url = host === "station.massa" && port - ? `http://${service}.localhost:${port}` - : `//${service}.${host}`; - window.open(url, '_blank'); + return host === "station.massa" && port + ? `http://${service}.localhost:${port}${path}` + : `//${service}.${host}${path}`; }; const handleSearch = (e: React.FormEvent) => { e.preventDefault(); if (searchQuery.trim()) { - redirectTo(searchQuery); + window.open(generateUrl(searchQuery), '_blank'); } }; + const quickAccessItems = [ + { + path: "/explore", + title: "Explore DeWeb", + description: "Browse the list of all websites available in the decentralized web ecosystem", + service: "deweb", + pathUrl: "/explore" + }, + { + path: "/mns", + title: "Massa Name System", + description: "Decentralized naming service for users and smart contracts on the Massa blockchain", + service: "mns" + }, + { + path: "/upload", + title: "DeWeb Uploader", + description: "Upload and manage your websites on DeWeb", + service: "dws" + } + ]; + const theme = GenerateTheme(); return ( @@ -83,44 +126,18 @@ export default function App() { .massa -

Quick Access

+

Quick Access

- {/* DeWeb Homepage Card */} -
redirectTo('deweb')} - className="bg-secondary text-primary p-6 rounded-lg shadow-lg cursor-pointer hover:bg-opacity-90 transition-all" - > -
- -
-

DeWeb

-

Search for websites and browse the list of websites uploaded on DeWeb

-
- - {/* MNS Card */} -
redirectTo('mns')} - className="bg-secondary text-primary p-6 rounded-lg shadow-lg cursor-pointer hover:bg-opacity-90 transition-all" - > -
- -
-

Massa Name System

-

Decentralized naming service for users and smart contracts on the Massa blockchain

-
- - {/* DeWeb Uploader Card */} -
redirectTo('dws')} - className="bg-secondary text-primary p-6 rounded-lg shadow-lg cursor-pointer hover:bg-opacity-90 transition-all" - > -
- -
-

DeWeb Uploader

-

Upload and manage your websites on DeWeb

-
+ {quickAccessItems.map((item) => ( + + ))}
); From 07e5d4e6080ba14b494ac221e2db051f274692ba Mon Sep 17 00:00:00 2001 From: thomas-senechal Date: Tue, 18 Mar 2025 17:50:10 +0100 Subject: [PATCH 26/57] Update DeWeb plugin home page README.md --- plugin/home/README.md | 115 +++++++++++++++++++++++------------------- 1 file changed, 64 insertions(+), 51 deletions(-) diff --git a/plugin/home/README.md b/plugin/home/README.md index 40ede56e..1605a64d 100644 --- a/plugin/home/README.md +++ b/plugin/home/README.md @@ -1,54 +1,67 @@ -# React + TypeScript + Vite - -This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. - -Currently, two official plugins are available: - -- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh -- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh - -## Expanding the ESLint configuration - -If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules: - -```js -export default tseslint.config({ - extends: [ - // Remove ...tseslint.configs.recommended and replace with this - ...tseslint.configs.recommendedTypeChecked, - // Alternatively, use this for stricter rules - ...tseslint.configs.strictTypeChecked, - // Optionally, add this for stylistic rules - ...tseslint.configs.stylisticTypeChecked, - ], - languageOptions: { - // other options... - parserOptions: { - project: ['./tsconfig.node.json', './tsconfig.app.json'], - tsconfigRootDir: import.meta.dirname, - }, - }, -}) +# DeWeb Plugin Homepage + +This is the homepage for the DeWeb plugin, providing a central navigation hub and search interface for the decentralized web ecosystem on Massa. + +## Features + +- Search for DeWeb domains +- Quick access to key DeWeb services: + - Explore DeWeb: Browse available decentralized websites + - Massa Name System (MNS): Manage decentralized domain names + - DeWeb Uploader: Upload and manage websites +- Network status indicator showing connection info + +## Development + +### Prerequisites + +- Node.js (v18+) +- npm or yarn + +### Setup + +```bash +# Install dependencies +npm install + +# Run development server +npm run dev ``` -You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules: - -```js -// eslint.config.js -import reactX from 'eslint-plugin-react-x' -import reactDom from 'eslint-plugin-react-dom' - -export default tseslint.config({ - plugins: { - // Add the react-x and react-dom plugins - 'react-x': reactX, - 'react-dom': reactDom, - }, - rules: { - // other rules... - // Enable its recommended typescript rules - ...reactX.configs['recommended-typescript'].rules, - ...reactDom.configs.recommended.rules, - }, -}) +The development server will start at http://localhost:5173 (or another port if 5173 is in use). + +### Project Structure + +- `src/` - Source code + - `App.tsx` - Main application component +- `public/` - Static assets + +## Building for Production + +```bash +# Build the project +npm run build + +# Build and package for plugin deployment +npm run build:plugin ``` + +The `build:plugin` command will: +1. Build the project +2. Create a zip file (`dist/home.zip`) for deployment + +## Dependencies + +This project uses: +- React 19 +- TypeScript +- Vite +- TailwindCSS for styling +- React Icons +- DeWeb Pages (local dependency) + +## Integration + +This homepage is designed to work with the DeWeb plugin for Massa. It communicates with the plugin's API endpoints to retrieve network information and port configurations. + +The application dynamically generates URLs based on the current environment (development or production) to ensure proper navigation between different DeWeb services. From ea8c2d2c368eddbd3c1c3f08d9ae1b7a9b46954f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20S=C3=A9n=C3=A9chal?= <44696378+thomas-senechal@users.noreply.github.com> Date: Thu, 20 Mar 2025 11:08:09 +0100 Subject: [PATCH 27/57] Refacto workflows (#261) * Disable old workflows * Divide build and release workflow into a server and a plugin workflow * Add missing task generate * Add CLI workflow * Update plugin release workflow to use new artifact path for zip files * Add job needs in plugin release workflows * Remove obsolete GitHub workflows for build, linting, and testing * Apply CR comments --- .github/workflows/{tests.yml => cli.yml} | 50 +++---- .github/workflows/lint.yml | 76 ---------- .github/workflows/plugin-release.yml | 93 ++++++++++++ .github/workflows/{build.yml => plugin.yml} | 111 +++++++-------- .../{release.yml => server-release.yml} | 51 ++++--- .github/workflows/server.yml | 133 ++++++++++++++++++ 6 files changed, 322 insertions(+), 192 deletions(-) rename .github/workflows/{tests.yml => cli.yml} (66%) delete mode 100644 .github/workflows/lint.yml create mode 100644 .github/workflows/plugin-release.yml rename .github/workflows/{build.yml => plugin.yml} (53%) rename .github/workflows/{release.yml => server-release.yml} (53%) create mode 100644 .github/workflows/server.yml diff --git a/.github/workflows/tests.yml b/.github/workflows/cli.yml similarity index 66% rename from .github/workflows/tests.yml rename to .github/workflows/cli.yml index c58ab778..518f0acb 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/cli.yml @@ -1,38 +1,40 @@ -name: tests +name: CLI on: push: branches: [main] + paths: + - 'cli/**' + - '.github/workflows/cli.yml' pull_request: - workflow_call: + paths: + - 'cli/**' + - '.github/workflows/cli.yml' + workflow_dispatch: jobs: - test-server: - runs-on: ubuntu-22.04 - + lint: + runs-on: ubuntu-latest defaults: run: - working-directory: ./server - + working-directory: ./cli steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: installing dependencies - uses: ./.github/actions/install + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - - - name: Run unit tests - run: go test ./... + node-version: 20 + cache: "npm" + cache-dependency-path: ./cli/package-lock.json + - name: Install dependencies + run: npm ci + - name: Run code formatting and linting + run: npm run fmt:check - test-cli: + test: runs-on: ubuntu-22.04 - defaults: run: working-directory: ./cli - steps: - name: Checkout repository uses: actions/checkout@v4 @@ -40,19 +42,17 @@ jobs: with: node-version: 20 cache: "npm" - cache-dependency-path: ./server/pages/package-lock.json + cache-dependency-path: ./cli/package-lock.json - name: Install dependencies run: npm ci - name: Run unit tests run: npm test - functional-test-cli: + functional-test: runs-on: ubuntu-22.04 - defaults: run: working-directory: ./cli - steps: - name: Checkout repository uses: actions/checkout@v4 @@ -60,7 +60,7 @@ jobs: with: node-version: 20 cache: "npm" - cache-dependency-path: ./server/pages/package-lock.json + cache-dependency-path: ./cli/package-lock.json - name: Install dependencies run: npm ci - name: Setup wallet @@ -76,4 +76,4 @@ jobs: npm run build npm run start -- upload -y --wallet ./wallet_fullpower.yaml --password $WALLET_TEST_PASSWORD ../smart-contract/src/e2e/test-project/dist env: - WALLET_TEST_PASSWORD: ${{ secrets.WALLET_TEST_PASSWORD }} + WALLET_TEST_PASSWORD: ${{ secrets.WALLET_TEST_PASSWORD }} \ No newline at end of file diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml deleted file mode 100644 index 3734bab9..00000000 --- a/.github/workflows/lint.yml +++ /dev/null @@ -1,76 +0,0 @@ -name: Lint - -on: - push: - branches: [main] - pull_request: - -jobs: - lint-server: - runs-on: ubuntu-latest - - defaults: - run: - working-directory: ./server - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: installing dependencies - uses: ./.github/actions/install - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - - - name: run golangci-lint - uses: golangci/golangci-lint-action@v6 - with: - version: v1.64 - args: --timeout=3m - working-directory: ./server - - - name: install gofumpt - run: go install mvdan.cc/gofumpt@latest - - - name: run gofumpt - run: | - ERRORS=$(gofumpt -l . | wc -l) - if [[ "$ERRORS" != "0" ]]; then - echo "following files are not gofumpted:" - gofumpt -l . - exit 1 - fi - - lint-cli: - runs-on: ubuntu-latest - defaults: - run: - working-directory: ./cli - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 - with: - node-version: 20 - cache: "npm" - cache-dependency-path: ./cli/package-lock.json - - name: Install dependencies - run: npm ci - - name: Run code formating and linting - run: npm run fmt:check - - lint-frontend: - runs-on: ubuntu-latest - defaults: - run: - working-directory: ./server/pages - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 - with: - node-version: 20 - cache: "npm" - cache-dependency-path: ./server/pages/package-lock.json - - name: Install dependencies - run: npm ci - - name: Run code formating and linting - run: npm run lint:check diff --git a/.github/workflows/plugin-release.yml b/.github/workflows/plugin-release.yml new file mode 100644 index 00000000..6414932c --- /dev/null +++ b/.github/workflows/plugin-release.yml @@ -0,0 +1,93 @@ +name: Plugin Release + +on: + workflow_dispatch: + inputs: + version: + description: 'Plugin version for this release (without v prefix)' + required: true + type: string + release-as-draft: + description: "Whether it's a draft or not" + required: true + type: boolean + default: true + release-as-prerelease: + description: "Whether it's a prerelease or not" + required: true + type: boolean + default: false + generate-release-notes: + description: "Generate release notes" + required: true + type: boolean + default: true + +jobs: + check-manifest: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Check the manifest version + working-directory: ./plugin + run: | + sudo apt-get install -y jq + version=$(jq -r '.version' manifest.json) + input_version=${{ inputs.version }} + if [[ "$version" != "$input_version" ]]; then + echo "ERROR: The manifest version ($version) does not match the input version ($input_version)" + exit 1 + fi + echo "Manifest version matches input version: $version" + + build-plugin: + uses: ./.github/workflows/plugin.yml + needs: check-manifest + with: + version: ${{ inputs.version }} + secrets: inherit + + create-release: + needs: [check-manifest, build-plugin] + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - name: Download all artifacts + uses: actions/download-artifact@v4 + with: + path: artifacts + pattern: 'deweb-plugin_*' + + - name: List artifacts + run: ls -R artifacts + + - name: Create zip packages for each platform + run: | + mkdir -p release_zips + + # Find all artifact folders + for platform_dir in artifacts/deweb-plugin_*; do + # Extract the platform name from the directory + platform_name=$(basename "$platform_dir") + + # Create a zip package for this platform + (cd "$platform_dir" && zip -r "../../release_zips/${platform_name}.zip" *) + + echo "Created zip package for $platform_name" + done + + ls -la release_zips/ + + - name: Create Release + uses: softprops/action-gh-release@v2 + with: + tag_name: plugin-v${{ inputs.version }} + name: plugin v${{ inputs.version }} + draft: ${{ inputs.release-as-draft }} + prerelease: ${{ inputs.release-as-prerelease }} + generate_release_notes: ${{ inputs.generate-release-notes }} + files: | + release_zips/*.zip diff --git a/.github/workflows/build.yml b/.github/workflows/plugin.yml similarity index 53% rename from .github/workflows/build.yml rename to .github/workflows/plugin.yml index 8bf3bb87..814e284d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/plugin.yml @@ -1,84 +1,67 @@ -name: build and upload artifacts +name: Plugin on: push: branches: [main] + paths: + - 'plugin/**' + - 'server/**' + - '.github/workflows/plugin.yml' pull_request: + paths: + - 'plugin/**' + - 'server/**' + - '.github/workflows/plugin.yml' workflow_dispatch: workflow_call: inputs: - tag_name: + version: type: string - description: "The tag name of the release without v prefix" + description: "Version for the build, without v prefix" + required: false env: - VERSION: ${{ inputs.tag_name }} + VERSION: ${{ inputs.version }} jobs: - build: - name: build and upload artifacts - strategy: - matrix: - include: - - os: windows-2022 - arch: amd64 - target: windows - ext: .exe - - os: ubuntu-22.04 - arch: amd64 - target: linux - - os: ubuntu-22.04 - arch: arm64 - target: linux - - os: macos-13 - arch: amd64 - target: darwin - - os: macos-14 - arch: arm64 - target: darwin - - runs-on: ${{ matrix.os }} - + lint: + runs-on: ubuntu-latest defaults: run: - working-directory: ./server - + working-directory: ./plugin steps: - name: Checkout repository uses: actions/checkout@v4 - - name: installing dependencies + - name: Installing dependencies uses: ./.github/actions/install with: - os: ${{ matrix.os }} repo-token: ${{ secrets.GITHUB_TOKEN }} - - name: Check if VERSION exists - shell: bash - id: check_version - run: | - if [ ! -z "${{ env.VERSION }}" ]; then - echo "PRODUCTION=true" >> $GITHUB_ENV - fi + - name: Task generate + run: task generate - - name: Build Server - shell: bash - run: task build - env: - OS: ${{ matrix.target }} - ARCH: ${{ matrix.arch }} + - name: Run golangci-lint + uses: golangci/golangci-lint-action@v6 + with: + version: v1.59 + args: --timeout=3m + working-directory: ./plugin - - name: Rename Server artifact - run: mv build/deweb-server${{ matrix.ext }} build/deweb-server_${{ matrix.target }}_${{ matrix.arch }}${{ matrix.ext }} + - name: Install gofumpt + run: go install mvdan.cc/gofumpt@v0.7.0 - - name: Upload Server artifact - uses: actions/upload-artifact@v4 - with: - name: deweb-server_${{ matrix.target }}_${{ matrix.arch }} - path: server/build/deweb-server_${{ matrix.target }}_${{ matrix.arch }}${{ matrix.ext }} + - name: Run gofumpt + run: | + ERRORS=$(gofumpt -l . | wc -l) + if [[ "$ERRORS" != "0" ]]; then + echo "following files are not gofumpted:" + gofumpt -l . + exit 1 + fi - build-plugin: - name: build and upload plugin artifact + build: + name: Build plugin strategy: matrix: include: @@ -100,16 +83,14 @@ jobs: target: darwin runs-on: ${{ matrix.os }} - defaults: run: working-directory: ./plugin - steps: - name: Checkout repository uses: actions/checkout@v4 - - name: installing dependencies + - name: Installing dependencies uses: ./.github/actions/install with: os: ${{ matrix.os }} @@ -118,12 +99,10 @@ jobs: - name: Install Plugin Go Dependencies run: task install shell: bash - working-directory: ./plugin - name: Go Generate Plugin run: task generate shell: bash - working-directory: ./plugin - name: Check if VERSION exists shell: bash @@ -143,12 +122,16 @@ jobs: - name: Rename Plugin artifact run: mv build/deweb-plugin${{ matrix.ext }} deweb-plugin_${{ matrix.target }}_${{ matrix.arch }}${{ matrix.ext }} + - name: Copy shared files to platform directory + shell: bash + run: | + mkdir -p platform_${{ matrix.target }}_${{ matrix.arch }} + cp deweb-plugin_${{ matrix.target }}_${{ matrix.arch }}${{ matrix.ext }} platform_${{ matrix.target }}_${{ matrix.arch }}/ + cp favicon.png platform_${{ matrix.target }}_${{ matrix.arch }}/ + cp manifest.json platform_${{ matrix.target }}_${{ matrix.arch }}/ + - name: Upload Plugin artifact uses: actions/upload-artifact@v4 with: name: deweb-plugin_${{ matrix.target }}_${{ matrix.arch }} - path: | - plugin/deweb-plugin_${{ matrix.target }}_${{ matrix.arch }}${{ matrix.ext }} - plugin/favicon.png - plugin/manifest.json - + path: plugin/platform_${{ matrix.target }}_${{ matrix.arch }}/ \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/server-release.yml similarity index 53% rename from .github/workflows/release.yml rename to .github/workflows/server-release.yml index 8245b8c7..f96f7e7b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/server-release.yml @@ -1,10 +1,10 @@ -name: Release workflow +name: Server Release on: workflow_dispatch: inputs: - tag_name: - description: "Version to produce" + version: + description: 'Server version for this release (without v prefix)' required: true type: string release-as-draft: @@ -22,39 +22,36 @@ on: required: true type: boolean default: true - + jobs: - validate-input: - name: if tag_name is provided it must not start with "v" - runs-on: ubuntu-latest - steps: - - name: Check if tag_name starts with "v" - run: | - if [[ "${{ github.event.inputs.tag_name }}" == v* ]]; then - echo "tag_name starts with v" - exit 1 - fi - - build-release: - needs: validate-input - uses: ./.github/workflows/build.yml - secrets: inherit + build-server: + uses: ./.github/workflows/server.yml with: - tag_name: ${{ github.event.inputs.tag_name }} + version: ${{ inputs.version }} + secrets: inherit create-release: - name: Release - needs: build-release - + needs: build-server runs-on: ubuntu-latest + permissions: + contents: write steps: - - uses: actions/download-artifact@v4 - - name: Create release and upload binaries + - name: Download all server artifacts + uses: actions/download-artifact@v4 + with: + path: artifacts + pattern: 'deweb-server_*' + + - name: List artifacts + run: ls -R artifacts + + - name: Create Release uses: softprops/action-gh-release@v2 with: - tag_name: v${{ inputs.tag_name }} + tag_name: v${{ inputs.version }} + name: server v${{ inputs.version }} draft: ${{ inputs.release-as-draft }} prerelease: ${{ inputs.release-as-prerelease }} generate_release_notes: ${{ inputs.generate-release-notes }} files: | - ./deweb-*/deweb-* + artifacts/deweb-server_*/deweb-server_* diff --git a/.github/workflows/server.yml b/.github/workflows/server.yml new file mode 100644 index 00000000..dd9946f2 --- /dev/null +++ b/.github/workflows/server.yml @@ -0,0 +1,133 @@ +name: Server + +on: + push: + branches: [main] + paths: + - 'server/**' + - '.github/workflows/server.yml' + pull_request: + paths: + - 'server/**' + - '.github/workflows/server.yml' + workflow_dispatch: + workflow_call: + inputs: + version: + type: string + description: "Version for the build, without v prefix" + required: false + +env: + VERSION: ${{ inputs.version }} + +jobs: + lint: + runs-on: ubuntu-latest + defaults: + run: + working-directory: ./server + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Installing dependencies + uses: ./.github/actions/install + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + + - name: Run golangci-lint + uses: golangci/golangci-lint-action@v6 + with: + version: v1.59 + args: --timeout=3m + working-directory: ./server + + - name: Install gofumpt + run: go install mvdan.cc/gofumpt@v0.7.0 + + - name: Run gofumpt + run: | + ERRORS=$(gofumpt -l . | wc -l) + if [[ "$ERRORS" != "0" ]]; then + echo "following files are not gofumpted:" + gofumpt -l . + exit 1 + fi + + test: + runs-on: ubuntu-22.04 + defaults: + run: + working-directory: ./server + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Installing dependencies + uses: ./.github/actions/install + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + + - name: Run unit tests + run: go test ./... + + build: + name: Build server + strategy: + matrix: + include: + - os: windows-2022 + arch: amd64 + target: windows + ext: .exe + - os: ubuntu-22.04 + arch: amd64 + target: linux + - os: ubuntu-22.04 + arch: arm64 + target: linux + - os: macos-13 + arch: amd64 + target: darwin + - os: macos-14 + arch: arm64 + target: darwin + + runs-on: ${{ matrix.os }} + defaults: + run: + working-directory: ./server + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Installing dependencies + uses: ./.github/actions/install + with: + os: ${{ matrix.os }} + repo-token: ${{ secrets.GITHUB_TOKEN }} + + - name: Check if VERSION exists + shell: bash + id: check_version + run: | + if [ ! -z "${{ env.VERSION }}" ]; then + echo "PRODUCTION=true" >> $GITHUB_ENV + fi + + - name: Build Server + shell: bash + run: task build + env: + OS: ${{ matrix.target }} + ARCH: ${{ matrix.arch }} + + - name: Rename Server artifact + run: mv build/deweb-server${{ matrix.ext }} build/deweb-server_${{ matrix.target }}_${{ matrix.arch }}${{ matrix.ext }} + + - name: Upload Server artifact + uses: actions/upload-artifact@v4 + with: + name: deweb-server_${{ matrix.target }}_${{ matrix.arch }} + path: server/build/deweb-server_${{ matrix.target }}_${{ matrix.arch }}${{ matrix.ext }} \ No newline at end of file From 21fc0cf5f3bcede5c4e74dbf934e54e1e88a4495 Mon Sep 17 00:00:00 2001 From: thomas-senechal Date: Tue, 1 Apr 2025 16:30:33 +0200 Subject: [PATCH 28/57] Update plugin go.mod --- plugin/go.mod | 22 +++++++-- plugin/go.sum | 127 ++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 142 insertions(+), 7 deletions(-) diff --git a/plugin/go.mod b/plugin/go.mod index 1d9c9492..e84aaaa2 100644 --- a/plugin/go.mod +++ b/plugin/go.mod @@ -1,6 +1,8 @@ module github.com/massalabs/deweb-plugin -go 1.22 +go 1.23 + +toolchain go1.24.0 replace github.com/massalabs/deweb-server => ../server @@ -15,8 +17,13 @@ require ( github.com/awnumar/memcall v0.1.2 // indirect github.com/awnumar/memguard v0.22.3 // indirect github.com/btcsuite/btcutil v1.0.2 // indirect + github.com/cespare/xxhash v1.1.0 // indirect + github.com/cespare/xxhash/v2 v2.1.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect + github.com/dgraph-io/badger/v3 v3.2103.5 // indirect + github.com/dgraph-io/ristretto v0.1.1 // indirect github.com/docker/go-units v0.5.0 // indirect + github.com/dustin/go-humanize v1.0.0 // indirect github.com/go-openapi/analysis v0.23.0 // indirect github.com/go-openapi/errors v0.22.0 // indirect github.com/go-openapi/jsonpointer v0.21.0 // indirect @@ -27,21 +34,30 @@ require ( github.com/go-openapi/strfmt v0.23.0 // indirect github.com/go-openapi/swag v0.23.0 // indirect github.com/go-openapi/validate v0.24.0 // indirect - github.com/gofrs/flock v0.12.1 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b // indirect + github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 // indirect + github.com/golang/protobuf v1.3.1 // indirect + github.com/golang/snappy v0.0.3 // indirect + github.com/google/flatbuffers v1.12.1 // indirect github.com/google/uuid v1.6.0 // indirect + github.com/hashicorp/golang-lru v1.0.2 // indirect github.com/jessevdk/go-flags v1.6.1 // indirect github.com/josharian/intern v1.0.0 // indirect + github.com/klauspost/compress v1.13.6 // indirect github.com/klauspost/cpuid/v2 v2.1.0 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/massalabs/station-massa-hello-world v0.0.11-0.20240503070604-6b14a27fcdff // indirect github.com/massalabs/station-massa-wallet v0.4.5 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/oklog/ulid v1.3.1 // indirect + github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/shopspring/decimal v1.3.1 // indirect - github.com/stretchr/testify v1.9.0 // indirect + github.com/stretchr/testify v1.10.0 // indirect github.com/ybbus/jsonrpc/v3 v3.1.4 // indirect go.mongodb.org/mongo-driver v1.14.0 // indirect + go.opencensus.io v0.22.5 // indirect go.uber.org/atomic v1.10.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.24.0 // indirect diff --git a/plugin/go.sum b/plugin/go.sum index b07a03f1..8f39580f 100644 --- a/plugin/go.sum +++ b/plugin/go.sum @@ -1,4 +1,9 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/awnumar/memcall v0.1.2 h1:7gOfDTL+BJ6nnbtAp9+HQzUFjtP1hEseRQq8eP055QY= @@ -17,11 +22,29 @@ github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVa github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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/dgraph-io/badger/v3 v3.2103.5 h1:ylPa6qzbjYRQMU6jokoj4wzcaweHylt//CH0AKt0akg= +github.com/dgraph-io/badger/v3 v3.2103.5/go.mod h1:4MPiseMeDQ3FNCYwRbbcBOGJLf5jsE0PPFzRiKjtcdw= +github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8= +github.com/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkzgwUve0VDWWA= +github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA= +github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/go-openapi/analysis v0.23.0 h1:aGday7OWupfMs+LbmLZG4k0MYXIANxcuBTYUC03zFCU= github.com/go-openapi/analysis v0.23.0/go.mod h1:9mz9ZWaSlV8TvjQHLl2mUW2PbZtemkE8yA5v22ohupo= @@ -43,14 +66,31 @@ github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+Gr github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= github.com/go-openapi/validate v0.24.0 h1:LdfDKwNbpB6Vn40xhTdNZAnfLECL81w+VX3BumrGD58= github.com/go-openapi/validate v0.24.0/go.mod h1:iyeX1sEufmv3nPbBdX3ieNviWnOZaJ1+zquzJEf2BAQ= -github.com/gofrs/flock v0.12.1 h1:MTLVXXHf8ekldpJk3AKicLij9MdwOWkZ+a/jHHZby9E= -github.com/gofrs/flock v0.12.1/go.mod h1:9zxTsyu5xtJ9DK+1tFZyibEV7y3uwDxPPfbxeeHCoD0= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 h1:ZgQEtGgCBiWRM39fZuwSd1LwSqqSW0hOdXCYYDX0R3I= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/snappy v0.0.3 h1:fHPg5GQYlCeLIPB9BZqMVR5nR9A+IM5zcgeTdjMYmLA= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/flatbuffers v1.12.1 h1:MVlul7pQNoDzWRLTw5imwYsl+usrS1TXG2H4jg6ImGw= +github.com/google/flatbuffers v1.12.1/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c= +github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.6.1 h1:Cvu5U8UGrLay1rZfv/zP7iLpSHGUZ/Ou68T0iX1bBK4= @@ -58,14 +98,23 @@ github.com/jessevdk/go-flags v1.6.1/go.mod h1:Mk8T1hIAWpOiJiHa9rJASDK2UGWji0EuPG 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/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= +github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc= +github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.1.0 h1:eyi1Ad2aNJMW95zcSbmGg7Cg6cq3ADwLpMAP96d8rF0= github.com/klauspost/cpuid/v2 v2.1.0/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= 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/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/massalabs/station v0.6.5 h1:lkWWYB0/dPsRHSoAqN0wh/mFx8+InsVGMfraXQFZ76U= @@ -74,6 +123,8 @@ github.com/massalabs/station-massa-hello-world v0.0.11-0.20240503070604-6b14a27f github.com/massalabs/station-massa-hello-world v0.0.11-0.20240503070604-6b14a27fcdff/go.mod h1:QbRHQvJFrm4mO+vPzr4Uiwa5REL/CgBlV4PDFdhewa0= github.com/massalabs/station-massa-wallet v0.4.5 h1:0rTHxGPlJ5cKjgB/yQclOBHbWiZO5rOwO0lT7ZjFuVQ= github.com/massalabs/station-massa-wallet v0.4.5/go.mod h1:Eu6Zlijs0uAuGM5CxEUOxFrcIlWtuZVAbiWPCUni9XY= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= @@ -81,22 +132,42 @@ github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 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.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= +github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= +github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= -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.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +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 v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/ybbus/jsonrpc/v3 v3.1.4 h1:pPmgfWXnqR2GdIlealyCzmV6LV3nxm3w9gwA1B3cP3Y= github.com/ybbus/jsonrpc/v3 v3.1.4/go.mod h1:4HQTl0UzErqWGa6bSXhp8rIjifMAMa55E4D5wdhe768= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.mongodb.org/mongo-driver v1.14.0 h1:P98w8egYRjYe3XDjxhYJagTokP/H6HzlsnojRgZRd80= go.mongodb.org/mongo-driver v1.14.0/go.mod h1:Vzb0Mk/pa7e6cWw85R4F/endUC3u0U9jGcNU603k65c= +go.opencensus.io v0.22.5 h1:dntmOdLpSpHlVqbW5Eay97DelsZHe+55D+xC6i0dDS0= +go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= @@ -106,26 +177,72 @@ go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN8 go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 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.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/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/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= @@ -134,10 +251,12 @@ gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYs gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0/go.mod h1:WDnlLJ4WF5VGsH/HVa3CI79GS0ol3YnhVnKP89i0kNg= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= howett.net/plist v1.0.0 h1:7CrbWYbPPO/PyNy38b2EB/+gYbjCe2DXBxgtOOZbSQM= howett.net/plist v1.0.0/go.mod h1:lqaXoTrLY4hg8tnEzNru53gicrbv7rrk+2xJA/7hw9g= lukechampine.com/blake3 v1.1.7 h1:GgRMhmdsuK8+ii6UZFDL8Nb+VyMwadAgcJyfYHxG6n0= From a3023a5ef23e9ab7df12071c22af5f6bb8b5315b Mon Sep 17 00:00:00 2001 From: thomas-senechal Date: Tue, 1 Apr 2025 16:40:51 +0200 Subject: [PATCH 29/57] Update golangci-lint version to v1.64 in GitHub workflows --- .github/workflows/plugin.yml | 2 +- .github/workflows/server.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/plugin.yml b/.github/workflows/plugin.yml index 814e284d..f316f238 100644 --- a/.github/workflows/plugin.yml +++ b/.github/workflows/plugin.yml @@ -44,7 +44,7 @@ jobs: - name: Run golangci-lint uses: golangci/golangci-lint-action@v6 with: - version: v1.59 + version: v1.64 args: --timeout=3m working-directory: ./plugin diff --git a/.github/workflows/server.yml b/.github/workflows/server.yml index dd9946f2..d5e766bd 100644 --- a/.github/workflows/server.yml +++ b/.github/workflows/server.yml @@ -39,7 +39,7 @@ jobs: - name: Run golangci-lint uses: golangci/golangci-lint-action@v6 with: - version: v1.59 + version: v1.64 args: --timeout=3m working-directory: ./server From 7ac05df938c5c60338da659e4c355e7b6ac3ef1b Mon Sep 17 00:00:00 2001 From: thomas-senechal Date: Thu, 3 Apr 2025 15:58:35 +0200 Subject: [PATCH 30/57] Move cache init at API init --- server/int/api/api.go | 4 +++ server/int/api/plugin.go | 53 ++++++++++++++++++++-------------------- 2 files changed, 30 insertions(+), 27 deletions(-) diff --git a/server/int/api/api.go b/server/int/api/api.go index 7e37e8ac..4377f3cc 100644 --- a/server/int/api/api.go +++ b/server/int/api/api.go @@ -24,6 +24,10 @@ const ( mnsCacheKey mnsCacheKeyType = "mnsCache" ) +type cacheKeyType string + +const cacheKey cacheKeyType = "cache" + type API struct { Conf *config.ServerConfig APIServer *restapi.Server diff --git a/server/int/api/plugin.go b/server/int/api/plugin.go index 9ec619a3..27f8d26b 100644 --- a/server/int/api/plugin.go +++ b/server/int/api/plugin.go @@ -7,10 +7,8 @@ import ( "net" "net/http" - "github.com/go-openapi/loads" "github.com/go-openapi/runtime" "github.com/go-openapi/runtime/middleware" - "github.com/massalabs/deweb-server/api/read/restapi" "github.com/massalabs/deweb-server/api/read/restapi/operations" "github.com/massalabs/deweb-server/int/api/config" "github.com/massalabs/station-massa-hello-world/pkg/plugin" @@ -18,71 +16,72 @@ import ( ) type PluginAPI struct { - conf *config.ServerConfig - apiServer *restapi.Server - dewebAPI *operations.DeWebAPI - homeZip []byte + *API + homeZip []byte } func NewPluginAPI(conf *config.ServerConfig, homeZip []byte) *PluginAPI { - swaggerSpec, err := loads.Analyzed(restapi.SwaggerJSON, "") - if err != nil { - log.Fatalln(err) - } - - dewebAPI := operations.NewDeWebAPI(swaggerSpec) - server := restapi.NewServer(dewebAPI) + baseAPI := NewAPI(conf) return &PluginAPI{ - conf: conf, - apiServer: server, - dewebAPI: dewebAPI, - homeZip: homeZip, + API: baseAPI, + homeZip: homeZip, } } +// createHandler overrides the base API's createHandler to add StationMiddleware +func (a *PluginAPI) createHandler() http.Handler { + baseHandler := a.API.createHandler() + return StationMiddleware(baseHandler, a.homeZip, a.Conf) +} + // Start starts the API server. func (a *PluginAPI) Start() { defer func() { - if err := a.apiServer.Shutdown(); err != nil { + if a.Cache != nil { + a.Cache.Close() + } + + if err := a.APIServer.Shutdown(); err != nil { log.Fatalln(err) } }() - a.apiServer.Port = a.conf.APIPort + a.APIServer.Port = a.Conf.APIPort a.configurePluginAPI() - a.apiServer.ConfigureAPI() + a.APIServer.ConfigureAPI() - a.apiServer.SetHandler(StationMiddleware(SubdomainMiddleware(a.dewebAPI.Serve(nil), a.conf), a.homeZip, a.conf)) + // Set handler using the createHandler method + a.APIServer.SetHandler(a.createHandler()) - listener, err := a.apiServer.HTTPListener() + listener, err := a.APIServer.HTTPListener() if err != nil { logger.Fatalf("Failed to get HTTP listener: %v", err) } // We get the port from the listener in case the port was set to 0 and the OS assigned a port - a.conf.APIPort = listener.Addr().(*net.TCPAddr).Port + a.Conf.APIPort = listener.Addr().(*net.TCPAddr).Port if err := plugin.RegisterPlugin(listener); err != nil { logger.Fatalf("Failed to register plugin: %v", err) } - if err := a.apiServer.Serve(); err != nil { + if err := a.APIServer.Serve(); err != nil { log.Fatalln(err) } } // ConfigureAPI sets up the API handlers and error handling. func (a *PluginAPI) configurePluginAPI() { - a.dewebAPI.ServeError = func(w http.ResponseWriter, r *http.Request, err error) { + a.DewebAPI.ServeError = func(w http.ResponseWriter, r *http.Request, err error) { log.Printf("ServeError: %v", err) w.WriteHeader(http.StatusInternalServerError) } - a.dewebAPI.GetResourceHandler = operations.GetResourceHandlerFunc(getPluginResourceHandler) - a.dewebAPI.DefaultPageHandler = operations.DefaultPageHandlerFunc(getPluginDefaultPageHandler) + a.DewebAPI.GetResourceHandler = operations.GetResourceHandlerFunc(getPluginResourceHandler) + a.DewebAPI.DefaultPageHandler = operations.DefaultPageHandlerFunc(getPluginDefaultPageHandler) } // StationMiddleware handles station website serving. From 51b59ee9eeaaef0fd53f785ef9e1053ec24ed596 Mon Sep 17 00:00:00 2001 From: thomas-senechal Date: Thu, 3 Apr 2025 16:00:09 +0200 Subject: [PATCH 31/57] Update plugin config structure to use CacheConfig object --- plugin/config/config.go | 43 ++++++++++++++++++++++++++--------------- plugin/go.mod | 4 ++-- plugin/main.go | 4 ++-- 3 files changed, 31 insertions(+), 20 deletions(-) diff --git a/plugin/config/config.go b/plugin/config/config.go index c58289f0..d269db60 100644 --- a/plugin/config/config.go +++ b/plugin/config/config.go @@ -5,7 +5,8 @@ import ( "os" "path/filepath" - "gopkg.in/yaml.v3" + apiConfig "github.com/massalabs/deweb-server/int/api/config" + "gopkg.in/yaml.v2" ) const ( @@ -16,9 +17,15 @@ const ( // PluginConfig represents the configuration for the DeWeb plugin type PluginConfig struct { - APIPort int `yaml:"api_port"` - NetworkURL string `yaml:"network_url"` - CacheDir string `yaml:"cache_dir"` + APIPort int + NetworkURL string + CacheConfig apiConfig.CacheConfig +} + +type YamlPluginConfig struct { + APIPort *int `yaml:"api_port"` + NetworkURL string `yaml:"network_url"` + CacheConfig apiConfig.YamlCacheConfig `yaml:"cache"` } // LoadConfig loads the configuration from a YAML file @@ -27,7 +34,12 @@ func LoadConfig(pluginDir string) (PluginConfig, error) { config := PluginConfig{ APIPort: 0, // Default port (0 means a random port will be assigned by OS) NetworkURL: DefaultNetworkURL, - CacheDir: filepath.Join(pluginDir, DefaultCacheDir), + CacheConfig: apiConfig.CacheConfig{ + DiskCacheDir: filepath.Join(pluginDir, DefaultCacheDir), + SiteRAMCacheMaxItems: apiConfig.DefaultMaxRAMUsageMB, + SiteDiskCacheMaxItems: apiConfig.DefaultMaxDiskUsageMB, + FileListCacheDurationSeconds: apiConfig.DefaultFileListCachePeriod, + }, } configPath := filepath.Join(pluginDir, ConfigFileName) @@ -42,8 +54,8 @@ func LoadConfig(pluginDir string) (PluginConfig, error) { // loadFromFile attempts to load config from a file // Returns the loaded config and an error if loading failed -func loadFromFile(configPath string) (PluginConfig, error) { - var pluginConfig PluginConfig +func loadFromFile(configPath string) (YamlPluginConfig, error) { + var pluginConfig YamlPluginConfig // Check if config file exists _, err := os.Stat(configPath) @@ -70,20 +82,19 @@ func loadFromFile(configPath string) (PluginConfig, error) { // mergeConfig applies non-empty values from source to target // Handles both absolute and relative paths for CacheDir -func mergeConfig(source PluginConfig, target *PluginConfig, pluginDir string) { - if source.APIPort != 0 { - target.APIPort = source.APIPort +func mergeConfig(source YamlPluginConfig, target *PluginConfig, pluginDir string) { + if source.APIPort != nil { + target.APIPort = *source.APIPort } if source.NetworkURL != "" { target.NetworkURL = source.NetworkURL } - if source.CacheDir != "" { - if filepath.IsAbs(source.CacheDir) { - target.CacheDir = source.CacheDir - } else { - target.CacheDir = filepath.Join(pluginDir, source.CacheDir) - } + cacheConfig := apiConfig.ConvertYamlCacheConfig(&source.CacheConfig) + target.CacheConfig = cacheConfig + + if !filepath.IsAbs(target.CacheConfig.DiskCacheDir) { + target.CacheConfig.DiskCacheDir = filepath.Join(pluginDir, target.CacheConfig.DiskCacheDir) } } diff --git a/plugin/go.mod b/plugin/go.mod index e84aaaa2..6286f611 100644 --- a/plugin/go.mod +++ b/plugin/go.mod @@ -9,7 +9,7 @@ replace github.com/massalabs/deweb-server => ../server require ( github.com/massalabs/deweb-server v0.0.0 github.com/massalabs/station v0.6.5 - gopkg.in/yaml.v3 v3.0.1 + gopkg.in/yaml.v2 v2.4.0 ) require ( @@ -66,7 +66,7 @@ require ( golang.org/x/sync v0.10.0 // indirect golang.org/x/sys v0.29.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect howett.net/plist v1.0.0 // indirect lukechampine.com/blake3 v1.1.7 // indirect ) diff --git a/plugin/main.go b/plugin/main.go index 1b94e1d4..6125a946 100644 --- a/plugin/main.go +++ b/plugin/main.go @@ -43,13 +43,13 @@ func main() { APIPort: conf.APIPort, Domain: "localhost", NetworkInfos: pkgConfig.NewNetworkConfig(conf.NetworkURL), - CacheDir: conf.CacheDir, + CacheConfig: conf.CacheConfig, } logger.Infof("Starting DeWeb plugin with configuration:") logger.Infof(" API Port: %d", serverConfig.APIPort) logger.Infof(" Network URL: %s", serverConfig.NetworkInfos.NodeURL) - logger.Infof(" Cache Directory: %s", serverConfig.CacheDir) + logger.Infof(" Cache Directory: %s", serverConfig.CacheConfig.DiskCacheDir) api := api.NewPluginAPI(&serverConfig, homeZip) api.Start() From 98e09ad095ff733e9beed5f5951f4384f5b357e9 Mon Sep 17 00:00:00 2001 From: thomas-senechal Date: Thu, 3 Apr 2025 16:04:16 +0200 Subject: [PATCH 32/57] Fix misnamed variables in config --- plugin/config/config.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugin/config/config.go b/plugin/config/config.go index d269db60..90ba9d92 100644 --- a/plugin/config/config.go +++ b/plugin/config/config.go @@ -36,8 +36,8 @@ func LoadConfig(pluginDir string) (PluginConfig, error) { NetworkURL: DefaultNetworkURL, CacheConfig: apiConfig.CacheConfig{ DiskCacheDir: filepath.Join(pluginDir, DefaultCacheDir), - SiteRAMCacheMaxItems: apiConfig.DefaultMaxRAMUsageMB, - SiteDiskCacheMaxItems: apiConfig.DefaultMaxDiskUsageMB, + SiteRAMCacheMaxItems: apiConfig.DefaultMaxRAMItems, + SiteDiskCacheMaxItems: apiConfig.DefaultMaxDiskItems, FileListCacheDurationSeconds: apiConfig.DefaultFileListCachePeriod, }, } From 70c572956184a2e3f94cd0edf5528a9e412313a4 Mon Sep 17 00:00:00 2001 From: thomas-senechal Date: Thu, 3 Apr 2025 16:05:39 +0200 Subject: [PATCH 33/57] Add example configuration file for DeWeb plugin --- plugin/config.yaml.example | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 plugin/config.yaml.example diff --git a/plugin/config.yaml.example b/plugin/config.yaml.example new file mode 100644 index 00000000..930e0f98 --- /dev/null +++ b/plugin/config.yaml.example @@ -0,0 +1,24 @@ +# DeWeb plugin Configuration + +# Network node URL to connect to (default: "https://mainnet.massa.net/api/v2") +network_node_url: "https://mainnet.massa.net/api/v2" + +# API port to listen on (default: 0) +api_port: 0 + +# Cache configuration +cache: + # Whether caching is enabled (default: true) + enabled: true + + # Maximum number of files stored in RAM cache (default: 1000) + site_ram_cache_max_items: 1000 + + # Maximum number of files stored in disk cache (default: 10000) + site_disk_cache_max_items: 10000 + + # Directory to store the disk cache (default: "./websitesCache/") + disk_cache_dir: "./websitesCache/" + + # Duration in seconds for file list cache (default: 60s) + file_list_cache_duration_seconds: 60 From b556c5ff40d0e8c282ec762f0d5ae7571720303a Mon Sep 17 00:00:00 2001 From: thomas-senechal Date: Thu, 3 Apr 2025 16:15:26 +0200 Subject: [PATCH 34/57] audit fix server pages and plugin home --- plugin/home/package-lock.json | 40 +++++++++++++++++------------------ 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/plugin/home/package-lock.json b/plugin/home/package-lock.json index 3365820c..86ca6e8e 100644 --- a/plugin/home/package-lock.json +++ b/plugin/home/package-lock.json @@ -255,27 +255,27 @@ } }, "node_modules/@babel/helpers": { - "version": "7.26.9", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.9.tgz", - "integrity": "sha512-Mz/4+y8udxBKdmzt/UjPACs4G3j5SshJJEFFKxlCGPydG4JAHXxjWjAwjd09tf6oINvl1VfMJo+nB7H2YKQ0dA==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.0.tgz", + "integrity": "sha512-U5eyP/CTFPuNE3qk+WZMxFkp/4zUzdceQlfzf7DdGdhp+Fezd7HD+i8Y24ZuTMKX3wQBld449jijbGq6OdGNQg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/template": "^7.26.9", - "@babel/types": "^7.26.9" + "@babel/template": "^7.27.0", + "@babel/types": "^7.27.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/parser": { - "version": "7.26.9", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.9.tgz", - "integrity": "sha512-81NWa1njQblgZbQHxWHpxxCzNsa3ZwvFqpUg7P+NNUU6f3UU2jBEg4OlF/J6rl8+PQGh1q6/zWScd001YwcA5A==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.0.tgz", + "integrity": "sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.26.9" + "@babel/types": "^7.27.0" }, "bin": { "parser": "bin/babel-parser.js" @@ -317,15 +317,15 @@ } }, "node_modules/@babel/template": { - "version": "7.26.9", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.26.9.tgz", - "integrity": "sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.0.tgz", + "integrity": "sha512-2ncevenBqXI6qRMukPlXwHKHchC7RyMuu4xv5JBXRfOGVcTy1mXCD12qrp7Jsoxll1EV3+9sE4GugBVRjT2jFA==", "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.26.2", - "@babel/parser": "^7.26.9", - "@babel/types": "^7.26.9" + "@babel/parser": "^7.27.0", + "@babel/types": "^7.27.0" }, "engines": { "node": ">=6.9.0" @@ -361,9 +361,9 @@ } }, "node_modules/@babel/types": { - "version": "7.26.9", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.9.tgz", - "integrity": "sha512-Y3IR1cRnOxOCDvMmNiym7XpXQ93iGDDPHx+Zj+NM+rg0fBaShfQLkg+hKPaZCEvg5N/LeCo4+Rj/i3FuJsIQaw==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.0.tgz", + "integrity": "sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg==", "dev": true, "license": "MIT", "dependencies": { @@ -4821,9 +4821,9 @@ "license": "MIT" }, "node_modules/vite": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/vite/-/vite-6.2.1.tgz", - "integrity": "sha512-n2GnqDb6XPhlt9B8olZPrgMD/es/Nd1RdChF6CBD/fHW6pUyUTt2sQW2fPRX5GiD9XEa6+8A6A4f2vT6pSsE7Q==", + "version": "6.2.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.2.5.tgz", + "integrity": "sha512-j023J/hCAa4pRIUH6J9HemwYfjB5llR2Ps0CWeikOtdR8+pAURAk0DoJC5/mm9kd+UgdnIy7d6HE4EAvlYhPhA==", "dev": true, "license": "MIT", "dependencies": { From 0a9e69de38fdd357efc3bce1ffd739ae42738f07 Mon Sep 17 00:00:00 2001 From: thomas-senechal Date: Thu, 3 Apr 2025 16:26:10 +0200 Subject: [PATCH 35/57] Fix plugin build --- plugin/home/package-lock.json | 966 +++++++++++++--------------------- plugin/home/src/App.tsx | 4 +- 2 files changed, 361 insertions(+), 609 deletions(-) diff --git a/plugin/home/package-lock.json b/plugin/home/package-lock.json index 86ca6e8e..f7a3397e 100644 --- a/plugin/home/package-lock.json +++ b/plugin/home/package-lock.json @@ -33,8 +33,10 @@ } }, "../../server/pages": { + "name": "pages", "version": "0.0.0", "dependencies": { + "@massalabs/massa-web3": "^5.1.2-dev", "react": "^18.3.1", "react-dom": "^18.3.1", "react-icons": "^5.3.0", @@ -62,9 +64,6 @@ "vite-plugin-svgr": "^4.2.0" } }, - "../server/pages": { - "extraneous": true - }, "node_modules/@alloc/quick-lru": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", @@ -118,22 +117,22 @@ } }, "node_modules/@babel/core": { - "version": "7.26.9", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.9.tgz", - "integrity": "sha512-lWBYIrF7qK5+GjY5Uy+/hEgp8OJWOD/rpy74GplYRhEauvbHDeFB8t5hPOZxCZ0Oxf4Cc36tK51/l3ymJysrKw==", + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.10.tgz", + "integrity": "sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ==", "dev": true, "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.26.2", - "@babel/generator": "^7.26.9", + "@babel/generator": "^7.26.10", "@babel/helper-compilation-targets": "^7.26.5", "@babel/helper-module-transforms": "^7.26.0", - "@babel/helpers": "^7.26.9", - "@babel/parser": "^7.26.9", + "@babel/helpers": "^7.26.10", + "@babel/parser": "^7.26.10", "@babel/template": "^7.26.9", - "@babel/traverse": "^7.26.9", - "@babel/types": "^7.26.9", + "@babel/traverse": "^7.26.10", + "@babel/types": "^7.26.10", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -149,14 +148,14 @@ } }, "node_modules/@babel/generator": { - "version": "7.26.9", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.9.tgz", - "integrity": "sha512-kEWdzjOAUMW4hAyrzJ0ZaTOu9OmpyDIQicIh0zg0EEcEkYXZb2TjtBhnHi2ViX7PKwZqF4xwqfAm299/QMP3lg==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.27.0.tgz", + "integrity": "sha512-VybsKvpiN1gU1sdMZIp7FcqphVVKEwcuj02x73uvcHE0PTihx1nlBcowYWhDwjpoAXRv43+gDzyggGnn1XZhVw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/parser": "^7.26.9", - "@babel/types": "^7.26.9", + "@babel/parser": "^7.27.0", + "@babel/types": "^7.27.0", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^3.0.2" @@ -166,13 +165,13 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.26.5", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.26.5.tgz", - "integrity": "sha512-IXuyn5EkouFJscIDuFF5EsiSolseme1s0CZB+QxVugqJLYmKdxI1VfIBOst0SUu4rnk2Z7kqTwmoO1lp3HIfnA==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.0.tgz", + "integrity": "sha512-LVk7fbXml0H2xH34dFzKQ7TDZ2G4/rVTOrq9V+icbbadjbVxxeFeDsNHv2SrZeWoA+6ZiTyWYWtScEIW07EAcA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.26.5", + "@babel/compat-data": "^7.26.8", "@babel/helper-validator-option": "^7.25.9", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", @@ -332,17 +331,17 @@ } }, "node_modules/@babel/traverse": { - "version": "7.26.9", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.9.tgz", - "integrity": "sha512-ZYW7L+pL8ahU5fXmNbPF+iZFHCv5scFak7MZ9bwaRPLUhHh7QQEMjZUg0HevihoqCM5iSYHN61EyCoZvqC+bxg==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.27.0.tgz", + "integrity": "sha512-19lYZFzYVQkkHkl4Cy4WrAVcqBkgvV2YM2TU3xG6DIwO7O3ecbDPfW3yM3bjAGcqcQHi+CCtjMR3dIEHxsd6bA==", "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.26.2", - "@babel/generator": "^7.26.9", - "@babel/parser": "^7.26.9", - "@babel/template": "^7.26.9", - "@babel/types": "^7.26.9", + "@babel/generator": "^7.27.0", + "@babel/parser": "^7.27.0", + "@babel/template": "^7.27.0", + "@babel/types": "^7.27.0", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -375,9 +374,9 @@ } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.1.tgz", - "integrity": "sha512-kfYGy8IdzTGy+z0vFGvExZtxkFlA4zAxgKEahG9KE1ScBjpQnFsNOX8KTU5ojNru5ed5CVoJYXFtoxaq5nFbjQ==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.2.tgz", + "integrity": "sha512-wCIboOL2yXZym2cgm6mlA742s9QeJ8DjGVaL39dLN4rRwrOgOyYSnOaFPhKZGLb2ngj4EyfAFjsNJwPXZvseag==", "cpu": [ "ppc64" ], @@ -392,9 +391,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.1.tgz", - "integrity": "sha512-dp+MshLYux6j/JjdqVLnMglQlFu+MuVeNrmT5nk6q07wNhCdSnB7QZj+7G8VMUGh1q+vj2Bq8kRsuyA00I/k+Q==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.2.tgz", + "integrity": "sha512-NQhH7jFstVY5x8CKbcfa166GoV0EFkaPkCKBQkdPJFvo5u+nGXLEH/ooniLb3QI8Fk58YAx7nsPLozUWfCBOJA==", "cpu": [ "arm" ], @@ -409,9 +408,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.1.tgz", - "integrity": "sha512-50tM0zCJW5kGqgG7fQ7IHvQOcAn9TKiVRuQ/lN0xR+T2lzEFvAi1ZcS8DiksFcEpf1t/GYOeOfCAgDHFpkiSmA==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.2.tgz", + "integrity": "sha512-5ZAX5xOmTligeBaeNEPnPaeEuah53Id2tX4c2CVP3JaROTH+j4fnfHCkr1PjXMd78hMst+TlkfKcW/DlTq0i4w==", "cpu": [ "arm64" ], @@ -426,9 +425,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.1.tgz", - "integrity": "sha512-GCj6WfUtNldqUzYkN/ITtlhwQqGWu9S45vUXs7EIYf+7rCiiqH9bCloatO9VhxsL0Pji+PF4Lz2XXCES+Q8hDw==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.2.tgz", + "integrity": "sha512-Ffcx+nnma8Sge4jzddPHCZVRvIfQ0kMsUsCMcJRHkGJ1cDmhe4SsrYIjLUKn1xpHZybmOqCWwB0zQvsjdEHtkg==", "cpu": [ "x64" ], @@ -443,9 +442,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.1.tgz", - "integrity": "sha512-5hEZKPf+nQjYoSr/elb62U19/l1mZDdqidGfmFutVUjjUZrOazAtwK+Kr+3y0C/oeJfLlxo9fXb1w7L+P7E4FQ==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.2.tgz", + "integrity": "sha512-MpM6LUVTXAzOvN4KbjzU/q5smzryuoNjlriAIx+06RpecwCkL9JpenNzpKd2YMzLJFOdPqBpuub6eVRP5IgiSA==", "cpu": [ "arm64" ], @@ -460,9 +459,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.1.tgz", - "integrity": "sha512-hxVnwL2Dqs3fM1IWq8Iezh0cX7ZGdVhbTfnOy5uURtao5OIVCEyj9xIzemDi7sRvKsuSdtCAhMKarxqtlyVyfA==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.2.tgz", + "integrity": "sha512-5eRPrTX7wFyuWe8FqEFPG2cU0+butQQVNcT4sVipqjLYQjjh8a8+vUTfgBKM88ObB85ahsnTwF7PSIt6PG+QkA==", "cpu": [ "x64" ], @@ -477,9 +476,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.1.tgz", - "integrity": "sha512-1MrCZs0fZa2g8E+FUo2ipw6jw5qqQiH+tERoS5fAfKnRx6NXH31tXBKI3VpmLijLH6yriMZsxJtaXUyFt/8Y4A==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.2.tgz", + "integrity": "sha512-mLwm4vXKiQ2UTSX4+ImyiPdiHjiZhIaE9QvC7sw0tZ6HoNMjYAqQpGyui5VRIi5sGd+uWq940gdCbY3VLvsO1w==", "cpu": [ "arm64" ], @@ -494,9 +493,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.1.tgz", - "integrity": "sha512-0IZWLiTyz7nm0xuIs0q1Y3QWJC52R8aSXxe40VUxm6BB1RNmkODtW6LHvWRrGiICulcX7ZvyH6h5fqdLu4gkww==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.2.tgz", + "integrity": "sha512-6qyyn6TjayJSwGpm8J9QYYGQcRgc90nmfdUb0O7pp1s4lTY+9D0H9O02v5JqGApUyiHOtkz6+1hZNvNtEhbwRQ==", "cpu": [ "x64" ], @@ -511,9 +510,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.1.tgz", - "integrity": "sha512-NdKOhS4u7JhDKw9G3cY6sWqFcnLITn6SqivVArbzIaf3cemShqfLGHYMx8Xlm/lBit3/5d7kXvriTUGa5YViuQ==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.2.tgz", + "integrity": "sha512-UHBRgJcmjJv5oeQF8EpTRZs/1knq6loLxTsjc3nxO9eXAPDLcWW55flrMVc97qFPbmZP31ta1AZVUKQzKTzb0g==", "cpu": [ "arm" ], @@ -528,9 +527,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.1.tgz", - "integrity": "sha512-jaN3dHi0/DDPelk0nLcXRm1q7DNJpjXy7yWaWvbfkPvI+7XNSc/lDOnCLN7gzsyzgu6qSAmgSvP9oXAhP973uQ==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.2.tgz", + "integrity": "sha512-gq/sjLsOyMT19I8obBISvhoYiZIAaGF8JpeXu1u8yPv8BE5HlWYobmlsfijFIZ9hIVGYkbdFhEqC0NvM4kNO0g==", "cpu": [ "arm64" ], @@ -545,9 +544,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.1.tgz", - "integrity": "sha512-OJykPaF4v8JidKNGz8c/q1lBO44sQNUQtq1KktJXdBLn1hPod5rE/Hko5ugKKZd+D2+o1a9MFGUEIUwO2YfgkQ==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.2.tgz", + "integrity": "sha512-bBYCv9obgW2cBP+2ZWfjYTU+f5cxRoGGQ5SeDbYdFCAZpYWrfjjfYwvUpP8MlKbP0nwZ5gyOU/0aUzZ5HWPuvQ==", "cpu": [ "ia32" ], @@ -562,9 +561,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.1.tgz", - "integrity": "sha512-nGfornQj4dzcq5Vp835oM/o21UMlXzn79KobKlcs3Wz9smwiifknLy4xDCLUU0BWp7b/houtdrgUz7nOGnfIYg==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.2.tgz", + "integrity": "sha512-SHNGiKtvnU2dBlM5D8CXRFdd+6etgZ9dXfaPCeJtz+37PIUlixvlIhI23L5khKXs3DIzAn9V8v+qb1TRKrgT5w==", "cpu": [ "loong64" ], @@ -579,9 +578,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.1.tgz", - "integrity": "sha512-1osBbPEFYwIE5IVB/0g2X6i1qInZa1aIoj1TdL4AaAb55xIIgbg8Doq6a5BzYWgr+tEcDzYH67XVnTmUzL+nXg==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.2.tgz", + "integrity": "sha512-hDDRlzE6rPeoj+5fsADqdUZl1OzqDYow4TB4Y/3PlKBD0ph1e6uPHzIQcv2Z65u2K0kpeByIyAjCmjn1hJgG0Q==", "cpu": [ "mips64el" ], @@ -596,9 +595,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.1.tgz", - "integrity": "sha512-/6VBJOwUf3TdTvJZ82qF3tbLuWsscd7/1w+D9LH0W/SqUgM5/JJD0lrJ1fVIfZsqB6RFmLCe0Xz3fmZc3WtyVg==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.2.tgz", + "integrity": "sha512-tsHu2RRSWzipmUi9UBDEzc0nLc4HtpZEI5Ba+Omms5456x5WaNuiG3u7xh5AO6sipnJ9r4cRWQB2tUjPyIkc6g==", "cpu": [ "ppc64" ], @@ -613,9 +612,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.1.tgz", - "integrity": "sha512-nSut/Mx5gnilhcq2yIMLMe3Wl4FK5wx/o0QuuCLMtmJn+WeWYoEGDN1ipcN72g1WHsnIbxGXd4i/MF0gTcuAjQ==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.2.tgz", + "integrity": "sha512-k4LtpgV7NJQOml/10uPU0s4SAXGnowi5qBSjaLWMojNCUICNu7TshqHLAEbkBdAszL5TabfvQ48kK84hyFzjnw==", "cpu": [ "riscv64" ], @@ -630,9 +629,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.1.tgz", - "integrity": "sha512-cEECeLlJNfT8kZHqLarDBQso9a27o2Zd2AQ8USAEoGtejOrCYHNtKP8XQhMDJMtthdF4GBmjR2au3x1udADQQQ==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.2.tgz", + "integrity": "sha512-GRa4IshOdvKY7M/rDpRR3gkiTNp34M0eLTaC1a08gNrh4u488aPhuZOCpkF6+2wl3zAN7L7XIpOFBhnaE3/Q8Q==", "cpu": [ "s390x" ], @@ -647,9 +646,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.1.tgz", - "integrity": "sha512-xbfUhu/gnvSEg+EGovRc+kjBAkrvtk38RlerAzQxvMzlB4fXpCFCeUAYzJvrnhFtdeyVCDANSjJvOvGYoeKzFA==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.2.tgz", + "integrity": "sha512-QInHERlqpTTZ4FRB0fROQWXcYRD64lAoiegezDunLpalZMjcUcld3YzZmVJ2H/Cp0wJRZ8Xtjtj0cEHhYc/uUg==", "cpu": [ "x64" ], @@ -664,9 +663,9 @@ } }, "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.1.tgz", - "integrity": "sha512-O96poM2XGhLtpTh+s4+nP7YCCAfb4tJNRVZHfIE7dgmax+yMP2WgMd2OecBuaATHKTHsLWHQeuaxMRnCsH8+5g==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.2.tgz", + "integrity": "sha512-talAIBoY5M8vHc6EeI2WW9d/CkiO9MQJ0IOWX8hrLhxGbro/vBXJvaQXefW2cP0z0nQVTdQ/eNyGFV1GSKrxfw==", "cpu": [ "arm64" ], @@ -681,9 +680,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.1.tgz", - "integrity": "sha512-X53z6uXip6KFXBQ+Krbx25XHV/NCbzryM6ehOAeAil7X7oa4XIq+394PWGnwaSQ2WRA0KI6PUO6hTO5zeF5ijA==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.2.tgz", + "integrity": "sha512-voZT9Z+tpOxrvfKFyfDYPc4DO4rk06qamv1a/fkuzHpiVBMOhpjK+vBmWM8J1eiB3OLSMFYNaOaBNLXGChf5tg==", "cpu": [ "x64" ], @@ -698,9 +697,9 @@ } }, "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.1.tgz", - "integrity": "sha512-Na9T3szbXezdzM/Kfs3GcRQNjHzM6GzFBeU1/6IV/npKP5ORtp9zbQjvkDJ47s6BCgaAZnnnu/cY1x342+MvZg==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.2.tgz", + "integrity": "sha512-dcXYOC6NXOqcykeDlwId9kB6OkPUxOEqU+rkrYVqJbK2hagWOMrsTGsMr8+rW02M+d5Op5NNlgMmjzecaRf7Tg==", "cpu": [ "arm64" ], @@ -715,9 +714,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.1.tgz", - "integrity": "sha512-T3H78X2h1tszfRSf+txbt5aOp/e7TAz3ptVKu9Oyir3IAOFPGV6O9c2naym5TOriy1l0nNf6a4X5UXRZSGX/dw==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.2.tgz", + "integrity": "sha512-t/TkWwahkH0Tsgoq1Ju7QfgGhArkGLkF1uYz8nQS/PPFlXbP5YgRpqQR3ARRiC2iXoLTWFxc6DJMSK10dVXluw==", "cpu": [ "x64" ], @@ -732,9 +731,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.1.tgz", - "integrity": "sha512-2H3RUvcmULO7dIE5EWJH8eubZAI4xw54H1ilJnRNZdeo8dTADEZ21w6J22XBkXqGJbe0+wnNJtw3UXRoLJnFEg==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.2.tgz", + "integrity": "sha512-cfZH1co2+imVdWCjd+D1gf9NjkchVhhdpgb1q5y6Hcv9TP6Zi9ZG/beI3ig8TvwT9lH9dlxLq5MQBBgwuj4xvA==", "cpu": [ "x64" ], @@ -749,9 +748,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.1.tgz", - "integrity": "sha512-GE7XvrdOzrb+yVKB9KsRMq+7a2U/K5Cf/8grVFRAGJmfADr/e/ODQ134RK2/eeHqYV5eQRFxb1hY7Nr15fv1NQ==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.2.tgz", + "integrity": "sha512-7Loyjh+D/Nx/sOTzV8vfbB3GJuHdOQyrOryFdZvPHLf42Tk9ivBU5Aedi7iyX+x6rbn2Mh68T4qq1SDqJBQO5Q==", "cpu": [ "arm64" ], @@ -766,9 +765,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.1.tgz", - "integrity": "sha512-uOxSJCIcavSiT6UnBhBzE8wy3n0hOkJsBOzy7HDAuTDE++1DJMRRVCPGisULScHL+a/ZwdXPpXD3IyFKjA7K8A==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.2.tgz", + "integrity": "sha512-WRJgsz9un0nqZJ4MfhabxaD9Ft8KioqU3JMinOTvobbX6MOSUigSBlogP8QB3uxpJDsFS6yN+3FDBdqE5lg9kg==", "cpu": [ "ia32" ], @@ -783,9 +782,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.1.tgz", - "integrity": "sha512-Y1EQdcfwMSeQN/ujR5VayLOJ1BHaK+ssyk0AEzPjC+t1lITgsnccPqFjb6V+LsTp/9Iov4ysfjxLaGJ9RPtkVg==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.2.tgz", + "integrity": "sha512-kM3HKb16VIXZyIeVrM1ygYmZBKybX8N4p754bw390wGO3Tf2j4L2/WYL+4suWujpgf6GBYs3jv7TyUivdd05JA==", "cpu": [ "x64" ], @@ -800,9 +799,9 @@ } }, "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", - "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==", + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.5.1.tgz", + "integrity": "sha512-soEIOALTfTK6EjmKMMoLugwaP0rzkad90iIWd1hMO9ARkSAyjfMfkRRhLvD5qH7vvM0Cg72pieUfR6yh6XxC4w==", "dev": true, "license": "MIT", "dependencies": { @@ -857,9 +856,9 @@ } }, "node_modules/@eslint/config-helpers": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.1.0.tgz", - "integrity": "sha512-kLrdPDJE1ckPo94kmPPf9Hfd0DU0Jw6oKYrhe+pwSC0iTUInmTa+w6fw8sGgcfkFJGNdWOUeOaDM4quW4a7OkA==", + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.2.1.tgz", + "integrity": "sha512-RI17tsD2frtDu/3dmI7QRrD4bedNKPM08ziRYaC5AhkGrzIAJelm9kJU1TznK+apx6V+cqRz8tfpEeG3oIyjxw==", "dev": true, "license": "Apache-2.0", "engines": { @@ -880,9 +879,9 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.0.tgz", - "integrity": "sha512-yaVPAiNAalnCZedKLdR21GOGILMLKPyqSLWaAjQFvYA2i/ciDi8ArYVr69Anohb6cH2Ukhqti4aFnYyPm8wdwQ==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", + "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", "dev": true, "license": "MIT", "dependencies": { @@ -917,9 +916,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.22.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.22.0.tgz", - "integrity": "sha512-vLFajx9o8d1/oL2ZkpMYbkLv8nDB6yaIwFNt7nI4+I80U/z03SxmfOMsLbvWr3p7C+Wnoh//aOu2pQW8cS0HCQ==", + "version": "9.23.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.23.0.tgz", + "integrity": "sha512-35MJ8vCPU0ZMxo7zfev2pypqTwWTofFZO6m4KAtdoFhRpLJUpHTZZ+KB3C7Hb1d7bULYwO4lJXGCi5Se+8OMbw==", "dev": true, "license": "MIT", "engines": { @@ -937,19 +936,32 @@ } }, "node_modules/@eslint/plugin-kit": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.7.tgz", - "integrity": "sha512-JubJ5B2pJ4k4yGxaNLdbjrnk9d/iDz6/q8wOilpIowd6PJPgaxCuHBnBszq7Ce2TyMrywm5r4PnKm6V3iiZF+g==", + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.8.tgz", + "integrity": "sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@eslint/core": "^0.12.0", + "@eslint/core": "^0.13.0", "levn": "^0.4.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, + "node_modules/@eslint/plugin-kit/node_modules/@eslint/core": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.13.0.tgz", + "integrity": "sha512-yfkgDw1KR66rkT5A8ci4irzDysN7FRpq3ttJolR88OqQikAWqwA8j5VZyas+vjyBNFIJ7MfybJ9plMILI2UrCw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, "node_modules/@humanfs/core": { "version": "0.19.1", "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", @@ -1137,9 +1149,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.35.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.35.0.tgz", - "integrity": "sha512-uYQ2WfPaqz5QtVgMxfN6NpLD+no0MYHDBywl7itPYd3K5TjjSghNKmX8ic9S8NU8w81NVhJv/XojcHptRly7qQ==", + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.39.0.tgz", + "integrity": "sha512-lGVys55Qb00Wvh8DMAocp5kIcaNzEFTmGhfFd88LfaogYTRKrdxgtlO5H6S49v2Nd8R2C6wLOal0qv6/kCkOwA==", "cpu": [ "arm" ], @@ -1151,9 +1163,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.35.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.35.0.tgz", - "integrity": "sha512-FtKddj9XZudurLhdJnBl9fl6BwCJ3ky8riCXjEw3/UIbjmIY58ppWwPEvU3fNu+W7FUsAsB1CdH+7EQE6CXAPA==", + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.39.0.tgz", + "integrity": "sha512-It9+M1zE31KWfqh/0cJLrrsCPiF72PoJjIChLX+rEcujVRCb4NLQ5QzFkzIZW8Kn8FTbvGQBY5TkKBau3S8cCQ==", "cpu": [ "arm64" ], @@ -1165,9 +1177,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.35.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.35.0.tgz", - "integrity": "sha512-Uk+GjOJR6CY844/q6r5DR/6lkPFOw0hjfOIzVx22THJXMxktXG6CbejseJFznU8vHcEBLpiXKY3/6xc+cBm65Q==", + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.39.0.tgz", + "integrity": "sha512-lXQnhpFDOKDXiGxsU9/l8UEGGM65comrQuZ+lDcGUx+9YQ9dKpF3rSEGepyeR5AHZ0b5RgiligsBhWZfSSQh8Q==", "cpu": [ "arm64" ], @@ -1179,9 +1191,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.35.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.35.0.tgz", - "integrity": "sha512-3IrHjfAS6Vkp+5bISNQnPogRAW5GAV1n+bNCrDwXmfMHbPl5EhTmWtfmwlJxFRUCBZ+tZ/OxDyU08aF6NI/N5Q==", + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.39.0.tgz", + "integrity": "sha512-mKXpNZLvtEbgu6WCkNij7CGycdw9cJi2k9v0noMb++Vab12GZjFgUXD69ilAbBh034Zwn95c2PNSz9xM7KYEAQ==", "cpu": [ "x64" ], @@ -1193,9 +1205,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.35.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.35.0.tgz", - "integrity": "sha512-sxjoD/6F9cDLSELuLNnY0fOrM9WA0KrM0vWm57XhrIMf5FGiN8D0l7fn+bpUeBSU7dCgPV2oX4zHAsAXyHFGcQ==", + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.39.0.tgz", + "integrity": "sha512-jivRRlh2Lod/KvDZx2zUR+I4iBfHcu2V/BA2vasUtdtTN2Uk3jfcZczLa81ESHZHPHy4ih3T/W5rPFZ/hX7RtQ==", "cpu": [ "arm64" ], @@ -1207,9 +1219,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.35.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.35.0.tgz", - "integrity": "sha512-2mpHCeRuD1u/2kruUiHSsnjWtHjqVbzhBkNVQ1aVD63CcexKVcQGwJ2g5VphOd84GvxfSvnnlEyBtQCE5hxVVw==", + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.39.0.tgz", + "integrity": "sha512-8RXIWvYIRK9nO+bhVz8DwLBepcptw633gv/QT4015CpJ0Ht8punmoHU/DuEd3iw9Hr8UwUV+t+VNNuZIWYeY7Q==", "cpu": [ "x64" ], @@ -1221,9 +1233,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.35.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.35.0.tgz", - "integrity": "sha512-mrA0v3QMy6ZSvEuLs0dMxcO2LnaCONs1Z73GUDBHWbY8tFFocM6yl7YyMu7rz4zS81NDSqhrUuolyZXGi8TEqg==", + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.39.0.tgz", + "integrity": "sha512-mz5POx5Zu58f2xAG5RaRRhp3IZDK7zXGk5sdEDj4o96HeaXhlUwmLFzNlc4hCQi5sGdR12VDgEUqVSHer0lI9g==", "cpu": [ "arm" ], @@ -1235,9 +1247,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.35.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.35.0.tgz", - "integrity": "sha512-DnYhhzcvTAKNexIql8pFajr0PiDGrIsBYPRvCKlA5ixSS3uwo/CWNZxB09jhIapEIg945KOzcYEAGGSmTSpk7A==", + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.39.0.tgz", + "integrity": "sha512-+YDwhM6gUAyakl0CD+bMFpdmwIoRDzZYaTWV3SDRBGkMU/VpIBYXXEvkEcTagw/7VVkL2vA29zU4UVy1mP0/Yw==", "cpu": [ "arm" ], @@ -1249,9 +1261,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.35.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.35.0.tgz", - "integrity": "sha512-uagpnH2M2g2b5iLsCTZ35CL1FgyuzzJQ8L9VtlJ+FckBXroTwNOaD0z0/UF+k5K3aNQjbm8LIVpxykUOQt1m/A==", + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.39.0.tgz", + "integrity": "sha512-EKf7iF7aK36eEChvlgxGnk7pdJfzfQbNvGV/+l98iiMwU23MwvmV0Ty3pJ0p5WQfm3JRHOytSIqD9LB7Bq7xdQ==", "cpu": [ "arm64" ], @@ -1263,9 +1275,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.35.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.35.0.tgz", - "integrity": "sha512-XQxVOCd6VJeHQA/7YcqyV0/88N6ysSVzRjJ9I9UA/xXpEsjvAgDTgH3wQYz5bmr7SPtVK2TsP2fQ2N9L4ukoUg==", + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.39.0.tgz", + "integrity": "sha512-vYanR6MtqC7Z2SNr8gzVnzUul09Wi1kZqJaek3KcIlI/wq5Xtq4ZPIZ0Mr/st/sv/NnaPwy/D4yXg5x0B3aUUA==", "cpu": [ "arm64" ], @@ -1277,9 +1289,9 @@ ] }, "node_modules/@rollup/rollup-linux-loongarch64-gnu": { - "version": "4.35.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.35.0.tgz", - "integrity": "sha512-5pMT5PzfgwcXEwOaSrqVsz/LvjDZt+vQ8RT/70yhPU06PTuq8WaHhfT1LW+cdD7mW6i/J5/XIkX/1tCAkh1W6g==", + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.39.0.tgz", + "integrity": "sha512-NMRUT40+h0FBa5fb+cpxtZoGAggRem16ocVKIv5gDB5uLDgBIwrIsXlGqYbLwW8YyO3WVTk1FkFDjMETYlDqiw==", "cpu": [ "loong64" ], @@ -1291,9 +1303,9 @@ ] }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.35.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.35.0.tgz", - "integrity": "sha512-c+zkcvbhbXF98f4CtEIP1EBA/lCic5xB0lToneZYvMeKu5Kamq3O8gqrxiYYLzlZH6E3Aq+TSW86E4ay8iD8EA==", + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.39.0.tgz", + "integrity": "sha512-0pCNnmxgduJ3YRt+D+kJ6Ai/r+TaePu9ZLENl+ZDV/CdVczXl95CbIiwwswu4L+K7uOIGf6tMo2vm8uadRaICQ==", "cpu": [ "ppc64" ], @@ -1305,9 +1317,23 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.35.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.35.0.tgz", - "integrity": "sha512-s91fuAHdOwH/Tad2tzTtPX7UZyytHIRR6V4+2IGlV0Cej5rkG0R61SX4l4y9sh0JBibMiploZx3oHKPnQBKe4g==", + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.39.0.tgz", + "integrity": "sha512-t7j5Zhr7S4bBtksT73bO6c3Qa2AV/HqiGlj9+KB3gNF5upcVkx+HLgxTm8DK4OkzsOYqbdqbLKwvGMhylJCPhQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.39.0.tgz", + "integrity": "sha512-m6cwI86IvQ7M93MQ2RF5SP8tUjD39Y7rjb1qjHgYh28uAPVU8+k/xYWvxRO3/tBN2pZkSMa5RjnPuUIbrwVxeA==", "cpu": [ "riscv64" ], @@ -1319,9 +1345,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.35.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.35.0.tgz", - "integrity": "sha512-hQRkPQPLYJZYGP+Hj4fR9dDBMIM7zrzJDWFEMPdTnTy95Ljnv0/4w/ixFw3pTBMEuuEuoqtBINYND4M7ujcuQw==", + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.39.0.tgz", + "integrity": "sha512-iRDJd2ebMunnk2rsSBYlsptCyuINvxUfGwOUldjv5M4tpa93K8tFMeYGpNk2+Nxl+OBJnBzy2/JCscGeO507kA==", "cpu": [ "s390x" ], @@ -1333,9 +1359,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.35.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.35.0.tgz", - "integrity": "sha512-Pim1T8rXOri+0HmV4CdKSGrqcBWX0d1HoPnQ0uw0bdp1aP5SdQVNBy8LjYncvnLgu3fnnCt17xjWGd4cqh8/hA==", + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.39.0.tgz", + "integrity": "sha512-t9jqYw27R6Lx0XKfEFe5vUeEJ5pF3SGIM6gTfONSMb7DuG6z6wfj2yjcoZxHg129veTqU7+wOhY6GX8wmf90dA==", "cpu": [ "x64" ], @@ -1347,9 +1373,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.35.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.35.0.tgz", - "integrity": "sha512-QysqXzYiDvQWfUiTm8XmJNO2zm9yC9P/2Gkrwg2dH9cxotQzunBHYr6jk4SujCTqnfGxduOmQcI7c2ryuW8XVg==", + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.39.0.tgz", + "integrity": "sha512-ThFdkrFDP55AIsIZDKSBWEt/JcWlCzydbZHinZ0F/r1h83qbGeenCt/G/wG2O0reuENDD2tawfAj2s8VK7Bugg==", "cpu": [ "x64" ], @@ -1361,9 +1387,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.35.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.35.0.tgz", - "integrity": "sha512-OUOlGqPkVJCdJETKOCEf1mw848ZyJ5w50/rZ/3IBQVdLfR5jk/6Sr5m3iO2tdPgwo0x7VcncYuOvMhBWZq8ayg==", + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.39.0.tgz", + "integrity": "sha512-jDrLm6yUtbOg2TYB3sBF3acUnAwsIksEYjLeHL+TJv9jg+TmTwdyjnDex27jqEMakNKf3RwwPahDIt7QXCSqRQ==", "cpu": [ "arm64" ], @@ -1375,9 +1401,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.35.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.35.0.tgz", - "integrity": "sha512-2/lsgejMrtwQe44glq7AFFHLfJBPafpsTa6JvP2NGef/ifOa4KBoglVf7AKN7EV9o32evBPRqfg96fEHzWo5kw==", + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.39.0.tgz", + "integrity": "sha512-6w9uMuza+LbLCVoNKL5FSLE7yvYkq9laSd09bwS0tMjkwXrmib/4KmoJcrKhLWHvw19mwU+33ndC69T7weNNjQ==", "cpu": [ "ia32" ], @@ -1389,9 +1415,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.35.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.35.0.tgz", - "integrity": "sha512-PIQeY5XDkrOysbQblSW7v3l1MDZzkTEzAfTPkj5VAu3FW8fS4ynyLg2sINp0fp3SjZ8xkRYpLqoKcYqAkhU1dw==", + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.39.0.tgz", + "integrity": "sha512-yAkUOkIKZlK5dl7u6dg897doBgLXmUHhIINM2c+sND3DZwnrdQkkSiDh7N75Ll4mM4dxSkYfXqU9fW3lLkMFug==", "cpu": [ "x64" ], @@ -1438,9 +1464,9 @@ } }, "node_modules/@types/babel__traverse": { - "version": "7.20.6", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", - "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.7.tgz", + "integrity": "sha512-dkO5fhS7+/oos4ciWxyEyjWe48zmG6wbCheo/G2ZnHx4fs3EU6YC6UM8rk56gAjNJ9P3MTH2jo5jb92/K6wbng==", "dev": true, "license": "MIT", "dependencies": { @@ -1448,9 +1474,9 @@ } }, "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==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz", + "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==", "dev": true, "license": "MIT" }, @@ -1462,19 +1488,19 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "22.13.10", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.10.tgz", - "integrity": "sha512-I6LPUvlRH+O6VRUqYOcMudhaIdUVWfsjnZavnsraHvpBwaEyMN29ry+0UVJhImYL16xsscu0aske3yA+uPOWfw==", + "version": "22.14.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.14.0.tgz", + "integrity": "sha512-Kmpl+z84ILoG+3T/zQFyAJsU6EPTmOCj8/2+83fSN6djd6I4o7uOuGIH6vq3PrjY5BGitSbFuMN18j3iknubbA==", "dev": true, "license": "MIT", "dependencies": { - "undici-types": "~6.20.0" + "undici-types": "~6.21.0" } }, "node_modules/@types/react": { - "version": "19.0.10", - "resolved": "https://registry.npmjs.org/@types/react/-/react-19.0.10.tgz", - "integrity": "sha512-JuRQ9KXLEjaUNjTWpzuR231Z2WpIwczOkBEIvbHNCzQefFIT0L8IqE6NV6ULLyC1SI/i234JnDoMkfg+RjQj2g==", + "version": "19.1.0", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.0.tgz", + "integrity": "sha512-UaicktuQI+9UKyA4njtDOGBD/67t8YEBt2xdfqu8+gP9hqPUPsiXlNPcpS2gVdjmis5GKPG3fCxbQLVgxsQZ8w==", "dev": true, "license": "MIT", "dependencies": { @@ -1482,9 +1508,9 @@ } }, "node_modules/@types/react-dom": { - "version": "19.0.4", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.0.4.tgz", - "integrity": "sha512-4fSQ8vWFkg+TGhePfUzVmat3eC14TXYSsiiDSLI0dVLsrm9gZFABjPy/Qu6TKgl1tq1Bu1yDsuQgY3A3DOjCcg==", + "version": "19.1.1", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.1.1.tgz", + "integrity": "sha512-jFf/woGTVTjUJsl2O7hcopJ1r0upqoq/vIOoCj0yLh3RIXxWcljlpuZ+vEBRXsymD1jhfeJrlyTy/S1UW+4y1w==", "dev": true, "license": "MIT", "peerDependencies": { @@ -1492,17 +1518,17 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.26.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.26.0.tgz", - "integrity": "sha512-cLr1J6pe56zjKYajK6SSSre6nl1Gj6xDp1TY0trpgPzjVbgDwd09v2Ws37LABxzkicmUjhEeg/fAUjPJJB1v5Q==", + "version": "8.29.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.29.0.tgz", + "integrity": "sha512-PAIpk/U7NIS6H7TEtN45SPGLQaHNgB7wSjsQV/8+KYokAb2T/gloOA/Bee2yd4/yKVhPKe5LlaUGhAZk5zmSaQ==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.26.0", - "@typescript-eslint/type-utils": "8.26.0", - "@typescript-eslint/utils": "8.26.0", - "@typescript-eslint/visitor-keys": "8.26.0", + "@typescript-eslint/scope-manager": "8.29.0", + "@typescript-eslint/type-utils": "8.29.0", + "@typescript-eslint/utils": "8.29.0", + "@typescript-eslint/visitor-keys": "8.29.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", @@ -1522,16 +1548,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.26.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.26.0.tgz", - "integrity": "sha512-mNtXP9LTVBy14ZF3o7JG69gRPBK/2QWtQd0j0oH26HcY/foyJJau6pNUez7QrM5UHnSvwlQcJXKsk0I99B9pOA==", + "version": "8.29.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.29.0.tgz", + "integrity": "sha512-8C0+jlNJOwQso2GapCVWWfW/rzaq7Lbme+vGUFKE31djwNncIpgXD7Cd4weEsDdkoZDjH0lwwr3QDQFuyrMg9g==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.26.0", - "@typescript-eslint/types": "8.26.0", - "@typescript-eslint/typescript-estree": "8.26.0", - "@typescript-eslint/visitor-keys": "8.26.0", + "@typescript-eslint/scope-manager": "8.29.0", + "@typescript-eslint/types": "8.29.0", + "@typescript-eslint/typescript-estree": "8.29.0", + "@typescript-eslint/visitor-keys": "8.29.0", "debug": "^4.3.4" }, "engines": { @@ -1547,14 +1573,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.26.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.26.0.tgz", - "integrity": "sha512-E0ntLvsfPqnPwng8b8y4OGuzh/iIOm2z8U3S9zic2TeMLW61u5IH2Q1wu0oSTkfrSzwbDJIB/Lm8O3//8BWMPA==", + "version": "8.29.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.29.0.tgz", + "integrity": "sha512-aO1PVsq7Gm+tcghabUpzEnVSFMCU4/nYIgC2GOatJcllvWfnhrgW0ZEbnTxm36QsikmCN1K/6ZgM7fok2I7xNw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.26.0", - "@typescript-eslint/visitor-keys": "8.26.0" + "@typescript-eslint/types": "8.29.0", + "@typescript-eslint/visitor-keys": "8.29.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1565,14 +1591,14 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.26.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.26.0.tgz", - "integrity": "sha512-ruk0RNChLKz3zKGn2LwXuVoeBcUMh+jaqzN461uMMdxy5H9epZqIBtYj7UiPXRuOpaALXGbmRuZQhmwHhaS04Q==", + "version": "8.29.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.29.0.tgz", + "integrity": "sha512-ahaWQ42JAOx+NKEf5++WC/ua17q5l+j1GFrbbpVKzFL/tKVc0aYY8rVSYUpUvt2hUP1YBr7mwXzx+E/DfUWI9Q==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "8.26.0", - "@typescript-eslint/utils": "8.26.0", + "@typescript-eslint/typescript-estree": "8.29.0", + "@typescript-eslint/utils": "8.29.0", "debug": "^4.3.4", "ts-api-utils": "^2.0.1" }, @@ -1589,9 +1615,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.26.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.26.0.tgz", - "integrity": "sha512-89B1eP3tnpr9A8L6PZlSjBvnJhWXtYfZhECqlBl1D9Lme9mHO6iWlsprBtVenQvY1HMhax1mWOjhtL3fh/u+pA==", + "version": "8.29.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.29.0.tgz", + "integrity": "sha512-wcJL/+cOXV+RE3gjCyl/V2G877+2faqvlgtso/ZRbTCnZazh0gXhe+7gbAnfubzN2bNsBtZjDvlh7ero8uIbzg==", "dev": true, "license": "MIT", "engines": { @@ -1603,14 +1629,14 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.26.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.26.0.tgz", - "integrity": "sha512-tiJ1Hvy/V/oMVRTbEOIeemA2XoylimlDQ03CgPPNaHYZbpsc78Hmngnt+WXZfJX1pjQ711V7g0H7cSJThGYfPQ==", + "version": "8.29.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.29.0.tgz", + "integrity": "sha512-yOfen3jE9ISZR/hHpU/bmNvTtBW1NjRbkSFdZOksL1N+ybPEE7UVGMwqvS6CP022Rp00Sb0tdiIkhSCe6NI8ow==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.26.0", - "@typescript-eslint/visitor-keys": "8.26.0", + "@typescript-eslint/types": "8.29.0", + "@typescript-eslint/visitor-keys": "8.29.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", @@ -1669,16 +1695,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.26.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.26.0.tgz", - "integrity": "sha512-2L2tU3FVwhvU14LndnQCA2frYC8JnPDVKyQtWFPf8IYFMt/ykEN1bPolNhNbCVgOmdzTlWdusCTKA/9nKrf8Ig==", + "version": "8.29.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.29.0.tgz", + "integrity": "sha512-gX/A0Mz9Bskm8avSWFcK0gP7cZpbY4AIo6B0hWYFCaIsz750oaiWR4Jr2CI+PQhfW1CpcQr9OlfPS+kMFegjXA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "8.26.0", - "@typescript-eslint/types": "8.26.0", - "@typescript-eslint/typescript-estree": "8.26.0" + "@typescript-eslint/scope-manager": "8.29.0", + "@typescript-eslint/types": "8.29.0", + "@typescript-eslint/typescript-estree": "8.29.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1693,13 +1719,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.26.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.26.0.tgz", - "integrity": "sha512-2z8JQJWAzPdDd51dRQ/oqIJxe99/hoLIqmf8RMCAJQtYDc535W/Jt2+RTP4bP0aKeBG1F65yjIZuczOXCmbWwg==", + "version": "8.29.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.29.0.tgz", + "integrity": "sha512-Sne/pVz8ryR03NFK21VpN88dZ2FdQXOlq3VIklbrTYEt8yXtRFr9tvUhqvCeKjqYk5FSim37sHbooT6vzBTZcg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.26.0", + "@typescript-eslint/types": "8.29.0", "eslint-visitor-keys": "^4.2.0" }, "engines": { @@ -2099,9 +2125,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001703", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001703.tgz", - "integrity": "sha512-kRlAGTRWgPsOj7oARC9m1okJEXdL/8fekFVcxA8Hl7GH4r/sN4OJn/i6Flde373T50KS7Y37oFbMwlE8+F42kQ==", + "version": "1.0.30001709", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001709.tgz", + "integrity": "sha512-NgL3vUTnDrPCZ3zTahp4fsugQ4dc7EKTSzwQDPEel6DMoMnfH2jhry9n2Zm8onbSR+f/QtKHFOA+iAQu4kbtWA==", "dev": true, "funding": [ { @@ -2329,18 +2355,6 @@ "dev": true, "license": "MIT" }, - "node_modules/detect-libc": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", - "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", - "dev": true, - "license": "Apache-2.0", - "optional": true, - "peer": true, - "engines": { - "node": ">=8" - } - }, "node_modules/deweb-pages": { "resolved": "../../server/pages", "link": true @@ -2367,9 +2381,9 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.114", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.114.tgz", - "integrity": "sha512-DFptFef3iktoKlFQK/afbo274/XNWD00Am0xa7M8FZUepHlHT8PEuiNBoRfFHbH1okqN58AlhbJ4QTkcnXorjA==", + "version": "1.5.130", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.130.tgz", + "integrity": "sha512-Ou2u7L9j2XLZbhqzyX0jWDj6gA8D3jIfVzt4rikLf3cGBa0VdReuFimBKS9tQJA4+XpeCxj1NoWlfBXzbMa9IA==", "dev": true, "license": "ISC" }, @@ -2381,9 +2395,9 @@ "license": "MIT" }, "node_modules/esbuild": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.1.tgz", - "integrity": "sha512-BGO5LtrGC7vxnqucAe/rmvKdJllfGaYWdyABvyMoXQlfYMb2bbRuReWR5tEGE//4LcNJj9XrkovTqNYRFZHAMQ==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.2.tgz", + "integrity": "sha512-16854zccKPnC+toMywC+uKNeYSv+/eXkevRAfwRD/G9Cleq66m8XFIrigkbvauLLlCfDL45Q2cWegSg53gGBnQ==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -2394,31 +2408,31 @@ "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.1", - "@esbuild/android-arm": "0.25.1", - "@esbuild/android-arm64": "0.25.1", - "@esbuild/android-x64": "0.25.1", - "@esbuild/darwin-arm64": "0.25.1", - "@esbuild/darwin-x64": "0.25.1", - "@esbuild/freebsd-arm64": "0.25.1", - "@esbuild/freebsd-x64": "0.25.1", - "@esbuild/linux-arm": "0.25.1", - "@esbuild/linux-arm64": "0.25.1", - "@esbuild/linux-ia32": "0.25.1", - "@esbuild/linux-loong64": "0.25.1", - "@esbuild/linux-mips64el": "0.25.1", - "@esbuild/linux-ppc64": "0.25.1", - "@esbuild/linux-riscv64": "0.25.1", - "@esbuild/linux-s390x": "0.25.1", - "@esbuild/linux-x64": "0.25.1", - "@esbuild/netbsd-arm64": "0.25.1", - "@esbuild/netbsd-x64": "0.25.1", - "@esbuild/openbsd-arm64": "0.25.1", - "@esbuild/openbsd-x64": "0.25.1", - "@esbuild/sunos-x64": "0.25.1", - "@esbuild/win32-arm64": "0.25.1", - "@esbuild/win32-ia32": "0.25.1", - "@esbuild/win32-x64": "0.25.1" + "@esbuild/aix-ppc64": "0.25.2", + "@esbuild/android-arm": "0.25.2", + "@esbuild/android-arm64": "0.25.2", + "@esbuild/android-x64": "0.25.2", + "@esbuild/darwin-arm64": "0.25.2", + "@esbuild/darwin-x64": "0.25.2", + "@esbuild/freebsd-arm64": "0.25.2", + "@esbuild/freebsd-x64": "0.25.2", + "@esbuild/linux-arm": "0.25.2", + "@esbuild/linux-arm64": "0.25.2", + "@esbuild/linux-ia32": "0.25.2", + "@esbuild/linux-loong64": "0.25.2", + "@esbuild/linux-mips64el": "0.25.2", + "@esbuild/linux-ppc64": "0.25.2", + "@esbuild/linux-riscv64": "0.25.2", + "@esbuild/linux-s390x": "0.25.2", + "@esbuild/linux-x64": "0.25.2", + "@esbuild/netbsd-arm64": "0.25.2", + "@esbuild/netbsd-x64": "0.25.2", + "@esbuild/openbsd-arm64": "0.25.2", + "@esbuild/openbsd-x64": "0.25.2", + "@esbuild/sunos-x64": "0.25.2", + "@esbuild/win32-arm64": "0.25.2", + "@esbuild/win32-ia32": "0.25.2", + "@esbuild/win32-x64": "0.25.2" } }, "node_modules/escalade": { @@ -2445,19 +2459,19 @@ } }, "node_modules/eslint": { - "version": "9.22.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.22.0.tgz", - "integrity": "sha512-9V/QURhsRN40xuHXWjV64yvrzMjcz7ZyNoF2jJFmy9j/SLk0u1OLSZgXi28MrXjymnjEGSR80WCdab3RGMDveQ==", + "version": "9.23.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.23.0.tgz", + "integrity": "sha512-jV7AbNoFPAY1EkFYpLq5bslU9NLNO8xnEeQXwErNibVryjk67wHVmddTBilc5srIttJDBrB0eMHKZBFbSIABCw==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.19.2", - "@eslint/config-helpers": "^0.1.0", + "@eslint/config-helpers": "^0.2.0", "@eslint/core": "^0.12.0", - "@eslint/eslintrc": "^3.3.0", - "@eslint/js": "9.22.0", + "@eslint/eslintrc": "^3.3.1", + "@eslint/js": "9.23.0", "@eslint/plugin-kit": "^0.2.7", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", @@ -3131,15 +3145,13 @@ } }, "node_modules/jiti": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz", - "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==", + "version": "1.21.7", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", + "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "bin": { - "jiti": "lib/jiti-cli.mjs" + "jiti": "bin/jiti.js" } }, "node_modules/js-tokens": { @@ -3279,257 +3291,6 @@ "node": ">= 0.8.0" } }, - "node_modules/lightningcss": { - "version": "1.29.2", - "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.29.2.tgz", - "integrity": "sha512-6b6gd/RUXKaw5keVdSEtqFVdzWnU5jMxTUjA2bVcMNPLwSQ08Sv/UodBVtETLCn7k4S1Ibxwh7k68IwLZPgKaA==", - "dev": true, - "license": "MPL-2.0", - "optional": true, - "peer": true, - "dependencies": { - "detect-libc": "^2.0.3" - }, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - }, - "optionalDependencies": { - "lightningcss-darwin-arm64": "1.29.2", - "lightningcss-darwin-x64": "1.29.2", - "lightningcss-freebsd-x64": "1.29.2", - "lightningcss-linux-arm-gnueabihf": "1.29.2", - "lightningcss-linux-arm64-gnu": "1.29.2", - "lightningcss-linux-arm64-musl": "1.29.2", - "lightningcss-linux-x64-gnu": "1.29.2", - "lightningcss-linux-x64-musl": "1.29.2", - "lightningcss-win32-arm64-msvc": "1.29.2", - "lightningcss-win32-x64-msvc": "1.29.2" - } - }, - "node_modules/lightningcss-darwin-arm64": { - "version": "1.29.2", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.29.2.tgz", - "integrity": "sha512-cK/eMabSViKn/PG8U/a7aCorpeKLMlK0bQeNHmdb7qUnBkNPnL+oV5DjJUo0kqWsJUapZsM4jCfYItbqBDvlcA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "darwin" - ], - "peer": true, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-darwin-x64": { - "version": "1.29.2", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.29.2.tgz", - "integrity": "sha512-j5qYxamyQw4kDXX5hnnCKMf3mLlHvG44f24Qyi2965/Ycz829MYqjrVg2H8BidybHBp9kom4D7DR5VqCKDXS0w==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "darwin" - ], - "peer": true, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-freebsd-x64": { - "version": "1.29.2", - "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.29.2.tgz", - "integrity": "sha512-wDk7M2tM78Ii8ek9YjnY8MjV5f5JN2qNVO+/0BAGZRvXKtQrBC4/cn4ssQIpKIPP44YXw6gFdpUF+Ps+RGsCwg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "freebsd" - ], - "peer": true, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm-gnueabihf": { - "version": "1.29.2", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.29.2.tgz", - "integrity": "sha512-IRUrOrAF2Z+KExdExe3Rz7NSTuuJ2HvCGlMKoquK5pjvo2JY4Rybr+NrKnq0U0hZnx5AnGsuFHjGnNT14w26sg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm64-gnu": { - "version": "1.29.2", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.29.2.tgz", - "integrity": "sha512-KKCpOlmhdjvUTX/mBuaKemp0oeDIBBLFiU5Fnqxh1/DZ4JPZi4evEH7TKoSBFOSOV3J7iEmmBaw/8dpiUvRKlQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm64-musl": { - "version": "1.29.2", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.29.2.tgz", - "integrity": "sha512-Q64eM1bPlOOUgxFmoPUefqzY1yV3ctFPE6d/Vt7WzLW4rKTv7MyYNky+FWxRpLkNASTnKQUaiMJ87zNODIrrKQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-x64-gnu": { - "version": "1.29.2", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.29.2.tgz", - "integrity": "sha512-0v6idDCPG6epLXtBH/RPkHvYx74CVziHo6TMYga8O2EiQApnUPZsbR9nFNrg2cgBzk1AYqEd95TlrsL7nYABQg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-x64-musl": { - "version": "1.29.2", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.29.2.tgz", - "integrity": "sha512-rMpz2yawkgGT8RULc5S4WiZopVMOFWjiItBT7aSfDX4NQav6M44rhn5hjtkKzB+wMTRlLLqxkeYEtQ3dd9696w==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-win32-arm64-msvc": { - "version": "1.29.2", - "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.29.2.tgz", - "integrity": "sha512-nL7zRW6evGQqYVu/bKGK+zShyz8OVzsCotFgc7judbt6wnB2KbiKKJwBE4SGoDBQ1O94RjW4asrCjQL4i8Fhbw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "win32" - ], - "peer": true, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-win32-x64-msvc": { - "version": "1.29.2", - "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.29.2.tgz", - "integrity": "sha512-EdIUW3B2vLuHmv7urfzMI/h2fmlnOQBk1xlsDxkN1tCWKjNFjfLhGxYk8C8mzpSfr+A6jFFIi8fU6LbQGsRWjA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "win32" - ], - "peer": true, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, "node_modules/lilconfig": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", @@ -3657,9 +3418,9 @@ } }, "node_modules/nanoid": { - "version": "3.3.9", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.9.tgz", - "integrity": "sha512-SppoicMGpZvbF1l3z4x7No3OlIjP7QJvC9XR7AhZr1kL133KHnKPztkKDc+Ir4aJ/1VhTySrtKhrsycmrMQfvg==", + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", "dev": true, "funding": [ { @@ -3881,9 +3642,9 @@ } }, "node_modules/pirates": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", - "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", + "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", "dev": true, "license": "MIT", "engines": { @@ -4099,24 +3860,24 @@ "license": "MIT" }, "node_modules/react": { - "version": "19.0.0", - "resolved": "https://registry.npmjs.org/react/-/react-19.0.0.tgz", - "integrity": "sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==", + "version": "19.1.0", + "resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz", + "integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==", "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/react-dom": { - "version": "19.0.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.0.0.tgz", - "integrity": "sha512-4GV5sHFG0e/0AD4X+ySy6UJd3jVl1iNsNHdpad0qhABJ11twS3TTBnseqsKurKcsNqCEFeGL3uLpVChpIO3QfQ==", + "version": "19.1.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz", + "integrity": "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==", "license": "MIT", "dependencies": { - "scheduler": "^0.25.0" + "scheduler": "^0.26.0" }, "peerDependencies": { - "react": "^19.0.0" + "react": "^19.1.0" } }, "node_modules/react-icons": { @@ -4254,13 +4015,13 @@ } }, "node_modules/rollup": { - "version": "4.35.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.35.0.tgz", - "integrity": "sha512-kg6oI4g+vc41vePJyO6dHt/yl0Rz3Thv0kJeVQ3D1kS3E5XSuKbPc29G4IpT/Kv1KQwgHVcN+HtyS+HYLNSvQg==", + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.39.0.tgz", + "integrity": "sha512-thI8kNc02yNvnmJp8dr3fNWJ9tCONDhp6TV35X6HkKGGs9E6q7YWCHbe5vKiTa7TAiNcFEmXKj3X/pG2b3ci0g==", "dev": true, "license": "MIT", "dependencies": { - "@types/estree": "1.0.6" + "@types/estree": "1.0.7" }, "bin": { "rollup": "dist/bin/rollup" @@ -4270,25 +4031,26 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.35.0", - "@rollup/rollup-android-arm64": "4.35.0", - "@rollup/rollup-darwin-arm64": "4.35.0", - "@rollup/rollup-darwin-x64": "4.35.0", - "@rollup/rollup-freebsd-arm64": "4.35.0", - "@rollup/rollup-freebsd-x64": "4.35.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.35.0", - "@rollup/rollup-linux-arm-musleabihf": "4.35.0", - "@rollup/rollup-linux-arm64-gnu": "4.35.0", - "@rollup/rollup-linux-arm64-musl": "4.35.0", - "@rollup/rollup-linux-loongarch64-gnu": "4.35.0", - "@rollup/rollup-linux-powerpc64le-gnu": "4.35.0", - "@rollup/rollup-linux-riscv64-gnu": "4.35.0", - "@rollup/rollup-linux-s390x-gnu": "4.35.0", - "@rollup/rollup-linux-x64-gnu": "4.35.0", - "@rollup/rollup-linux-x64-musl": "4.35.0", - "@rollup/rollup-win32-arm64-msvc": "4.35.0", - "@rollup/rollup-win32-ia32-msvc": "4.35.0", - "@rollup/rollup-win32-x64-msvc": "4.35.0", + "@rollup/rollup-android-arm-eabi": "4.39.0", + "@rollup/rollup-android-arm64": "4.39.0", + "@rollup/rollup-darwin-arm64": "4.39.0", + "@rollup/rollup-darwin-x64": "4.39.0", + "@rollup/rollup-freebsd-arm64": "4.39.0", + "@rollup/rollup-freebsd-x64": "4.39.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.39.0", + "@rollup/rollup-linux-arm-musleabihf": "4.39.0", + "@rollup/rollup-linux-arm64-gnu": "4.39.0", + "@rollup/rollup-linux-arm64-musl": "4.39.0", + "@rollup/rollup-linux-loongarch64-gnu": "4.39.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.39.0", + "@rollup/rollup-linux-riscv64-gnu": "4.39.0", + "@rollup/rollup-linux-riscv64-musl": "4.39.0", + "@rollup/rollup-linux-s390x-gnu": "4.39.0", + "@rollup/rollup-linux-x64-gnu": "4.39.0", + "@rollup/rollup-linux-x64-musl": "4.39.0", + "@rollup/rollup-win32-arm64-msvc": "4.39.0", + "@rollup/rollup-win32-ia32-msvc": "4.39.0", + "@rollup/rollup-win32-x64-msvc": "4.39.0", "fsevents": "~2.3.2" } }, @@ -4338,9 +4100,9 @@ "license": "MIT" }, "node_modules/scheduler": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.25.0.tgz", - "integrity": "sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA==", + "version": "0.26.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz", + "integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==", "license": "MIT" }, "node_modules/semver": { @@ -4627,16 +4389,6 @@ "node": ">=14.0.0" } }, - "node_modules/tailwindcss/node_modules/jiti": { - "version": "1.21.7", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", - "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", - "dev": true, - "license": "MIT", - "bin": { - "jiti": "bin/jiti.js" - } - }, "node_modules/tar-stream": { "version": "3.1.7", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", @@ -4696,9 +4448,9 @@ } }, "node_modules/ts-api-utils": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.0.1.tgz", - "integrity": "sha512-dnlgjFSVetynI8nzgJ+qF62efpglpWRk8isUEWZGWlJYySCTD6aKvbUDu+zbPeDakk3bg5H4XpitHukgfL1m9w==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", + "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", "dev": true, "license": "MIT", "engines": { @@ -4743,15 +4495,15 @@ } }, "node_modules/typescript-eslint": { - "version": "8.26.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.26.0.tgz", - "integrity": "sha512-PtVz9nAnuNJuAVeUFvwztjuUgSnJInODAUx47VDwWPXzd5vismPOtPtt83tzNXyOjVQbPRp786D6WFW/M2koIA==", + "version": "8.29.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.29.0.tgz", + "integrity": "sha512-ep9rVd9B4kQsZ7ZnWCVxUE/xDLUUUsRzE0poAeNu+4CkFErLfuvPt/qtm2EpnSyfvsR0S6QzDFSrPCFBwf64fg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/eslint-plugin": "8.26.0", - "@typescript-eslint/parser": "8.26.0", - "@typescript-eslint/utils": "8.26.0" + "@typescript-eslint/eslint-plugin": "8.29.0", + "@typescript-eslint/parser": "8.29.0", + "@typescript-eslint/utils": "8.29.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -4766,9 +4518,9 @@ } }, "node_modules/undici-types": { - "version": "6.20.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", - "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", "dev": true, "license": "MIT" }, @@ -5021,9 +4773,9 @@ "license": "ISC" }, "node_modules/yaml": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.0.tgz", - "integrity": "sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==", + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.1.tgz", + "integrity": "sha512-10ULxpnOCQXxJvBgxsn9ptjq6uviG/htZKk9veJGhlqn3w/DxQ631zFF+nlQXLwmImeS5amR2dl2U8sg6U9jsQ==", "dev": true, "license": "ISC", "bin": { diff --git a/plugin/home/src/App.tsx b/plugin/home/src/App.tsx index 4254154c..fa7cefdc 100644 --- a/plugin/home/src/App.tsx +++ b/plugin/home/src/App.tsx @@ -1,6 +1,6 @@ import { FiSearch, FiInfo } from "react-icons/fi"; import { useEffect, useState } from "react"; -import { GenerateTheme } from "deweb-pages/src/hooks/GenerateTheme"; +import { UseGenerateTheme } from "deweb-pages/src/hooks/UseGenerateTheme"; type QuickAccessItemProps = { path: string; @@ -93,7 +93,7 @@ export default function App() { } ]; - const theme = GenerateTheme(); + const theme = UseGenerateTheme(); return (
Date: Fri, 4 Apr 2025 09:13:40 +0200 Subject: [PATCH 36/57] Update plugin/config.yaml.example Co-authored-by: Andrei <34773578+fleandrei@users.noreply.github.com> --- plugin/config.yaml.example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin/config.yaml.example b/plugin/config.yaml.example index 930e0f98..dff97c74 100644 --- a/plugin/config.yaml.example +++ b/plugin/config.yaml.example @@ -3,7 +3,7 @@ # Network node URL to connect to (default: "https://mainnet.massa.net/api/v2") network_node_url: "https://mainnet.massa.net/api/v2" -# API port to listen on (default: 0) +# API port to listen on (default: 0 -> which means a random port will be assigned by OS) api_port: 0 # Cache configuration From 565fd9aa44a546ba822e75d586a21f87cd4075a4 Mon Sep 17 00:00:00 2001 From: thomas-senechal Date: Fri, 4 Apr 2025 09:21:39 +0200 Subject: [PATCH 37/57] Fix PluginDir not returning errors during stat if not IsNotExist --- plugin/main.go | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/plugin/main.go b/plugin/main.go index 6125a946..cdaf90eb 100644 --- a/plugin/main.go +++ b/plugin/main.go @@ -63,11 +63,15 @@ func PluginDir() (string, error) { path := filepath.Join(configDir, directoryName) - // create the directory if it doesn't exist - if _, err := os.Stat(path); os.IsNotExist(err) { - err = os.MkdirAll(path, os.ModePerm) - if err != nil { - return "", fmt.Errorf("creating account directory '%s': %w", path, err) + _, err = os.Stat(path) + if err != nil { + if os.IsNotExist(err) { + err = os.MkdirAll(path, os.ModePerm) + if err != nil { + return "", fmt.Errorf("creating account directory '%s': %w", path, err) + } + } else { + return "", fmt.Errorf("checking directory '%s': %w", path, err) } } From 45d10dd68aa8acb79f630a757105ff4676b0cd00 Mon Sep 17 00:00:00 2001 From: thomas-senechal Date: Tue, 22 Apr 2025 10:10:24 +0200 Subject: [PATCH 38/57] Remove duplicated cacheKeyType and cacheKey constants from API definition --- server/int/api/api.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/server/int/api/api.go b/server/int/api/api.go index 4377f3cc..7e37e8ac 100644 --- a/server/int/api/api.go +++ b/server/int/api/api.go @@ -24,10 +24,6 @@ const ( mnsCacheKey mnsCacheKeyType = "mnsCache" ) -type cacheKeyType string - -const cacheKey cacheKeyType = "cache" - type API struct { Conf *config.ServerConfig APIServer *restapi.Server From a0172281f7aba7f114682545a341c4dd503280be Mon Sep 17 00:00:00 2001 From: thomas-senechal Date: Thu, 24 Apr 2025 17:28:17 +0200 Subject: [PATCH 39/57] Add command-line flags for configuration and log file paths; enhance cache path resolution in config processing --- plugin/go.mod | 37 ++++--- plugin/go.sum | 172 ++++++++------------------------ server/cmd/server/main.go | 15 +-- server/int/api/config/cache.go | 47 +++++++-- server/int/api/config/config.go | 57 +++++++---- 5 files changed, 141 insertions(+), 187 deletions(-) diff --git a/plugin/go.mod b/plugin/go.mod index 6286f611..39161925 100644 --- a/plugin/go.mod +++ b/plugin/go.mod @@ -1,6 +1,6 @@ module github.com/massalabs/deweb-plugin -go 1.23 +go 1.23.0 toolchain go1.24.0 @@ -17,13 +17,14 @@ require ( github.com/awnumar/memcall v0.1.2 // indirect github.com/awnumar/memguard v0.22.3 // indirect github.com/btcsuite/btcutil v1.0.2 // indirect - github.com/cespare/xxhash v1.1.0 // indirect - github.com/cespare/xxhash/v2 v2.1.1 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/dgraph-io/badger/v3 v3.2103.5 // indirect - github.com/dgraph-io/ristretto v0.1.1 // indirect + github.com/dgraph-io/badger/v4 v4.7.0 // indirect + github.com/dgraph-io/ristretto/v2 v2.2.0 // indirect github.com/docker/go-units v0.5.0 // indirect - github.com/dustin/go-humanize v1.0.0 // indirect + github.com/dustin/go-humanize v1.0.1 // indirect + github.com/go-logr/logr v1.4.2 // indirect + github.com/go-logr/stdr v1.2.2 // indirect github.com/go-openapi/analysis v0.23.0 // indirect github.com/go-openapi/errors v0.22.0 // indirect github.com/go-openapi/jsonpointer v0.21.0 // indirect @@ -34,37 +35,35 @@ require ( github.com/go-openapi/strfmt v0.23.0 // indirect github.com/go-openapi/swag v0.23.0 // indirect github.com/go-openapi/validate v0.24.0 // indirect - github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b // indirect - github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 // indirect - github.com/golang/protobuf v1.3.1 // indirect - github.com/golang/snappy v0.0.3 // indirect - github.com/google/flatbuffers v1.12.1 // indirect + github.com/google/flatbuffers v25.2.10+incompatible // indirect github.com/google/uuid v1.6.0 // indirect - github.com/hashicorp/golang-lru v1.0.2 // indirect + github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/jessevdk/go-flags v1.6.1 // indirect github.com/josharian/intern v1.0.0 // indirect - github.com/klauspost/compress v1.13.6 // indirect + github.com/klauspost/compress v1.18.0 // indirect github.com/klauspost/cpuid/v2 v2.1.0 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/massalabs/station-massa-hello-world v0.0.11-0.20240503070604-6b14a27fcdff // indirect github.com/massalabs/station-massa-wallet v0.4.5 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/oklog/ulid v1.3.1 // indirect - github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/shopspring/decimal v1.3.1 // indirect github.com/stretchr/testify v1.10.0 // indirect github.com/ybbus/jsonrpc/v3 v3.1.4 // indirect go.mongodb.org/mongo-driver v1.14.0 // indirect - go.opencensus.io v0.22.5 // indirect + go.opentelemetry.io/auto/sdk v1.1.0 // indirect + go.opentelemetry.io/otel v1.35.0 // indirect + go.opentelemetry.io/otel/metric v1.35.0 // indirect + go.opentelemetry.io/otel/trace v1.35.0 // indirect go.uber.org/atomic v1.10.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.24.0 // indirect - golang.org/x/crypto v0.32.0 // indirect - golang.org/x/net v0.34.0 // indirect + golang.org/x/crypto v0.36.0 // indirect + golang.org/x/net v0.38.0 // indirect golang.org/x/sync v0.10.0 // indirect - golang.org/x/sys v0.29.0 // indirect + golang.org/x/sys v0.31.0 // indirect + google.golang.org/protobuf v1.36.6 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect howett.net/plist v1.0.0 // indirect diff --git a/plugin/go.sum b/plugin/go.sum index 8f39580f..cf0b8818 100644 --- a/plugin/go.sum +++ b/plugin/go.sum @@ -1,9 +1,4 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= -github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= -github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/awnumar/memcall v0.1.2 h1:7gOfDTL+BJ6nnbtAp9+HQzUFjtP1hEseRQq8eP055QY= @@ -22,30 +17,27 @@ github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVa github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= -github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= -github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= -github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= -github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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/dgraph-io/badger/v3 v3.2103.5 h1:ylPa6qzbjYRQMU6jokoj4wzcaweHylt//CH0AKt0akg= -github.com/dgraph-io/badger/v3 v3.2103.5/go.mod h1:4MPiseMeDQ3FNCYwRbbcBOGJLf5jsE0PPFzRiKjtcdw= -github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8= -github.com/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkzgwUve0VDWWA= -github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA= -github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dgraph-io/badger/v4 v4.7.0 h1:Q+J8HApYAY7UMpL8d9owqiB+odzEc0zn/aqOD9jhc6Y= +github.com/dgraph-io/badger/v4 v4.7.0/go.mod h1:He7TzG3YBy3j4f5baj5B7Zl2XyfNe5bl4Udl0aPemVA= +github.com/dgraph-io/ristretto/v2 v2.2.0 h1:bkY3XzJcXoMuELV8F+vS8kzNgicwQFAaGINAEJdWGOM= +github.com/dgraph-io/ristretto/v2 v2.2.0/go.mod h1:RZrm63UmcBAaYWC1DotLYBmTvgkrs0+XhBd7Npn7/zI= +github.com/dgryski/go-farm v0.0.0-20240924180020-3414d57e47da h1:aIftn67I1fkbMa512G+w+Pxci9hJPB8oMnkcP3iZF38= +github.com/dgryski/go-farm v0.0.0-20240924180020-3414d57e47da/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= -github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +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/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-openapi/analysis v0.23.0 h1:aGday7OWupfMs+LbmLZG4k0MYXIANxcuBTYUC03zFCU= github.com/go-openapi/analysis v0.23.0/go.mod h1:9mz9ZWaSlV8TvjQHLl2mUW2PbZtemkE8yA5v22ohupo= github.com/go-openapi/errors v0.22.0 h1:c4xY/OLxUBSTiepAg3j/MHuAv5mJhnf53LLMWFB+u/w= @@ -66,31 +58,16 @@ github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+Gr github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= github.com/go-openapi/validate v0.24.0 h1:LdfDKwNbpB6Vn40xhTdNZAnfLECL81w+VX3BumrGD58= github.com/go-openapi/validate v0.24.0/go.mod h1:iyeX1sEufmv3nPbBdX3ieNviWnOZaJ1+zquzJEf2BAQ= -github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 h1:ZgQEtGgCBiWRM39fZuwSd1LwSqqSW0hOdXCYYDX0R3I= -github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/snappy v0.0.3 h1:fHPg5GQYlCeLIPB9BZqMVR5nR9A+IM5zcgeTdjMYmLA= -github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/google/flatbuffers v1.12.1 h1:MVlul7pQNoDzWRLTw5imwYsl+usrS1TXG2H4jg6ImGw= -github.com/google/flatbuffers v1.12.1/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= -github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/flatbuffers v25.2.10+incompatible h1:F3vclr7C3HpB1k9mxCGRMXq6FdUalZ6H/pNX4FP1v0Q= +github.com/google/flatbuffers v25.2.10+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c= -github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= -github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +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/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.6.1 h1:Cvu5U8UGrLay1rZfv/zP7iLpSHGUZ/Ou68T0iX1bBK4= @@ -98,23 +75,16 @@ github.com/jessevdk/go-flags v1.6.1/go.mod h1:Mk8T1hIAWpOiJiHa9rJASDK2UGWji0EuPG 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/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= -github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= -github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= -github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc= -github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= +github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.1.0 h1:eyi1Ad2aNJMW95zcSbmGg7Cg6cq3ADwLpMAP96d8rF0= github.com/klauspost/cpuid/v2 v2.1.0/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= 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/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/massalabs/station v0.6.5 h1:lkWWYB0/dPsRHSoAqN0wh/mFx8+InsVGMfraXQFZ76U= @@ -123,8 +93,6 @@ github.com/massalabs/station-massa-hello-world v0.0.11-0.20240503070604-6b14a27f github.com/massalabs/station-massa-hello-world v0.0.11-0.20240503070604-6b14a27fcdff/go.mod h1:QbRHQvJFrm4mO+vPzr4Uiwa5REL/CgBlV4PDFdhewa0= github.com/massalabs/station-massa-wallet v0.4.5 h1:0rTHxGPlJ5cKjgB/yQclOBHbWiZO5rOwO0lT7ZjFuVQ= github.com/massalabs/station-massa-wallet v0.4.5/go.mod h1:Eu6Zlijs0uAuGM5CxEUOxFrcIlWtuZVAbiWPCUni9XY= -github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= @@ -132,42 +100,30 @@ github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 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.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= -github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= -github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= -github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= -github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= -github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= 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 v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/ybbus/jsonrpc/v3 v3.1.4 h1:pPmgfWXnqR2GdIlealyCzmV6LV3nxm3w9gwA1B3cP3Y= github.com/ybbus/jsonrpc/v3 v3.1.4/go.mod h1:4HQTl0UzErqWGa6bSXhp8rIjifMAMa55E4D5wdhe768= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.mongodb.org/mongo-driver v1.14.0 h1:P98w8egYRjYe3XDjxhYJagTokP/H6HzlsnojRgZRd80= go.mongodb.org/mongo-driver v1.14.0/go.mod h1:Vzb0Mk/pa7e6cWw85R4F/endUC3u0U9jGcNU603k65c= -go.opencensus.io v0.22.5 h1:dntmOdLpSpHlVqbW5Eay97DelsZHe+55D+xC6i0dDS0= -go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= +go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= +go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ= +go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y= +go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M= +go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE= +go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs= +go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc= go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= @@ -177,72 +133,28 @@ go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN8 go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= -golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= +golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= -golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= +golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 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.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= -golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= +golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= +google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/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/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= @@ -251,12 +163,10 @@ gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYs gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0/go.mod h1:WDnlLJ4WF5VGsH/HVa3CI79GS0ol3YnhVnKP89i0kNg= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= howett.net/plist v1.0.0 h1:7CrbWYbPPO/PyNy38b2EB/+gYbjCe2DXBxgtOOZbSQM= howett.net/plist v1.0.0/go.mod h1:lqaXoTrLY4hg8tnEzNru53gicrbv7rrk+2xJA/7hw9g= lukechampine.com/blake3 v1.1.7 h1:GgRMhmdsuK8+ii6UZFDL8Nb+VyMwadAgcJyfYHxG6n0= diff --git a/server/cmd/server/main.go b/server/cmd/server/main.go index c2d5163e..08725ac7 100644 --- a/server/cmd/server/main.go +++ b/server/cmd/server/main.go @@ -10,11 +10,19 @@ import ( ) func main() { + // Add command-line flag for config file path + configPath := flag.String("configPath", "./deweb_server_config.yaml", "Path to server configuration file") + logPath := flag.String("logPath", "./deweb-server.log", "Path to server log file") // If the --accept-disclaimer (or -a) flag is set, the disclaimer will not be displayed. This is for CI purposes. acceptDisclaimer := flag.Bool("accept-disclaimer", false, "Automatically accept the disclaimer") flag.BoolVar(acceptDisclaimer, "a", false, "Shortcut for --accept-disclaimer") flag.Parse() + err := logger.InitializeGlobal(*logPath) + if err != nil { + log.Fatalf("failed to initialize logger: %v", err) + } + if !*acceptDisclaimer { err := api.HandleDisclaimer() if err != nil { @@ -22,12 +30,7 @@ func main() { } } - err := logger.InitializeGlobal("./deweb-server.log") - if err != nil { - log.Fatalf("failed to initialize logger: %v", err) - } - - conf, err := config.LoadServerConfig("./deweb_server_config.yaml") + conf, err := config.LoadServerConfig(*configPath) if err != nil { log.Fatalf("failed to load server config: %v", err) } diff --git a/server/int/api/config/cache.go b/server/int/api/config/cache.go index 1b3b73e6..ef43e8de 100644 --- a/server/int/api/config/cache.go +++ b/server/int/api/config/cache.go @@ -1,6 +1,10 @@ package config -import "github.com/massalabs/station/pkg/logger" +import ( + "path/filepath" + + "github.com/massalabs/station/pkg/logger" +) const ( // Default cache size limits @@ -26,6 +30,7 @@ type YamlCacheConfig struct { FileListCacheDurationSeconds *int `yaml:"file_list_cache_duration_seconds"` } +// DefaultCacheConfig returns a cache configuration with default values func DefaultCacheConfig() CacheConfig { return CacheConfig{ Enabled: true, @@ -36,16 +41,42 @@ func DefaultCacheConfig() CacheConfig { } } -// ConvertYamlCacheConfig converts a yamlCacheConfig to a CacheConfig -func ConvertYamlCacheConfig(yamlConf *YamlCacheConfig) CacheConfig { +// resolveCachePath resolves the cache path based on the configuration +// - If path is absolute, it's used as-is +// - If path is relative and from config file, it's resolved relative to the config file +func resolveCachePath(cachePath string, configPath string) string { + if filepath.IsAbs(cachePath) { + return cachePath + } + + if configPath != "" { + configDir := filepath.Dir(configPath) + return filepath.Join(configDir, cachePath) + } + + return cachePath +} + +// ProcessCacheConfig processes YAML config into a ready-to-use CacheConfig +// It handles defaults, applies overrides from the YAML config, and resolves paths +func ProcessCacheConfig(yamlConf *YamlCacheConfig, configPath string) CacheConfig { config := DefaultCacheConfig() - if yamlConf == nil { - logger.Debugf("ConvertYamlCacheConfig: yamlConf is nil, returning default config") - return config + // Apply YAML configuration if provided + if yamlConf != nil { + applyYamlOverrides(&config, yamlConf) + } else { + logger.Debugf("ProcessCacheConfig: using default cache configuration") } - // Only override values that are explicitly set in the YAML + // Resolve cache directory path + config.DiskCacheDir = resolveCachePath(config.DiskCacheDir, configPath) + + return config +} + +// applyYamlOverrides applies non-nil YAML settings to the cache config +func applyYamlOverrides(config *CacheConfig, yamlConf *YamlCacheConfig) { if yamlConf.Enabled != nil { config.Enabled = *yamlConf.Enabled } @@ -65,6 +96,4 @@ func ConvertYamlCacheConfig(yamlConf *YamlCacheConfig) CacheConfig { if yamlConf.FileListCacheDurationSeconds != nil { config.FileListCacheDurationSeconds = *yamlConf.FileListCacheDurationSeconds } - - return config } diff --git a/server/int/api/config/config.go b/server/int/api/config/config.go index 8bb4c71b..26a1e411 100644 --- a/server/int/api/config/config.go +++ b/server/int/api/config/config.go @@ -27,15 +27,15 @@ type ServerConfig struct { CacheConfig CacheConfig } -type yamlServerConfig struct { - Domain string `yaml:"domain"` - NetworkNodeURL string `yaml:"network_node_url"` - APIPort int `yaml:"api_port"` - AllowList []string `yaml:"allow_list"` - BlockList []string `yaml:"block_list"` - MiscPublicInfoJson interface{} `yaml:"misc_public_info"` - CacheConfig *YamlCacheConfig `yaml:"cache"` - AllowOffline bool `yaml:"allow_offline"` +type YamlServerConfig struct { + Domain *string `yaml:"domain,omitempty"` + NetworkNodeURL *string `yaml:"network_node_url,omitempty"` + APIPort *int `yaml:"api_port,omitempty"` + AllowList []string `yaml:"allow_list,omitempty"` + BlockList []string `yaml:"block_list,omitempty"` + MiscPublicInfoJson interface{} `yaml:"misc_public_info,omitempty"` + CacheConfig *YamlCacheConfig `yaml:"cache,omitempty"` + AllowOffline bool `yaml:"allow_offline,omitempty"` } func DefaultConfig() (*ServerConfig, error) { @@ -62,7 +62,14 @@ func LoadServerConfig(configPath string) (*ServerConfig, error) { } if _, err := os.Stat(configPath); os.IsNotExist(err) { - return DefaultConfig() + defaultConfig, err := DefaultConfig() + if err != nil { + return nil, fmt.Errorf("failed to create default config: %w", err) + } + // Process cache config with empty configPath for defaults + defaultConfig.CacheConfig = ProcessCacheConfig(nil, "") + + return defaultConfig, nil } filebytes, err := utils.ReadFileBytes(configPath) @@ -70,27 +77,31 @@ func LoadServerConfig(configPath string) (*ServerConfig, error) { return nil, fmt.Errorf("failed to read file bytes: %w", err) } - var yamlConf yamlServerConfig + var yamlConf YamlServerConfig err = yaml.Unmarshal(filebytes, &yamlConf) if err != nil { return nil, fmt.Errorf("failed to unmarshal YAML data: %w", err) } + domain := DefaultDomain + networkNodeURL := DefaultNetworkNodeURL + apiPort := DefaultAPIPort + // Set default values if not specified in the YAML file - if yamlConf.Domain == "" { - yamlConf.Domain = DefaultDomain + if yamlConf.Domain != nil { + domain = *yamlConf.Domain } - if yamlConf.NetworkNodeURL == "" { - yamlConf.NetworkNodeURL = DefaultNetworkNodeURL + if yamlConf.NetworkNodeURL != nil { + networkNodeURL = *yamlConf.NetworkNodeURL } - if yamlConf.APIPort == 0 { - yamlConf.APIPort = DefaultAPIPort + if yamlConf.APIPort != nil { + apiPort = *yamlConf.APIPort } - networkInfos, err := pkgConfig.NewNetworkConfig(yamlConf.NetworkNodeURL) + networkInfos, err := pkgConfig.NewNetworkConfig(networkNodeURL) if err != nil { if yamlConf.AllowOffline { logger.Errorf("unable retrieve network config: %v", err) @@ -100,15 +111,17 @@ func LoadServerConfig(configPath string) (*ServerConfig, error) { } } - // Convert YAML config to ServerConfig + // Process cache configuration + cacheConfig := ProcessCacheConfig(yamlConf.CacheConfig, configPath) + config := &ServerConfig{ - Domain: yamlConf.Domain, - APIPort: yamlConf.APIPort, + Domain: domain, + APIPort: apiPort, NetworkInfos: networkInfos, AllowList: yamlConf.AllowList, BlockList: yamlConf.BlockList, MiscPublicInfoJson: convertYamlMisc2Json(yamlConf.MiscPublicInfoJson), - CacheConfig: ConvertYamlCacheConfig(yamlConf.CacheConfig), + CacheConfig: cacheConfig, } return config, nil From 7cf2361e2f82ba6f13356e56beaef957b3312b52 Mon Sep 17 00:00:00 2001 From: thomas-senechal Date: Tue, 29 Apr 2025 17:26:45 +0200 Subject: [PATCH 40/57] Add network information to DeWebInfo endpoint --- server/api/read/models/de_web_info.go | 107 ++++++++++++++++++++++- server/api/read/restapi/embedded_spec.go | 45 ++++++++++ server/api/readAPI-V0.yml | 10 +++ server/int/api/api.go | 2 +- server/int/api/handlers.go | 12 ++- 5 files changed, 171 insertions(+), 5 deletions(-) diff --git a/server/api/read/models/de_web_info.go b/server/api/read/models/de_web_info.go index 5de16cda..2657db3f 100644 --- a/server/api/read/models/de_web_info.go +++ b/server/api/read/models/de_web_info.go @@ -8,6 +8,7 @@ package models import ( "context" + "github.com/go-openapi/errors" "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" ) @@ -23,17 +24,78 @@ type DeWebInfo struct { // misc Misc interface{} `json:"misc,omitempty"` + // network + Network *DeWebInfoNetwork `json:"network,omitempty"` + // version Version string `json:"version,omitempty"` } // Validate validates this de web info func (m *DeWebInfo) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validateNetwork(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *DeWebInfo) validateNetwork(formats strfmt.Registry) error { + if swag.IsZero(m.Network) { // not required + return nil + } + + if m.Network != nil { + if err := m.Network.Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("network") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("network") + } + return err + } + } + return nil } -// ContextValidate validates this de web info based on context it is used +// ContextValidate validate this de web info based on the context it is used func (m *DeWebInfo) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + var res []error + + if err := m.contextValidateNetwork(ctx, formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *DeWebInfo) contextValidateNetwork(ctx context.Context, formats strfmt.Registry) error { + + if m.Network != nil { + + if swag.IsZero(m.Network) { // not required + return nil + } + + if err := m.Network.ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("network") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("network") + } + return err + } + } + return nil } @@ -54,3 +116,46 @@ func (m *DeWebInfo) UnmarshalBinary(b []byte) error { *m = res return nil } + +// DeWebInfoNetwork de web info network +// +// swagger:model DeWebInfoNetwork +type DeWebInfoNetwork struct { + + // chain ID + ChainID int64 `json:"chainID,omitempty"` + + // network + Network string `json:"network,omitempty"` + + // version + Version string `json:"version,omitempty"` +} + +// Validate validates this de web info network +func (m *DeWebInfoNetwork) Validate(formats strfmt.Registry) error { + return nil +} + +// ContextValidate validates this de web info network based on context it is used +func (m *DeWebInfoNetwork) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (m *DeWebInfoNetwork) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *DeWebInfoNetwork) UnmarshalBinary(b []byte) error { + var res DeWebInfoNetwork + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/server/api/read/restapi/embedded_spec.go b/server/api/read/restapi/embedded_spec.go index 2ee7c46f..caea7814 100644 --- a/server/api/read/restapi/embedded_spec.go +++ b/server/api/read/restapi/embedded_spec.go @@ -90,6 +90,21 @@ func init() { "type": "object", "additionalProperties": true }, + "network": { + "type": "object", + "properties": { + "chainID": { + "type": "integer", + "format": "int64" + }, + "network": { + "type": "string" + }, + "version": { + "type": "string" + } + } + }, "version": { "type": "string" } @@ -178,6 +193,36 @@ func init() { "type": "object", "additionalProperties": true }, + "network": { + "type": "object", + "properties": { + "chainID": { + "type": "integer", + "format": "int64" + }, + "network": { + "type": "string" + }, + "version": { + "type": "string" + } + } + }, + "version": { + "type": "string" + } + } + }, + "DeWebInfoNetwork": { + "type": "object", + "properties": { + "chainID": { + "type": "integer", + "format": "int64" + }, + "network": { + "type": "string" + }, "version": { "type": "string" } diff --git a/server/api/readAPI-V0.yml b/server/api/readAPI-V0.yml index 56d9865a..47400252 100644 --- a/server/api/readAPI-V0.yml +++ b/server/api/readAPI-V0.yml @@ -56,3 +56,13 @@ definitions: misc: type: object additionalProperties: true + network: + type: object + properties: + network: + type: string + version: + type: string + chainID: + type: integer + format: int64 diff --git a/server/int/api/api.go b/server/int/api/api.go index 7e37e8ac..5fc92b11 100644 --- a/server/int/api/api.go +++ b/server/int/api/api.go @@ -124,5 +124,5 @@ func (a *API) configureAPI() { a.DewebAPI.GetResourceHandler = operations.GetResourceHandlerFunc(getResourceHandler) a.DewebAPI.DefaultPageHandler = operations.DefaultPageHandlerFunc(defaultPageHandler) - a.DewebAPI.GetDeWebInfoHandler = NewDewebInfo(a.Conf.MiscPublicInfoJson) + a.DewebAPI.GetDeWebInfoHandler = NewDewebInfo(a.Conf.MiscPublicInfoJson, a.Conf.NetworkInfos) } diff --git a/server/int/api/handlers.go b/server/int/api/handlers.go index e0170107..25a7af54 100644 --- a/server/int/api/handlers.go +++ b/server/int/api/handlers.go @@ -32,11 +32,12 @@ func defaultPageHandler(params operations.DefaultPageParams) middleware.Responde /*Handle get deweb public infos*/ type dewebInfo struct { - miscInfo interface{} + miscInfo interface{} + networkInfo config.NetworkInfos } -func NewDewebInfo(miscInfo interface{}) operations.GetDeWebInfoHandler { - return &dewebInfo{miscInfo: miscInfo} +func NewDewebInfo(miscInfo interface{}, networkInfo config.NetworkInfos) operations.GetDeWebInfoHandler { + return &dewebInfo{miscInfo: miscInfo, networkInfo: networkInfo} } func (dI *dewebInfo) Handle(params operations.GetDeWebInfoParams) middleware.Responder { @@ -49,6 +50,11 @@ func (dI *dewebInfo) Handle(params operations.GetDeWebInfoParams) middleware.Res App: "deweb", Version: config.Version, Misc: dI.miscInfo, + Network: &models.DeWebInfoNetwork{ + Network: dI.networkInfo.Network, + Version: dI.networkInfo.Version, + ChainID: int64(dI.networkInfo.ChainID), + }, }).WriteResponse(w, runtime) }) } From 6caab1283e47e63134fc291d075c5064618c0e0f Mon Sep 17 00:00:00 2001 From: thomas-senechal Date: Tue, 29 Apr 2025 17:49:55 +0200 Subject: [PATCH 41/57] Add Plugin API spec and generated files --- plugin/api/models/cache_settings.go | 83 +++ plugin/api/models/error.go | 88 +++ plugin/api/models/server_status.go | 219 ++++++++ plugin/api/models/settings.go | 130 +++++ plugin/api/pluginAPI-V0.yml | 163 ++++++ plugin/api/restapi/configure_deweb_plugin.go | 108 ++++ plugin/api/restapi/doc.go | 24 + plugin/api/restapi/embedded_spec.go | 499 +++++++++++++++++ plugin/api/restapi/operations/default_page.go | 56 ++ .../operations/default_page_parameters.go | 46 ++ .../operations/default_page_responses.go | 37 ++ .../operations/default_page_urlbuilder.go | 84 +++ .../restapi/operations/deweb_plugin_api.go | 403 ++++++++++++++ .../restapi/operations/get_server_status.go | 56 ++ .../get_server_status_parameters.go | 46 ++ .../operations/get_server_status_responses.go | 59 ++ .../get_server_status_urlbuilder.go | 84 +++ plugin/api/restapi/operations/get_settings.go | 56 ++ .../operations/get_settings_parameters.go | 46 ++ .../operations/get_settings_responses.go | 59 ++ .../operations/get_settings_urlbuilder.go | 84 +++ .../api/restapi/operations/plugin_web_app.go | 56 ++ .../operations/plugin_web_app_parameters.go | 71 +++ .../operations/plugin_web_app_responses.go | 84 +++ .../operations/plugin_web_app_urlbuilder.go | 96 ++++ .../api/restapi/operations/redirect_to_web.go | 56 ++ .../operations/redirect_to_web_parameters.go | 46 ++ .../operations/redirect_to_web_responses.go | 37 ++ .../operations/redirect_to_web_urlbuilder.go | 84 +++ .../api/restapi/operations/update_settings.go | 56 ++ .../operations/update_settings_parameters.go | 84 +++ .../operations/update_settings_responses.go | 84 +++ .../operations/update_settings_urlbuilder.go | 84 +++ plugin/api/restapi/server.go | 507 ++++++++++++++++++ 34 files changed, 3775 insertions(+) create mode 100644 plugin/api/models/cache_settings.go create mode 100644 plugin/api/models/error.go create mode 100644 plugin/api/models/server_status.go create mode 100644 plugin/api/models/settings.go create mode 100644 plugin/api/pluginAPI-V0.yml create mode 100644 plugin/api/restapi/configure_deweb_plugin.go create mode 100644 plugin/api/restapi/doc.go create mode 100644 plugin/api/restapi/embedded_spec.go create mode 100644 plugin/api/restapi/operations/default_page.go create mode 100644 plugin/api/restapi/operations/default_page_parameters.go create mode 100644 plugin/api/restapi/operations/default_page_responses.go create mode 100644 plugin/api/restapi/operations/default_page_urlbuilder.go create mode 100644 plugin/api/restapi/operations/deweb_plugin_api.go create mode 100644 plugin/api/restapi/operations/get_server_status.go create mode 100644 plugin/api/restapi/operations/get_server_status_parameters.go create mode 100644 plugin/api/restapi/operations/get_server_status_responses.go create mode 100644 plugin/api/restapi/operations/get_server_status_urlbuilder.go create mode 100644 plugin/api/restapi/operations/get_settings.go create mode 100644 plugin/api/restapi/operations/get_settings_parameters.go create mode 100644 plugin/api/restapi/operations/get_settings_responses.go create mode 100644 plugin/api/restapi/operations/get_settings_urlbuilder.go create mode 100644 plugin/api/restapi/operations/plugin_web_app.go create mode 100644 plugin/api/restapi/operations/plugin_web_app_parameters.go create mode 100644 plugin/api/restapi/operations/plugin_web_app_responses.go create mode 100644 plugin/api/restapi/operations/plugin_web_app_urlbuilder.go create mode 100644 plugin/api/restapi/operations/redirect_to_web.go create mode 100644 plugin/api/restapi/operations/redirect_to_web_parameters.go create mode 100644 plugin/api/restapi/operations/redirect_to_web_responses.go create mode 100644 plugin/api/restapi/operations/redirect_to_web_urlbuilder.go create mode 100644 plugin/api/restapi/operations/update_settings.go create mode 100644 plugin/api/restapi/operations/update_settings_parameters.go create mode 100644 plugin/api/restapi/operations/update_settings_responses.go create mode 100644 plugin/api/restapi/operations/update_settings_urlbuilder.go create mode 100644 plugin/api/restapi/server.go diff --git a/plugin/api/models/cache_settings.go b/plugin/api/models/cache_settings.go new file mode 100644 index 00000000..b76c0ffd --- /dev/null +++ b/plugin/api/models/cache_settings.go @@ -0,0 +1,83 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package models + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + + "github.com/go-openapi/errors" + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" + "github.com/go-openapi/validate" +) + +// CacheSettings cache settings +// +// swagger:model CacheSettings +type CacheSettings struct { + + // Directory to store the disk cache + DiskCacheDir string `json:"diskCacheDir,omitempty"` + + // Whether caching is enabled + // Required: true + Enabled *bool `json:"enabled"` + + // Duration in seconds for file list cache + FileListCacheDurationSeconds int32 `json:"fileListCacheDurationSeconds,omitempty"` + + // Maximum number of files stored in disk cache + SiteDiskCacheMaxItems int32 `json:"siteDiskCacheMaxItems,omitempty"` + + // Maximum number of files stored in RAM cache + SiteRAMCacheMaxItems int32 `json:"siteRamCacheMaxItems,omitempty"` +} + +// Validate validates this cache settings +func (m *CacheSettings) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validateEnabled(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *CacheSettings) validateEnabled(formats strfmt.Registry) error { + + if err := validate.Required("enabled", "body", m.Enabled); err != nil { + return err + } + + return nil +} + +// ContextValidate validates this cache settings based on context it is used +func (m *CacheSettings) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (m *CacheSettings) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *CacheSettings) UnmarshalBinary(b []byte) error { + var res CacheSettings + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/plugin/api/models/error.go b/plugin/api/models/error.go new file mode 100644 index 00000000..cc6855e1 --- /dev/null +++ b/plugin/api/models/error.go @@ -0,0 +1,88 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package models + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + + "github.com/go-openapi/errors" + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" + "github.com/go-openapi/validate" +) + +// Error error +// +// swagger:model Error +type Error struct { + + // code + // Required: true + Code *int32 `json:"code"` + + // message + // Required: true + Message *string `json:"message"` +} + +// Validate validates this error +func (m *Error) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validateCode(formats); err != nil { + res = append(res, err) + } + + if err := m.validateMessage(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *Error) validateCode(formats strfmt.Registry) error { + + if err := validate.Required("code", "body", m.Code); err != nil { + return err + } + + return nil +} + +func (m *Error) validateMessage(formats strfmt.Registry) error { + + if err := validate.Required("message", "body", m.Message); err != nil { + return err + } + + return nil +} + +// ContextValidate validates this error based on context it is used +func (m *Error) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (m *Error) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *Error) UnmarshalBinary(b []byte) error { + var res Error + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/plugin/api/models/server_status.go b/plugin/api/models/server_status.go new file mode 100644 index 00000000..821bf239 --- /dev/null +++ b/plugin/api/models/server_status.go @@ -0,0 +1,219 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package models + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "encoding/json" + + "github.com/go-openapi/errors" + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" + "github.com/go-openapi/validate" +) + +// ServerStatus server status +// +// swagger:model ServerStatus +type ServerStatus struct { + + // Error message if server failed to start or is in error state + ErrorMessage string `json:"errorMessage,omitempty"` + + // network + Network *ServerStatusNetwork `json:"network,omitempty"` + + // The port the server is running on + ServerPort int32 `json:"serverPort,omitempty"` + + // status + // Enum: ["running","stopped","starting","stopping","error"] + Status string `json:"status,omitempty"` +} + +// Validate validates this server status +func (m *ServerStatus) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validateNetwork(formats); err != nil { + res = append(res, err) + } + + if err := m.validateStatus(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *ServerStatus) validateNetwork(formats strfmt.Registry) error { + if swag.IsZero(m.Network) { // not required + return nil + } + + if m.Network != nil { + if err := m.Network.Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("network") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("network") + } + return err + } + } + + return nil +} + +var serverStatusTypeStatusPropEnum []interface{} + +func init() { + var res []string + if err := json.Unmarshal([]byte(`["running","stopped","starting","stopping","error"]`), &res); err != nil { + panic(err) + } + for _, v := range res { + serverStatusTypeStatusPropEnum = append(serverStatusTypeStatusPropEnum, v) + } +} + +const ( + + // ServerStatusStatusRunning captures enum value "running" + ServerStatusStatusRunning string = "running" + + // ServerStatusStatusStopped captures enum value "stopped" + ServerStatusStatusStopped string = "stopped" + + // ServerStatusStatusStarting captures enum value "starting" + ServerStatusStatusStarting string = "starting" + + // ServerStatusStatusStopping captures enum value "stopping" + ServerStatusStatusStopping string = "stopping" + + // ServerStatusStatusError captures enum value "error" + ServerStatusStatusError string = "error" +) + +// prop value enum +func (m *ServerStatus) validateStatusEnum(path, location string, value string) error { + if err := validate.EnumCase(path, location, value, serverStatusTypeStatusPropEnum, true); err != nil { + return err + } + return nil +} + +func (m *ServerStatus) validateStatus(formats strfmt.Registry) error { + if swag.IsZero(m.Status) { // not required + return nil + } + + // value enum + if err := m.validateStatusEnum("status", "body", m.Status); err != nil { + return err + } + + return nil +} + +// ContextValidate validate this server status based on the context it is used +func (m *ServerStatus) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + var res []error + + if err := m.contextValidateNetwork(ctx, formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *ServerStatus) contextValidateNetwork(ctx context.Context, formats strfmt.Registry) error { + + if m.Network != nil { + + if swag.IsZero(m.Network) { // not required + return nil + } + + if err := m.Network.ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("network") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("network") + } + return err + } + } + + return nil +} + +// MarshalBinary interface implementation +func (m *ServerStatus) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *ServerStatus) UnmarshalBinary(b []byte) error { + var res ServerStatus + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} + +// ServerStatusNetwork server status network +// +// swagger:model ServerStatusNetwork +type ServerStatusNetwork struct { + + // chain ID + ChainID uint64 `json:"chainID,omitempty"` + + // network + Network string `json:"network,omitempty"` + + // version + Version string `json:"version,omitempty"` +} + +// Validate validates this server status network +func (m *ServerStatusNetwork) Validate(formats strfmt.Registry) error { + return nil +} + +// ContextValidate validates this server status network based on context it is used +func (m *ServerStatusNetwork) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (m *ServerStatusNetwork) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *ServerStatusNetwork) UnmarshalBinary(b []byte) error { + var res ServerStatusNetwork + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/plugin/api/models/settings.go b/plugin/api/models/settings.go new file mode 100644 index 00000000..b86860f4 --- /dev/null +++ b/plugin/api/models/settings.go @@ -0,0 +1,130 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package models + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + + "github.com/go-openapi/errors" + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" + "github.com/go-openapi/validate" +) + +// Settings settings +// +// swagger:model Settings +type Settings struct { + + // cache + Cache *CacheSettings `json:"cache,omitempty"` + + // The network node URL to connect to + // Required: true + NetworkURL *string `json:"networkUrl"` + + // The port the server is running on + ServerPort int32 `json:"serverPort,omitempty"` +} + +// Validate validates this settings +func (m *Settings) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validateCache(formats); err != nil { + res = append(res, err) + } + + if err := m.validateNetworkURL(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *Settings) validateCache(formats strfmt.Registry) error { + if swag.IsZero(m.Cache) { // not required + return nil + } + + if m.Cache != nil { + if err := m.Cache.Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("cache") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("cache") + } + return err + } + } + + return nil +} + +func (m *Settings) validateNetworkURL(formats strfmt.Registry) error { + + if err := validate.Required("networkUrl", "body", m.NetworkURL); err != nil { + return err + } + + return nil +} + +// ContextValidate validate this settings based on the context it is used +func (m *Settings) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + var res []error + + if err := m.contextValidateCache(ctx, formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *Settings) contextValidateCache(ctx context.Context, formats strfmt.Registry) error { + + if m.Cache != nil { + + if swag.IsZero(m.Cache) { // not required + return nil + } + + if err := m.Cache.ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("cache") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("cache") + } + return err + } + } + + return nil +} + +// MarshalBinary interface implementation +func (m *Settings) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *Settings) UnmarshalBinary(b []byte) error { + var res Settings + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/plugin/api/pluginAPI-V0.yml b/plugin/api/pluginAPI-V0.yml new file mode 100644 index 00000000..ac206fd0 --- /dev/null +++ b/plugin/api/pluginAPI-V0.yml @@ -0,0 +1,163 @@ +swagger: "2.0" +info: + title: DeWeb Plugin API + description: API for the DeWeb Plugin in MassaStation + version: 0.0.1 + +schemes: + - http + +paths: + /web/{resource}: + get: + description: Plugin Frontend router. + operationId: PluginWebApp + produces: + - application/json + - text/javascript + - text/html + - text/css + - text/webp + - image/png + parameters: + - in: path + name: resource + required: true + type: string + description: Website resource. + responses: + "200": + description: Page found + "404": + description: Resource not found. + schema: + $ref: "#/definitions/Error" + + /: + get: + description: Handle the default page of the plugin + operationId: DefaultPage + responses: + "302": + description: Redirect to /web + + /api/server/status: + get: + description: Get the current server status + operationId: GetServerStatus + produces: + - application/json + responses: + "200": + description: Current server status + schema: + $ref: "#/definitions/ServerStatus" + + /api/settings: + get: + description: Get the current plugin settings + operationId: GetSettings + produces: + - application/json + responses: + "200": + description: Current settings + schema: + $ref: "#/definitions/Settings" + put: + description: Update plugin settings + operationId: UpdateSettings + consumes: + - application/json + produces: + - application/json + parameters: + - in: body + name: settings + description: New settings + required: true + schema: + $ref: "#/definitions/Settings" + responses: + "200": + description: Settings updated successfully + "400": + description: Error updating settings + schema: + $ref: "#/definitions/Error" + +definitions: + Error: + type: object + properties: + code: + type: integer + format: int32 + message: + type: string + required: + - code + - message + + ServerStatus: + type: object + properties: + status: + type: string + enum: [running, stopped, starting, stopping, error] + serverPort: + type: integer + format: int32 + description: The port the server is running on + errorMessage: + type: string + description: Error message if server failed to start or is in error state + network: + type: object + properties: + network: + type: string + version: + type: string + chainID: + type: integer + format: uint64 + + Settings: + type: object + properties: + networkUrl: + type: string + description: The network node URL to connect to + serverPort: + type: integer + format: int32 + description: The port the server is running on + cache: + $ref: "#/definitions/CacheSettings" + required: + - networkUrl + + CacheSettings: + type: object + properties: + enabled: + type: boolean + description: Whether caching is enabled + siteRamCacheMaxItems: + type: integer + format: int32 + description: Maximum number of files stored in RAM cache + siteDiskCacheMaxItems: + type: integer + format: int32 + description: Maximum number of files stored in disk cache + diskCacheDir: + type: string + description: Directory to store the disk cache + fileListCacheDurationSeconds: + type: integer + format: int32 + description: Duration in seconds for file list cache + required: + - enabled diff --git a/plugin/api/restapi/configure_deweb_plugin.go b/plugin/api/restapi/configure_deweb_plugin.go new file mode 100644 index 00000000..130c5316 --- /dev/null +++ b/plugin/api/restapi/configure_deweb_plugin.go @@ -0,0 +1,108 @@ +// This file is safe to edit. Once it exists it will not be overwritten + +package restapi + +import ( + "crypto/tls" + "io" + "net/http" + + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + "github.com/go-openapi/runtime/middleware" + "github.com/massalabs/deweb-plugin/api/restapi/operations" +) + +//go:generate swagger generate server --target ../../api --name DewebPlugin --spec ../pluginAPI-V0.yml --principal interface{} --exclude-main + +func configureFlags(api *operations.DewebPluginAPI) { + // api.CommandLineOptionsGroups = []swag.CommandLineOptionsGroup{ ... } +} + +func configureAPI(api *operations.DewebPluginAPI) http.Handler { + // configure the api here + api.ServeError = errors.ServeError + + // Set your custom logger if needed. Default one is log.Printf + // Expected interface func(string, ...interface{}) + // + // Example: + // api.Logger = log.Printf + + api.UseSwaggerUI() + // To continue using redoc as your UI, uncomment the following line + // api.UseRedoc() + + api.JSONConsumer = runtime.JSONConsumer() + + api.BinProducer = runtime.ByteStreamProducer() + api.CSSProducer = runtime.ProducerFunc(func(w io.Writer, data interface{}) error { + return errors.NotImplemented("css producer has not yet been implemented") + }) + api.HTMLProducer = runtime.ProducerFunc(func(w io.Writer, data interface{}) error { + return errors.NotImplemented("html producer has not yet been implemented") + }) + api.JsProducer = runtime.ProducerFunc(func(w io.Writer, data interface{}) error { + return errors.NotImplemented("js producer has not yet been implemented") + }) + api.JSONProducer = runtime.JSONProducer() + api.TextWebpProducer = runtime.ProducerFunc(func(w io.Writer, data interface{}) error { + return errors.NotImplemented("textWebp producer has not yet been implemented") + }) + + if api.GetServerStatusHandler == nil { + api.GetServerStatusHandler = operations.GetServerStatusHandlerFunc(func(params operations.GetServerStatusParams) middleware.Responder { + return middleware.NotImplemented("operation operations.GetServerStatus has not yet been implemented") + }) + } + if api.GetSettingsHandler == nil { + api.GetSettingsHandler = operations.GetSettingsHandlerFunc(func(params operations.GetSettingsParams) middleware.Responder { + return middleware.NotImplemented("operation operations.GetSettings has not yet been implemented") + }) + } + if api.PluginWebAppHandler == nil { + api.PluginWebAppHandler = operations.PluginWebAppHandlerFunc(func(params operations.PluginWebAppParams) middleware.Responder { + return middleware.NotImplemented("operation operations.PluginWebApp has not yet been implemented") + }) + } + if api.DefaultPageHandler == nil { + api.DefaultPageHandler = operations.DefaultPageHandlerFunc(func(params operations.DefaultPageParams) middleware.Responder { + return middleware.NotImplemented("operation operations.RedirectToWeb has not yet been implemented") + }) + } + if api.UpdateSettingsHandler == nil { + api.UpdateSettingsHandler = operations.UpdateSettingsHandlerFunc(func(params operations.UpdateSettingsParams) middleware.Responder { + return middleware.NotImplemented("operation operations.UpdateSettings has not yet been implemented") + }) + } + + api.PreServerShutdown = func() {} + + api.ServerShutdown = func() {} + + return setupGlobalMiddleware(api.Serve(setupMiddlewares)) +} + +// The TLS configuration before HTTPS server starts. +func configureTLS(tlsConfig *tls.Config) { + // Make all necessary changes to the TLS configuration here. +} + +// As soon as server is initialized but not run yet, this function will be called. +// If you need to modify a config, store server instance to stop it individually later, this is the place. +// This function can be called multiple times, depending on the number of serving schemes. +// scheme value will be set accordingly: "http", "https" or "unix". +func configureServer(s *http.Server, scheme, addr string) { +} + +// The middleware configuration is for the handler executors. These do not apply to the swagger.json document. +// The middleware executes after routing but before authentication, binding and validation. +func setupMiddlewares(handler http.Handler) http.Handler { + return handler +} + +// The middleware configuration happens before anything, this middleware also applies to serving the swagger.json document. +// So this is a good place to plug in a panic handling middleware, logging and metrics. +func setupGlobalMiddleware(handler http.Handler) http.Handler { + return handler +} diff --git a/plugin/api/restapi/doc.go b/plugin/api/restapi/doc.go new file mode 100644 index 00000000..1e1cd67a --- /dev/null +++ b/plugin/api/restapi/doc.go @@ -0,0 +1,24 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// Package restapi DeWeb Plugin API +// +// API for the DeWeb Plugin in MassaStation +// Schemes: +// http +// Host: localhost +// BasePath: / +// Version: 0.0.1 +// +// Consumes: +// - application/json +// +// Produces: +// - image/png +// - text/css +// - text/html +// - text/javascript +// - application/json +// - text/webp +// +// swagger:meta +package restapi diff --git a/plugin/api/restapi/embedded_spec.go b/plugin/api/restapi/embedded_spec.go new file mode 100644 index 00000000..72984cae --- /dev/null +++ b/plugin/api/restapi/embedded_spec.go @@ -0,0 +1,499 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package restapi + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "encoding/json" +) + +var ( + // SwaggerJSON embedded version of the swagger document used at generation time + SwaggerJSON json.RawMessage + // FlatSwaggerJSON embedded flattened version of the swagger document used at generation time + FlatSwaggerJSON json.RawMessage +) + +func init() { + SwaggerJSON = json.RawMessage([]byte(`{ + "schemes": [ + "http" + ], + "swagger": "2.0", + "info": { + "description": "API for the DeWeb Plugin in MassaStation", + "title": "DeWeb Plugin API", + "version": "0.0.1" + }, + "paths": { + "/": { + "get": { + "description": "Handle the default page of the plugin", + "operationId": "DefaultPage", + "responses": { + "302": { + "description": "Redirect to /web" + } + } + } + }, + "/api/server/status": { + "get": { + "description": "Get the current server status", + "produces": [ + "application/json" + ], + "operationId": "GetServerStatus", + "responses": { + "200": { + "description": "Current server status", + "schema": { + "$ref": "#/definitions/ServerStatus" + } + } + } + } + }, + "/api/settings": { + "get": { + "description": "Get the current plugin settings", + "produces": [ + "application/json" + ], + "operationId": "GetSettings", + "responses": { + "200": { + "description": "Current settings", + "schema": { + "$ref": "#/definitions/Settings" + } + } + } + }, + "put": { + "description": "Update plugin settings", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "operationId": "UpdateSettings", + "parameters": [ + { + "description": "New settings", + "name": "settings", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/Settings" + } + } + ], + "responses": { + "200": { + "description": "Settings updated successfully" + }, + "400": { + "description": "Error updating settings", + "schema": { + "$ref": "#/definitions/Error" + } + } + } + } + }, + "/web/{resource}": { + "get": { + "description": "Plugin Frontend router.", + "produces": [ + "application/json", + "text/javascript", + "text/html", + "text/css", + "text/webp", + "image/png" + ], + "operationId": "PluginWebApp", + "parameters": [ + { + "type": "string", + "description": "Website resource.", + "name": "resource", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "Page found" + }, + "404": { + "description": "Resource not found.", + "schema": { + "$ref": "#/definitions/Error" + } + } + } + } + } + }, + "definitions": { + "CacheSettings": { + "type": "object", + "required": [ + "enabled" + ], + "properties": { + "diskCacheDir": { + "description": "Directory to store the disk cache", + "type": "string" + }, + "enabled": { + "description": "Whether caching is enabled", + "type": "boolean" + }, + "fileListCacheDurationSeconds": { + "description": "Duration in seconds for file list cache", + "type": "integer", + "format": "int32" + }, + "siteDiskCacheMaxItems": { + "description": "Maximum number of files stored in disk cache", + "type": "integer", + "format": "int32" + }, + "siteRamCacheMaxItems": { + "description": "Maximum number of files stored in RAM cache", + "type": "integer", + "format": "int32" + } + } + }, + "Error": { + "type": "object", + "required": [ + "code", + "message" + ], + "properties": { + "code": { + "type": "integer", + "format": "int32" + }, + "message": { + "type": "string" + } + } + }, + "ServerStatus": { + "type": "object", + "properties": { + "errorMessage": { + "description": "Error message if server failed to start or is in error state", + "type": "string" + }, + "network": { + "type": "object", + "properties": { + "chainID": { + "type": "integer", + "format": "uint64" + }, + "network": { + "type": "string" + }, + "version": { + "type": "string" + } + } + }, + "serverPort": { + "description": "The port the server is running on", + "type": "integer", + "format": "int32" + }, + "status": { + "type": "string", + "enum": [ + "running", + "stopped", + "starting", + "stopping", + "error" + ] + } + } + }, + "Settings": { + "type": "object", + "required": [ + "networkUrl" + ], + "properties": { + "cache": { + "$ref": "#/definitions/CacheSettings" + }, + "networkUrl": { + "description": "The network node URL to connect to", + "type": "string" + }, + "serverPort": { + "description": "The port the server is running on", + "type": "integer", + "format": "int32" + } + } + } + } +}`)) + FlatSwaggerJSON = json.RawMessage([]byte(`{ + "schemes": [ + "http" + ], + "swagger": "2.0", + "info": { + "description": "API for the DeWeb Plugin in MassaStation", + "title": "DeWeb Plugin API", + "version": "0.0.1" + }, + "paths": { + "/": { + "get": { + "description": "Handle the default page of the plugin", + "operationId": "DefaultPage", + "responses": { + "302": { + "description": "Redirect to /web" + } + } + } + }, + "/api/server/status": { + "get": { + "description": "Get the current server status", + "produces": [ + "application/json" + ], + "operationId": "GetServerStatus", + "responses": { + "200": { + "description": "Current server status", + "schema": { + "$ref": "#/definitions/ServerStatus" + } + } + } + } + }, + "/api/settings": { + "get": { + "description": "Get the current plugin settings", + "produces": [ + "application/json" + ], + "operationId": "GetSettings", + "responses": { + "200": { + "description": "Current settings", + "schema": { + "$ref": "#/definitions/Settings" + } + } + } + }, + "put": { + "description": "Update plugin settings", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "operationId": "UpdateSettings", + "parameters": [ + { + "description": "New settings", + "name": "settings", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/Settings" + } + } + ], + "responses": { + "200": { + "description": "Settings updated successfully" + }, + "400": { + "description": "Error updating settings", + "schema": { + "$ref": "#/definitions/Error" + } + } + } + } + }, + "/web/{resource}": { + "get": { + "description": "Plugin Frontend router.", + "produces": [ + "application/json", + "text/javascript", + "text/html", + "text/css", + "text/webp", + "image/png" + ], + "operationId": "PluginWebApp", + "parameters": [ + { + "type": "string", + "description": "Website resource.", + "name": "resource", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "Page found" + }, + "404": { + "description": "Resource not found.", + "schema": { + "$ref": "#/definitions/Error" + } + } + } + } + } + }, + "definitions": { + "CacheSettings": { + "type": "object", + "required": [ + "enabled" + ], + "properties": { + "diskCacheDir": { + "description": "Directory to store the disk cache", + "type": "string" + }, + "enabled": { + "description": "Whether caching is enabled", + "type": "boolean" + }, + "fileListCacheDurationSeconds": { + "description": "Duration in seconds for file list cache", + "type": "integer", + "format": "int32" + }, + "siteDiskCacheMaxItems": { + "description": "Maximum number of files stored in disk cache", + "type": "integer", + "format": "int32" + }, + "siteRamCacheMaxItems": { + "description": "Maximum number of files stored in RAM cache", + "type": "integer", + "format": "int32" + } + } + }, + "Error": { + "type": "object", + "required": [ + "code", + "message" + ], + "properties": { + "code": { + "type": "integer", + "format": "int32" + }, + "message": { + "type": "string" + } + } + }, + "ServerStatus": { + "type": "object", + "properties": { + "errorMessage": { + "description": "Error message if server failed to start or is in error state", + "type": "string" + }, + "network": { + "type": "object", + "properties": { + "chainID": { + "type": "integer", + "format": "uint64" + }, + "network": { + "type": "string" + }, + "version": { + "type": "string" + } + } + }, + "serverPort": { + "description": "The port the server is running on", + "type": "integer", + "format": "int32" + }, + "status": { + "type": "string", + "enum": [ + "running", + "stopped", + "starting", + "stopping", + "error" + ] + } + } + }, + "ServerStatusNetwork": { + "type": "object", + "properties": { + "chainID": { + "type": "integer", + "format": "uint64" + }, + "network": { + "type": "string" + }, + "version": { + "type": "string" + } + } + }, + "Settings": { + "type": "object", + "required": [ + "networkUrl" + ], + "properties": { + "cache": { + "$ref": "#/definitions/CacheSettings" + }, + "networkUrl": { + "description": "The network node URL to connect to", + "type": "string" + }, + "serverPort": { + "description": "The port the server is running on", + "type": "integer", + "format": "int32" + } + } + } + } +}`)) +} diff --git a/plugin/api/restapi/operations/default_page.go b/plugin/api/restapi/operations/default_page.go new file mode 100644 index 00000000..3875419b --- /dev/null +++ b/plugin/api/restapi/operations/default_page.go @@ -0,0 +1,56 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package operations + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the generate command + +import ( + "net/http" + + "github.com/go-openapi/runtime/middleware" +) + +// DefaultPageHandlerFunc turns a function with the right signature into a default page handler +type DefaultPageHandlerFunc func(DefaultPageParams) middleware.Responder + +// Handle executing the request and returning a response +func (fn DefaultPageHandlerFunc) Handle(params DefaultPageParams) middleware.Responder { + return fn(params) +} + +// DefaultPageHandler interface for that can handle valid default page params +type DefaultPageHandler interface { + Handle(DefaultPageParams) middleware.Responder +} + +// NewDefaultPage creates a new http.Handler for the default page operation +func NewDefaultPage(ctx *middleware.Context, handler DefaultPageHandler) *DefaultPage { + return &DefaultPage{Context: ctx, Handler: handler} +} + +/* + DefaultPage swagger:route GET / defaultPage + +Handle the default page of the plugin +*/ +type DefaultPage struct { + Context *middleware.Context + Handler DefaultPageHandler +} + +func (o *DefaultPage) ServeHTTP(rw http.ResponseWriter, r *http.Request) { + route, rCtx, _ := o.Context.RouteInfo(r) + if rCtx != nil { + *r = *rCtx + } + var Params = NewDefaultPageParams() + if err := o.Context.BindValidRequest(r, route, &Params); err != nil { // bind params + o.Context.Respond(rw, r, route.Produces, route, err) + return + } + + res := o.Handler.Handle(Params) // actually handle the request + o.Context.Respond(rw, r, route.Produces, route, res) + +} diff --git a/plugin/api/restapi/operations/default_page_parameters.go b/plugin/api/restapi/operations/default_page_parameters.go new file mode 100644 index 00000000..fa657be3 --- /dev/null +++ b/plugin/api/restapi/operations/default_page_parameters.go @@ -0,0 +1,46 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package operations + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "net/http" + + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime/middleware" +) + +// NewDefaultPageParams creates a new DefaultPageParams object +// +// There are no default values defined in the spec. +func NewDefaultPageParams() DefaultPageParams { + + return DefaultPageParams{} +} + +// DefaultPageParams contains all the bound params for the default page operation +// typically these are obtained from a http.Request +// +// swagger:parameters DefaultPage +type DefaultPageParams struct { + + // HTTP Request Object + HTTPRequest *http.Request `json:"-"` +} + +// BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls. +// +// To ensure default values, the struct must have been initialized with NewDefaultPageParams() beforehand. +func (o *DefaultPageParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error { + var res []error + + o.HTTPRequest = r + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} diff --git a/plugin/api/restapi/operations/default_page_responses.go b/plugin/api/restapi/operations/default_page_responses.go new file mode 100644 index 00000000..d44d4ee7 --- /dev/null +++ b/plugin/api/restapi/operations/default_page_responses.go @@ -0,0 +1,37 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package operations + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "net/http" + + "github.com/go-openapi/runtime" +) + +// DefaultPageFoundCode is the HTTP code returned for type DefaultPageFound +const DefaultPageFoundCode int = 302 + +/* +DefaultPageFound Redirect to /web + +swagger:response defaultPageFound +*/ +type DefaultPageFound struct { +} + +// NewDefaultPageFound creates DefaultPageFound with default headers values +func NewDefaultPageFound() *DefaultPageFound { + + return &DefaultPageFound{} +} + +// WriteResponse to the client +func (o *DefaultPageFound) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { + + rw.Header().Del(runtime.HeaderContentType) //Remove Content-Type on empty responses + + rw.WriteHeader(302) +} diff --git a/plugin/api/restapi/operations/default_page_urlbuilder.go b/plugin/api/restapi/operations/default_page_urlbuilder.go new file mode 100644 index 00000000..75d057f0 --- /dev/null +++ b/plugin/api/restapi/operations/default_page_urlbuilder.go @@ -0,0 +1,84 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package operations + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the generate command + +import ( + "errors" + "net/url" + golangswaggerpaths "path" +) + +// DefaultPageURL generates an URL for the default page operation +type DefaultPageURL struct { + _basePath string +} + +// WithBasePath sets the base path for this url builder, only required when it's different from the +// base path specified in the swagger spec. +// When the value of the base path is an empty string +func (o *DefaultPageURL) WithBasePath(bp string) *DefaultPageURL { + o.SetBasePath(bp) + return o +} + +// SetBasePath sets the base path for this url builder, only required when it's different from the +// base path specified in the swagger spec. +// When the value of the base path is an empty string +func (o *DefaultPageURL) SetBasePath(bp string) { + o._basePath = bp +} + +// Build a url path and query string +func (o *DefaultPageURL) Build() (*url.URL, error) { + var _result url.URL + + var _path = "/" + + _basePath := o._basePath + _result.Path = golangswaggerpaths.Join(_basePath, _path) + + return &_result, nil +} + +// Must is a helper function to panic when the url builder returns an error +func (o *DefaultPageURL) Must(u *url.URL, err error) *url.URL { + if err != nil { + panic(err) + } + if u == nil { + panic("url can't be nil") + } + return u +} + +// String returns the string representation of the path with query string +func (o *DefaultPageURL) String() string { + return o.Must(o.Build()).String() +} + +// BuildFull builds a full url with scheme, host, path and query string +func (o *DefaultPageURL) BuildFull(scheme, host string) (*url.URL, error) { + if scheme == "" { + return nil, errors.New("scheme is required for a full url on DefaultPageURL") + } + if host == "" { + return nil, errors.New("host is required for a full url on DefaultPageURL") + } + + base, err := o.Build() + if err != nil { + return nil, err + } + + base.Scheme = scheme + base.Host = host + return base, nil +} + +// StringFull returns the string representation of a complete url +func (o *DefaultPageURL) StringFull(scheme, host string) string { + return o.Must(o.BuildFull(scheme, host)).String() +} diff --git a/plugin/api/restapi/operations/deweb_plugin_api.go b/plugin/api/restapi/operations/deweb_plugin_api.go new file mode 100644 index 00000000..2b120457 --- /dev/null +++ b/plugin/api/restapi/operations/deweb_plugin_api.go @@ -0,0 +1,403 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package operations + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "fmt" + "io" + "net/http" + "strings" + + "github.com/go-openapi/errors" + "github.com/go-openapi/loads" + "github.com/go-openapi/runtime" + "github.com/go-openapi/runtime/middleware" + "github.com/go-openapi/runtime/security" + "github.com/go-openapi/spec" + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" +) + +// NewDewebPluginAPI creates a new DewebPlugin instance +func NewDewebPluginAPI(spec *loads.Document) *DewebPluginAPI { + return &DewebPluginAPI{ + handlers: make(map[string]map[string]http.Handler), + formats: strfmt.Default, + defaultConsumes: "application/json", + defaultProduces: "application/json", + customConsumers: make(map[string]runtime.Consumer), + customProducers: make(map[string]runtime.Producer), + PreServerShutdown: func() {}, + ServerShutdown: func() {}, + spec: spec, + useSwaggerUI: false, + ServeError: errors.ServeError, + BasicAuthenticator: security.BasicAuth, + APIKeyAuthenticator: security.APIKeyAuth, + BearerAuthenticator: security.BearerAuth, + + JSONConsumer: runtime.JSONConsumer(), + + BinProducer: runtime.ByteStreamProducer(), + CSSProducer: runtime.ProducerFunc(func(w io.Writer, data interface{}) error { + return errors.NotImplemented("css producer has not yet been implemented") + }), + HTMLProducer: runtime.ProducerFunc(func(w io.Writer, data interface{}) error { + return errors.NotImplemented("html producer has not yet been implemented") + }), + JsProducer: runtime.ProducerFunc(func(w io.Writer, data interface{}) error { + return errors.NotImplemented("js producer has not yet been implemented") + }), + JSONProducer: runtime.JSONProducer(), + TextWebpProducer: runtime.ProducerFunc(func(w io.Writer, data interface{}) error { + return errors.NotImplemented("textWebp producer has not yet been implemented") + }), + + DefaultPageHandler: DefaultPageHandlerFunc(func(params DefaultPageParams) middleware.Responder { + return middleware.NotImplemented("operation DefaultPage has not yet been implemented") + }), + GetServerStatusHandler: GetServerStatusHandlerFunc(func(params GetServerStatusParams) middleware.Responder { + return middleware.NotImplemented("operation GetServerStatus has not yet been implemented") + }), + GetSettingsHandler: GetSettingsHandlerFunc(func(params GetSettingsParams) middleware.Responder { + return middleware.NotImplemented("operation GetSettings has not yet been implemented") + }), + PluginWebAppHandler: PluginWebAppHandlerFunc(func(params PluginWebAppParams) middleware.Responder { + return middleware.NotImplemented("operation PluginWebApp has not yet been implemented") + }), + UpdateSettingsHandler: UpdateSettingsHandlerFunc(func(params UpdateSettingsParams) middleware.Responder { + return middleware.NotImplemented("operation UpdateSettings has not yet been implemented") + }), + } +} + +/*DewebPluginAPI API for the DeWeb Plugin in MassaStation */ +type DewebPluginAPI struct { + spec *loads.Document + context *middleware.Context + handlers map[string]map[string]http.Handler + formats strfmt.Registry + customConsumers map[string]runtime.Consumer + customProducers map[string]runtime.Producer + defaultConsumes string + defaultProduces string + Middleware func(middleware.Builder) http.Handler + useSwaggerUI bool + + // BasicAuthenticator generates a runtime.Authenticator from the supplied basic auth function. + // It has a default implementation in the security package, however you can replace it for your particular usage. + BasicAuthenticator func(security.UserPassAuthentication) runtime.Authenticator + + // APIKeyAuthenticator generates a runtime.Authenticator from the supplied token auth function. + // It has a default implementation in the security package, however you can replace it for your particular usage. + APIKeyAuthenticator func(string, string, security.TokenAuthentication) runtime.Authenticator + + // BearerAuthenticator generates a runtime.Authenticator from the supplied bearer token auth function. + // It has a default implementation in the security package, however you can replace it for your particular usage. + BearerAuthenticator func(string, security.ScopedTokenAuthentication) runtime.Authenticator + + // JSONConsumer registers a consumer for the following mime types: + // - application/json + JSONConsumer runtime.Consumer + + // BinProducer registers a producer for the following mime types: + // - image/png + BinProducer runtime.Producer + // CSSProducer registers a producer for the following mime types: + // - text/css + CSSProducer runtime.Producer + // HTMLProducer registers a producer for the following mime types: + // - text/html + HTMLProducer runtime.Producer + // JsProducer registers a producer for the following mime types: + // - text/javascript + JsProducer runtime.Producer + // JSONProducer registers a producer for the following mime types: + // - application/json + JSONProducer runtime.Producer + // TextWebpProducer registers a producer for the following mime types: + // - text/webp + TextWebpProducer runtime.Producer + + // DefaultPageHandler sets the operation handler for the default page operation + DefaultPageHandler DefaultPageHandler + // GetServerStatusHandler sets the operation handler for the get server status operation + GetServerStatusHandler GetServerStatusHandler + // GetSettingsHandler sets the operation handler for the get settings operation + GetSettingsHandler GetSettingsHandler + // PluginWebAppHandler sets the operation handler for the plugin web app operation + PluginWebAppHandler PluginWebAppHandler + // UpdateSettingsHandler sets the operation handler for the update settings operation + UpdateSettingsHandler UpdateSettingsHandler + + // ServeError is called when an error is received, there is a default handler + // but you can set your own with this + ServeError func(http.ResponseWriter, *http.Request, error) + + // PreServerShutdown is called before the HTTP(S) server is shutdown + // This allows for custom functions to get executed before the HTTP(S) server stops accepting traffic + PreServerShutdown func() + + // ServerShutdown is called when the HTTP(S) server is shut down and done + // handling all active connections and does not accept connections any more + ServerShutdown func() + + // Custom command line argument groups with their descriptions + CommandLineOptionsGroups []swag.CommandLineOptionsGroup + + // User defined logger function. + Logger func(string, ...interface{}) +} + +// UseRedoc for documentation at /docs +func (o *DewebPluginAPI) UseRedoc() { + o.useSwaggerUI = false +} + +// UseSwaggerUI for documentation at /docs +func (o *DewebPluginAPI) UseSwaggerUI() { + o.useSwaggerUI = true +} + +// SetDefaultProduces sets the default produces media type +func (o *DewebPluginAPI) SetDefaultProduces(mediaType string) { + o.defaultProduces = mediaType +} + +// SetDefaultConsumes returns the default consumes media type +func (o *DewebPluginAPI) SetDefaultConsumes(mediaType string) { + o.defaultConsumes = mediaType +} + +// SetSpec sets a spec that will be served for the clients. +func (o *DewebPluginAPI) SetSpec(spec *loads.Document) { + o.spec = spec +} + +// DefaultProduces returns the default produces media type +func (o *DewebPluginAPI) DefaultProduces() string { + return o.defaultProduces +} + +// DefaultConsumes returns the default consumes media type +func (o *DewebPluginAPI) DefaultConsumes() string { + return o.defaultConsumes +} + +// Formats returns the registered string formats +func (o *DewebPluginAPI) Formats() strfmt.Registry { + return o.formats +} + +// RegisterFormat registers a custom format validator +func (o *DewebPluginAPI) RegisterFormat(name string, format strfmt.Format, validator strfmt.Validator) { + o.formats.Add(name, format, validator) +} + +// Validate validates the registrations in the DewebPluginAPI +func (o *DewebPluginAPI) Validate() error { + var unregistered []string + + if o.JSONConsumer == nil { + unregistered = append(unregistered, "JSONConsumer") + } + + if o.BinProducer == nil { + unregistered = append(unregistered, "BinProducer") + } + if o.CSSProducer == nil { + unregistered = append(unregistered, "CSSProducer") + } + if o.HTMLProducer == nil { + unregistered = append(unregistered, "HTMLProducer") + } + if o.JsProducer == nil { + unregistered = append(unregistered, "JsProducer") + } + if o.JSONProducer == nil { + unregistered = append(unregistered, "JSONProducer") + } + if o.TextWebpProducer == nil { + unregistered = append(unregistered, "TextWebpProducer") + } + + if o.DefaultPageHandler == nil { + unregistered = append(unregistered, "DefaultPageHandler") + } + if o.GetServerStatusHandler == nil { + unregistered = append(unregistered, "GetServerStatusHandler") + } + if o.GetSettingsHandler == nil { + unregistered = append(unregistered, "GetSettingsHandler") + } + if o.PluginWebAppHandler == nil { + unregistered = append(unregistered, "PluginWebAppHandler") + } + if o.UpdateSettingsHandler == nil { + unregistered = append(unregistered, "UpdateSettingsHandler") + } + + if len(unregistered) > 0 { + return fmt.Errorf("missing registration: %s", strings.Join(unregistered, ", ")) + } + + return nil +} + +// ServeErrorFor gets a error handler for a given operation id +func (o *DewebPluginAPI) ServeErrorFor(operationID string) func(http.ResponseWriter, *http.Request, error) { + return o.ServeError +} + +// AuthenticatorsFor gets the authenticators for the specified security schemes +func (o *DewebPluginAPI) AuthenticatorsFor(schemes map[string]spec.SecurityScheme) map[string]runtime.Authenticator { + return nil +} + +// Authorizer returns the registered authorizer +func (o *DewebPluginAPI) Authorizer() runtime.Authorizer { + return nil +} + +// ConsumersFor gets the consumers for the specified media types. +// MIME type parameters are ignored here. +func (o *DewebPluginAPI) ConsumersFor(mediaTypes []string) map[string]runtime.Consumer { + result := make(map[string]runtime.Consumer, len(mediaTypes)) + for _, mt := range mediaTypes { + switch mt { + case "application/json": + result["application/json"] = o.JSONConsumer + } + + if c, ok := o.customConsumers[mt]; ok { + result[mt] = c + } + } + return result +} + +// ProducersFor gets the producers for the specified media types. +// MIME type parameters are ignored here. +func (o *DewebPluginAPI) ProducersFor(mediaTypes []string) map[string]runtime.Producer { + result := make(map[string]runtime.Producer, len(mediaTypes)) + for _, mt := range mediaTypes { + switch mt { + case "image/png": + result["image/png"] = o.BinProducer + case "text/css": + result["text/css"] = o.CSSProducer + case "text/html": + result["text/html"] = o.HTMLProducer + case "text/javascript": + result["text/javascript"] = o.JsProducer + case "application/json": + result["application/json"] = o.JSONProducer + case "text/webp": + result["text/webp"] = o.TextWebpProducer + } + + if p, ok := o.customProducers[mt]; ok { + result[mt] = p + } + } + return result +} + +// HandlerFor gets a http.Handler for the provided operation method and path +func (o *DewebPluginAPI) HandlerFor(method, path string) (http.Handler, bool) { + if o.handlers == nil { + return nil, false + } + um := strings.ToUpper(method) + if _, ok := o.handlers[um]; !ok { + return nil, false + } + if path == "/" { + path = "" + } + h, ok := o.handlers[um][path] + return h, ok +} + +// Context returns the middleware context for the deweb plugin API +func (o *DewebPluginAPI) Context() *middleware.Context { + if o.context == nil { + o.context = middleware.NewRoutableContext(o.spec, o, nil) + } + + return o.context +} + +func (o *DewebPluginAPI) initHandlerCache() { + o.Context() // don't care about the result, just that the initialization happened + if o.handlers == nil { + o.handlers = make(map[string]map[string]http.Handler) + } + + if o.handlers["GET"] == nil { + o.handlers["GET"] = make(map[string]http.Handler) + } + o.handlers["GET"][""] = NewDefaultPage(o.context, o.DefaultPageHandler) + if o.handlers["GET"] == nil { + o.handlers["GET"] = make(map[string]http.Handler) + } + o.handlers["GET"]["/api/server/status"] = NewGetServerStatus(o.context, o.GetServerStatusHandler) + if o.handlers["GET"] == nil { + o.handlers["GET"] = make(map[string]http.Handler) + } + o.handlers["GET"]["/api/settings"] = NewGetSettings(o.context, o.GetSettingsHandler) + if o.handlers["GET"] == nil { + o.handlers["GET"] = make(map[string]http.Handler) + } + o.handlers["GET"]["/web/{resource}"] = NewPluginWebApp(o.context, o.PluginWebAppHandler) + if o.handlers["PUT"] == nil { + o.handlers["PUT"] = make(map[string]http.Handler) + } + o.handlers["PUT"]["/api/settings"] = NewUpdateSettings(o.context, o.UpdateSettingsHandler) +} + +// Serve creates a http handler to serve the API over HTTP +// can be used directly in http.ListenAndServe(":8000", api.Serve(nil)) +func (o *DewebPluginAPI) Serve(builder middleware.Builder) http.Handler { + o.Init() + + if o.Middleware != nil { + return o.Middleware(builder) + } + if o.useSwaggerUI { + return o.context.APIHandlerSwaggerUI(builder) + } + return o.context.APIHandler(builder) +} + +// Init allows you to just initialize the handler cache, you can then recompose the middleware as you see fit +func (o *DewebPluginAPI) Init() { + if len(o.handlers) == 0 { + o.initHandlerCache() + } +} + +// RegisterConsumer allows you to add (or override) a consumer for a media type. +func (o *DewebPluginAPI) RegisterConsumer(mediaType string, consumer runtime.Consumer) { + o.customConsumers[mediaType] = consumer +} + +// RegisterProducer allows you to add (or override) a producer for a media type. +func (o *DewebPluginAPI) RegisterProducer(mediaType string, producer runtime.Producer) { + o.customProducers[mediaType] = producer +} + +// AddMiddlewareFor adds a http middleware to existing handler +func (o *DewebPluginAPI) AddMiddlewareFor(method, path string, builder middleware.Builder) { + um := strings.ToUpper(method) + if path == "/" { + path = "" + } + o.Init() + if h, ok := o.handlers[um][path]; ok { + o.handlers[um][path] = builder(h) + } +} diff --git a/plugin/api/restapi/operations/get_server_status.go b/plugin/api/restapi/operations/get_server_status.go new file mode 100644 index 00000000..51c054a8 --- /dev/null +++ b/plugin/api/restapi/operations/get_server_status.go @@ -0,0 +1,56 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package operations + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the generate command + +import ( + "net/http" + + "github.com/go-openapi/runtime/middleware" +) + +// GetServerStatusHandlerFunc turns a function with the right signature into a get server status handler +type GetServerStatusHandlerFunc func(GetServerStatusParams) middleware.Responder + +// Handle executing the request and returning a response +func (fn GetServerStatusHandlerFunc) Handle(params GetServerStatusParams) middleware.Responder { + return fn(params) +} + +// GetServerStatusHandler interface for that can handle valid get server status params +type GetServerStatusHandler interface { + Handle(GetServerStatusParams) middleware.Responder +} + +// NewGetServerStatus creates a new http.Handler for the get server status operation +func NewGetServerStatus(ctx *middleware.Context, handler GetServerStatusHandler) *GetServerStatus { + return &GetServerStatus{Context: ctx, Handler: handler} +} + +/* + GetServerStatus swagger:route GET /api/server/status getServerStatus + +Get the current server status +*/ +type GetServerStatus struct { + Context *middleware.Context + Handler GetServerStatusHandler +} + +func (o *GetServerStatus) ServeHTTP(rw http.ResponseWriter, r *http.Request) { + route, rCtx, _ := o.Context.RouteInfo(r) + if rCtx != nil { + *r = *rCtx + } + var Params = NewGetServerStatusParams() + if err := o.Context.BindValidRequest(r, route, &Params); err != nil { // bind params + o.Context.Respond(rw, r, route.Produces, route, err) + return + } + + res := o.Handler.Handle(Params) // actually handle the request + o.Context.Respond(rw, r, route.Produces, route, res) + +} diff --git a/plugin/api/restapi/operations/get_server_status_parameters.go b/plugin/api/restapi/operations/get_server_status_parameters.go new file mode 100644 index 00000000..24499c0f --- /dev/null +++ b/plugin/api/restapi/operations/get_server_status_parameters.go @@ -0,0 +1,46 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package operations + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "net/http" + + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime/middleware" +) + +// NewGetServerStatusParams creates a new GetServerStatusParams object +// +// There are no default values defined in the spec. +func NewGetServerStatusParams() GetServerStatusParams { + + return GetServerStatusParams{} +} + +// GetServerStatusParams contains all the bound params for the get server status operation +// typically these are obtained from a http.Request +// +// swagger:parameters GetServerStatus +type GetServerStatusParams struct { + + // HTTP Request Object + HTTPRequest *http.Request `json:"-"` +} + +// BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls. +// +// To ensure default values, the struct must have been initialized with NewGetServerStatusParams() beforehand. +func (o *GetServerStatusParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error { + var res []error + + o.HTTPRequest = r + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} diff --git a/plugin/api/restapi/operations/get_server_status_responses.go b/plugin/api/restapi/operations/get_server_status_responses.go new file mode 100644 index 00000000..c83ebc56 --- /dev/null +++ b/plugin/api/restapi/operations/get_server_status_responses.go @@ -0,0 +1,59 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package operations + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "net/http" + + "github.com/go-openapi/runtime" + + "github.com/massalabs/deweb-plugin/api/models" +) + +// GetServerStatusOKCode is the HTTP code returned for type GetServerStatusOK +const GetServerStatusOKCode int = 200 + +/* +GetServerStatusOK Current server status + +swagger:response getServerStatusOK +*/ +type GetServerStatusOK struct { + + /* + In: Body + */ + Payload *models.ServerStatus `json:"body,omitempty"` +} + +// NewGetServerStatusOK creates GetServerStatusOK with default headers values +func NewGetServerStatusOK() *GetServerStatusOK { + + return &GetServerStatusOK{} +} + +// WithPayload adds the payload to the get server status o k response +func (o *GetServerStatusOK) WithPayload(payload *models.ServerStatus) *GetServerStatusOK { + o.Payload = payload + return o +} + +// SetPayload sets the payload to the get server status o k response +func (o *GetServerStatusOK) SetPayload(payload *models.ServerStatus) { + o.Payload = payload +} + +// WriteResponse to the client +func (o *GetServerStatusOK) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { + + rw.WriteHeader(200) + if o.Payload != nil { + payload := o.Payload + if err := producer.Produce(rw, payload); err != nil { + panic(err) // let the recovery middleware deal with this + } + } +} diff --git a/plugin/api/restapi/operations/get_server_status_urlbuilder.go b/plugin/api/restapi/operations/get_server_status_urlbuilder.go new file mode 100644 index 00000000..8ed2ed91 --- /dev/null +++ b/plugin/api/restapi/operations/get_server_status_urlbuilder.go @@ -0,0 +1,84 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package operations + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the generate command + +import ( + "errors" + "net/url" + golangswaggerpaths "path" +) + +// GetServerStatusURL generates an URL for the get server status operation +type GetServerStatusURL struct { + _basePath string +} + +// WithBasePath sets the base path for this url builder, only required when it's different from the +// base path specified in the swagger spec. +// When the value of the base path is an empty string +func (o *GetServerStatusURL) WithBasePath(bp string) *GetServerStatusURL { + o.SetBasePath(bp) + return o +} + +// SetBasePath sets the base path for this url builder, only required when it's different from the +// base path specified in the swagger spec. +// When the value of the base path is an empty string +func (o *GetServerStatusURL) SetBasePath(bp string) { + o._basePath = bp +} + +// Build a url path and query string +func (o *GetServerStatusURL) Build() (*url.URL, error) { + var _result url.URL + + var _path = "/api/server/status" + + _basePath := o._basePath + _result.Path = golangswaggerpaths.Join(_basePath, _path) + + return &_result, nil +} + +// Must is a helper function to panic when the url builder returns an error +func (o *GetServerStatusURL) Must(u *url.URL, err error) *url.URL { + if err != nil { + panic(err) + } + if u == nil { + panic("url can't be nil") + } + return u +} + +// String returns the string representation of the path with query string +func (o *GetServerStatusURL) String() string { + return o.Must(o.Build()).String() +} + +// BuildFull builds a full url with scheme, host, path and query string +func (o *GetServerStatusURL) BuildFull(scheme, host string) (*url.URL, error) { + if scheme == "" { + return nil, errors.New("scheme is required for a full url on GetServerStatusURL") + } + if host == "" { + return nil, errors.New("host is required for a full url on GetServerStatusURL") + } + + base, err := o.Build() + if err != nil { + return nil, err + } + + base.Scheme = scheme + base.Host = host + return base, nil +} + +// StringFull returns the string representation of a complete url +func (o *GetServerStatusURL) StringFull(scheme, host string) string { + return o.Must(o.BuildFull(scheme, host)).String() +} diff --git a/plugin/api/restapi/operations/get_settings.go b/plugin/api/restapi/operations/get_settings.go new file mode 100644 index 00000000..813e767d --- /dev/null +++ b/plugin/api/restapi/operations/get_settings.go @@ -0,0 +1,56 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package operations + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the generate command + +import ( + "net/http" + + "github.com/go-openapi/runtime/middleware" +) + +// GetSettingsHandlerFunc turns a function with the right signature into a get settings handler +type GetSettingsHandlerFunc func(GetSettingsParams) middleware.Responder + +// Handle executing the request and returning a response +func (fn GetSettingsHandlerFunc) Handle(params GetSettingsParams) middleware.Responder { + return fn(params) +} + +// GetSettingsHandler interface for that can handle valid get settings params +type GetSettingsHandler interface { + Handle(GetSettingsParams) middleware.Responder +} + +// NewGetSettings creates a new http.Handler for the get settings operation +func NewGetSettings(ctx *middleware.Context, handler GetSettingsHandler) *GetSettings { + return &GetSettings{Context: ctx, Handler: handler} +} + +/* + GetSettings swagger:route GET /api/settings getSettings + +Get the current plugin settings +*/ +type GetSettings struct { + Context *middleware.Context + Handler GetSettingsHandler +} + +func (o *GetSettings) ServeHTTP(rw http.ResponseWriter, r *http.Request) { + route, rCtx, _ := o.Context.RouteInfo(r) + if rCtx != nil { + *r = *rCtx + } + var Params = NewGetSettingsParams() + if err := o.Context.BindValidRequest(r, route, &Params); err != nil { // bind params + o.Context.Respond(rw, r, route.Produces, route, err) + return + } + + res := o.Handler.Handle(Params) // actually handle the request + o.Context.Respond(rw, r, route.Produces, route, res) + +} diff --git a/plugin/api/restapi/operations/get_settings_parameters.go b/plugin/api/restapi/operations/get_settings_parameters.go new file mode 100644 index 00000000..8b8fe5ba --- /dev/null +++ b/plugin/api/restapi/operations/get_settings_parameters.go @@ -0,0 +1,46 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package operations + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "net/http" + + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime/middleware" +) + +// NewGetSettingsParams creates a new GetSettingsParams object +// +// There are no default values defined in the spec. +func NewGetSettingsParams() GetSettingsParams { + + return GetSettingsParams{} +} + +// GetSettingsParams contains all the bound params for the get settings operation +// typically these are obtained from a http.Request +// +// swagger:parameters GetSettings +type GetSettingsParams struct { + + // HTTP Request Object + HTTPRequest *http.Request `json:"-"` +} + +// BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls. +// +// To ensure default values, the struct must have been initialized with NewGetSettingsParams() beforehand. +func (o *GetSettingsParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error { + var res []error + + o.HTTPRequest = r + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} diff --git a/plugin/api/restapi/operations/get_settings_responses.go b/plugin/api/restapi/operations/get_settings_responses.go new file mode 100644 index 00000000..137d50d4 --- /dev/null +++ b/plugin/api/restapi/operations/get_settings_responses.go @@ -0,0 +1,59 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package operations + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "net/http" + + "github.com/go-openapi/runtime" + + "github.com/massalabs/deweb-plugin/api/models" +) + +// GetSettingsOKCode is the HTTP code returned for type GetSettingsOK +const GetSettingsOKCode int = 200 + +/* +GetSettingsOK Current settings + +swagger:response getSettingsOK +*/ +type GetSettingsOK struct { + + /* + In: Body + */ + Payload *models.Settings `json:"body,omitempty"` +} + +// NewGetSettingsOK creates GetSettingsOK with default headers values +func NewGetSettingsOK() *GetSettingsOK { + + return &GetSettingsOK{} +} + +// WithPayload adds the payload to the get settings o k response +func (o *GetSettingsOK) WithPayload(payload *models.Settings) *GetSettingsOK { + o.Payload = payload + return o +} + +// SetPayload sets the payload to the get settings o k response +func (o *GetSettingsOK) SetPayload(payload *models.Settings) { + o.Payload = payload +} + +// WriteResponse to the client +func (o *GetSettingsOK) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { + + rw.WriteHeader(200) + if o.Payload != nil { + payload := o.Payload + if err := producer.Produce(rw, payload); err != nil { + panic(err) // let the recovery middleware deal with this + } + } +} diff --git a/plugin/api/restapi/operations/get_settings_urlbuilder.go b/plugin/api/restapi/operations/get_settings_urlbuilder.go new file mode 100644 index 00000000..cb477994 --- /dev/null +++ b/plugin/api/restapi/operations/get_settings_urlbuilder.go @@ -0,0 +1,84 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package operations + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the generate command + +import ( + "errors" + "net/url" + golangswaggerpaths "path" +) + +// GetSettingsURL generates an URL for the get settings operation +type GetSettingsURL struct { + _basePath string +} + +// WithBasePath sets the base path for this url builder, only required when it's different from the +// base path specified in the swagger spec. +// When the value of the base path is an empty string +func (o *GetSettingsURL) WithBasePath(bp string) *GetSettingsURL { + o.SetBasePath(bp) + return o +} + +// SetBasePath sets the base path for this url builder, only required when it's different from the +// base path specified in the swagger spec. +// When the value of the base path is an empty string +func (o *GetSettingsURL) SetBasePath(bp string) { + o._basePath = bp +} + +// Build a url path and query string +func (o *GetSettingsURL) Build() (*url.URL, error) { + var _result url.URL + + var _path = "/api/settings" + + _basePath := o._basePath + _result.Path = golangswaggerpaths.Join(_basePath, _path) + + return &_result, nil +} + +// Must is a helper function to panic when the url builder returns an error +func (o *GetSettingsURL) Must(u *url.URL, err error) *url.URL { + if err != nil { + panic(err) + } + if u == nil { + panic("url can't be nil") + } + return u +} + +// String returns the string representation of the path with query string +func (o *GetSettingsURL) String() string { + return o.Must(o.Build()).String() +} + +// BuildFull builds a full url with scheme, host, path and query string +func (o *GetSettingsURL) BuildFull(scheme, host string) (*url.URL, error) { + if scheme == "" { + return nil, errors.New("scheme is required for a full url on GetSettingsURL") + } + if host == "" { + return nil, errors.New("host is required for a full url on GetSettingsURL") + } + + base, err := o.Build() + if err != nil { + return nil, err + } + + base.Scheme = scheme + base.Host = host + return base, nil +} + +// StringFull returns the string representation of a complete url +func (o *GetSettingsURL) StringFull(scheme, host string) string { + return o.Must(o.BuildFull(scheme, host)).String() +} diff --git a/plugin/api/restapi/operations/plugin_web_app.go b/plugin/api/restapi/operations/plugin_web_app.go new file mode 100644 index 00000000..8d120f26 --- /dev/null +++ b/plugin/api/restapi/operations/plugin_web_app.go @@ -0,0 +1,56 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package operations + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the generate command + +import ( + "net/http" + + "github.com/go-openapi/runtime/middleware" +) + +// PluginWebAppHandlerFunc turns a function with the right signature into a plugin web app handler +type PluginWebAppHandlerFunc func(PluginWebAppParams) middleware.Responder + +// Handle executing the request and returning a response +func (fn PluginWebAppHandlerFunc) Handle(params PluginWebAppParams) middleware.Responder { + return fn(params) +} + +// PluginWebAppHandler interface for that can handle valid plugin web app params +type PluginWebAppHandler interface { + Handle(PluginWebAppParams) middleware.Responder +} + +// NewPluginWebApp creates a new http.Handler for the plugin web app operation +func NewPluginWebApp(ctx *middleware.Context, handler PluginWebAppHandler) *PluginWebApp { + return &PluginWebApp{Context: ctx, Handler: handler} +} + +/* + PluginWebApp swagger:route GET /web/{resource} pluginWebApp + +Plugin Frontend router. +*/ +type PluginWebApp struct { + Context *middleware.Context + Handler PluginWebAppHandler +} + +func (o *PluginWebApp) ServeHTTP(rw http.ResponseWriter, r *http.Request) { + route, rCtx, _ := o.Context.RouteInfo(r) + if rCtx != nil { + *r = *rCtx + } + var Params = NewPluginWebAppParams() + if err := o.Context.BindValidRequest(r, route, &Params); err != nil { // bind params + o.Context.Respond(rw, r, route.Produces, route, err) + return + } + + res := o.Handler.Handle(Params) // actually handle the request + o.Context.Respond(rw, r, route.Produces, route, res) + +} diff --git a/plugin/api/restapi/operations/plugin_web_app_parameters.go b/plugin/api/restapi/operations/plugin_web_app_parameters.go new file mode 100644 index 00000000..747bae53 --- /dev/null +++ b/plugin/api/restapi/operations/plugin_web_app_parameters.go @@ -0,0 +1,71 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package operations + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "net/http" + + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime/middleware" + "github.com/go-openapi/strfmt" +) + +// NewPluginWebAppParams creates a new PluginWebAppParams object +// +// There are no default values defined in the spec. +func NewPluginWebAppParams() PluginWebAppParams { + + return PluginWebAppParams{} +} + +// PluginWebAppParams contains all the bound params for the plugin web app operation +// typically these are obtained from a http.Request +// +// swagger:parameters PluginWebApp +type PluginWebAppParams struct { + + // HTTP Request Object + HTTPRequest *http.Request `json:"-"` + + /*Website resource. + Required: true + In: path + */ + Resource string +} + +// BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls. +// +// To ensure default values, the struct must have been initialized with NewPluginWebAppParams() beforehand. +func (o *PluginWebAppParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error { + var res []error + + o.HTTPRequest = r + + rResource, rhkResource, _ := route.Params.GetOK("resource") + if err := o.bindResource(rResource, rhkResource, route.Formats); err != nil { + res = append(res, err) + } + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +// bindResource binds and validates parameter Resource from path. +func (o *PluginWebAppParams) bindResource(rawData []string, hasKey bool, formats strfmt.Registry) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + // Required: true + // Parameter is provided by construction from the route + o.Resource = raw + + return nil +} diff --git a/plugin/api/restapi/operations/plugin_web_app_responses.go b/plugin/api/restapi/operations/plugin_web_app_responses.go new file mode 100644 index 00000000..1a282b02 --- /dev/null +++ b/plugin/api/restapi/operations/plugin_web_app_responses.go @@ -0,0 +1,84 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package operations + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "net/http" + + "github.com/go-openapi/runtime" + + "github.com/massalabs/deweb-plugin/api/models" +) + +// PluginWebAppOKCode is the HTTP code returned for type PluginWebAppOK +const PluginWebAppOKCode int = 200 + +/* +PluginWebAppOK Page found + +swagger:response pluginWebAppOK +*/ +type PluginWebAppOK struct { +} + +// NewPluginWebAppOK creates PluginWebAppOK with default headers values +func NewPluginWebAppOK() *PluginWebAppOK { + + return &PluginWebAppOK{} +} + +// WriteResponse to the client +func (o *PluginWebAppOK) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { + + rw.Header().Del(runtime.HeaderContentType) //Remove Content-Type on empty responses + + rw.WriteHeader(200) +} + +// PluginWebAppNotFoundCode is the HTTP code returned for type PluginWebAppNotFound +const PluginWebAppNotFoundCode int = 404 + +/* +PluginWebAppNotFound Resource not found. + +swagger:response pluginWebAppNotFound +*/ +type PluginWebAppNotFound struct { + + /* + In: Body + */ + Payload *models.Error `json:"body,omitempty"` +} + +// NewPluginWebAppNotFound creates PluginWebAppNotFound with default headers values +func NewPluginWebAppNotFound() *PluginWebAppNotFound { + + return &PluginWebAppNotFound{} +} + +// WithPayload adds the payload to the plugin web app not found response +func (o *PluginWebAppNotFound) WithPayload(payload *models.Error) *PluginWebAppNotFound { + o.Payload = payload + return o +} + +// SetPayload sets the payload to the plugin web app not found response +func (o *PluginWebAppNotFound) SetPayload(payload *models.Error) { + o.Payload = payload +} + +// WriteResponse to the client +func (o *PluginWebAppNotFound) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { + + rw.WriteHeader(404) + if o.Payload != nil { + payload := o.Payload + if err := producer.Produce(rw, payload); err != nil { + panic(err) // let the recovery middleware deal with this + } + } +} diff --git a/plugin/api/restapi/operations/plugin_web_app_urlbuilder.go b/plugin/api/restapi/operations/plugin_web_app_urlbuilder.go new file mode 100644 index 00000000..a642bde5 --- /dev/null +++ b/plugin/api/restapi/operations/plugin_web_app_urlbuilder.go @@ -0,0 +1,96 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package operations + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the generate command + +import ( + "errors" + "net/url" + golangswaggerpaths "path" + "strings" +) + +// PluginWebAppURL generates an URL for the plugin web app operation +type PluginWebAppURL struct { + Resource string + + _basePath string + // avoid unkeyed usage + _ struct{} +} + +// WithBasePath sets the base path for this url builder, only required when it's different from the +// base path specified in the swagger spec. +// When the value of the base path is an empty string +func (o *PluginWebAppURL) WithBasePath(bp string) *PluginWebAppURL { + o.SetBasePath(bp) + return o +} + +// SetBasePath sets the base path for this url builder, only required when it's different from the +// base path specified in the swagger spec. +// When the value of the base path is an empty string +func (o *PluginWebAppURL) SetBasePath(bp string) { + o._basePath = bp +} + +// Build a url path and query string +func (o *PluginWebAppURL) Build() (*url.URL, error) { + var _result url.URL + + var _path = "/web/{resource}" + + resource := o.Resource + if resource != "" { + _path = strings.Replace(_path, "{resource}", resource, -1) + } else { + return nil, errors.New("resource is required on PluginWebAppURL") + } + + _basePath := o._basePath + _result.Path = golangswaggerpaths.Join(_basePath, _path) + + return &_result, nil +} + +// Must is a helper function to panic when the url builder returns an error +func (o *PluginWebAppURL) Must(u *url.URL, err error) *url.URL { + if err != nil { + panic(err) + } + if u == nil { + panic("url can't be nil") + } + return u +} + +// String returns the string representation of the path with query string +func (o *PluginWebAppURL) String() string { + return o.Must(o.Build()).String() +} + +// BuildFull builds a full url with scheme, host, path and query string +func (o *PluginWebAppURL) BuildFull(scheme, host string) (*url.URL, error) { + if scheme == "" { + return nil, errors.New("scheme is required for a full url on PluginWebAppURL") + } + if host == "" { + return nil, errors.New("host is required for a full url on PluginWebAppURL") + } + + base, err := o.Build() + if err != nil { + return nil, err + } + + base.Scheme = scheme + base.Host = host + return base, nil +} + +// StringFull returns the string representation of a complete url +func (o *PluginWebAppURL) StringFull(scheme, host string) string { + return o.Must(o.BuildFull(scheme, host)).String() +} diff --git a/plugin/api/restapi/operations/redirect_to_web.go b/plugin/api/restapi/operations/redirect_to_web.go new file mode 100644 index 00000000..13fddb73 --- /dev/null +++ b/plugin/api/restapi/operations/redirect_to_web.go @@ -0,0 +1,56 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package operations + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the generate command + +import ( + "net/http" + + "github.com/go-openapi/runtime/middleware" +) + +// RedirectToWebHandlerFunc turns a function with the right signature into a redirect to web handler +type RedirectToWebHandlerFunc func(RedirectToWebParams) middleware.Responder + +// Handle executing the request and returning a response +func (fn RedirectToWebHandlerFunc) Handle(params RedirectToWebParams) middleware.Responder { + return fn(params) +} + +// RedirectToWebHandler interface for that can handle valid redirect to web params +type RedirectToWebHandler interface { + Handle(RedirectToWebParams) middleware.Responder +} + +// NewRedirectToWeb creates a new http.Handler for the redirect to web operation +func NewRedirectToWeb(ctx *middleware.Context, handler RedirectToWebHandler) *RedirectToWeb { + return &RedirectToWeb{Context: ctx, Handler: handler} +} + +/* + RedirectToWeb swagger:route GET / redirectToWeb + +Redirect to the web interface +*/ +type RedirectToWeb struct { + Context *middleware.Context + Handler RedirectToWebHandler +} + +func (o *RedirectToWeb) ServeHTTP(rw http.ResponseWriter, r *http.Request) { + route, rCtx, _ := o.Context.RouteInfo(r) + if rCtx != nil { + *r = *rCtx + } + var Params = NewRedirectToWebParams() + if err := o.Context.BindValidRequest(r, route, &Params); err != nil { // bind params + o.Context.Respond(rw, r, route.Produces, route, err) + return + } + + res := o.Handler.Handle(Params) // actually handle the request + o.Context.Respond(rw, r, route.Produces, route, res) + +} diff --git a/plugin/api/restapi/operations/redirect_to_web_parameters.go b/plugin/api/restapi/operations/redirect_to_web_parameters.go new file mode 100644 index 00000000..cd96de7c --- /dev/null +++ b/plugin/api/restapi/operations/redirect_to_web_parameters.go @@ -0,0 +1,46 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package operations + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "net/http" + + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime/middleware" +) + +// NewRedirectToWebParams creates a new RedirectToWebParams object +// +// There are no default values defined in the spec. +func NewRedirectToWebParams() RedirectToWebParams { + + return RedirectToWebParams{} +} + +// RedirectToWebParams contains all the bound params for the redirect to web operation +// typically these are obtained from a http.Request +// +// swagger:parameters RedirectToWeb +type RedirectToWebParams struct { + + // HTTP Request Object + HTTPRequest *http.Request `json:"-"` +} + +// BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls. +// +// To ensure default values, the struct must have been initialized with NewRedirectToWebParams() beforehand. +func (o *RedirectToWebParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error { + var res []error + + o.HTTPRequest = r + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} diff --git a/plugin/api/restapi/operations/redirect_to_web_responses.go b/plugin/api/restapi/operations/redirect_to_web_responses.go new file mode 100644 index 00000000..c10c84a0 --- /dev/null +++ b/plugin/api/restapi/operations/redirect_to_web_responses.go @@ -0,0 +1,37 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package operations + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "net/http" + + "github.com/go-openapi/runtime" +) + +// RedirectToWebFoundCode is the HTTP code returned for type RedirectToWebFound +const RedirectToWebFoundCode int = 302 + +/* +RedirectToWebFound Redirect to /web + +swagger:response redirectToWebFound +*/ +type RedirectToWebFound struct { +} + +// NewRedirectToWebFound creates RedirectToWebFound with default headers values +func NewRedirectToWebFound() *RedirectToWebFound { + + return &RedirectToWebFound{} +} + +// WriteResponse to the client +func (o *RedirectToWebFound) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { + + rw.Header().Del(runtime.HeaderContentType) //Remove Content-Type on empty responses + + rw.WriteHeader(302) +} diff --git a/plugin/api/restapi/operations/redirect_to_web_urlbuilder.go b/plugin/api/restapi/operations/redirect_to_web_urlbuilder.go new file mode 100644 index 00000000..85e08c46 --- /dev/null +++ b/plugin/api/restapi/operations/redirect_to_web_urlbuilder.go @@ -0,0 +1,84 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package operations + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the generate command + +import ( + "errors" + "net/url" + golangswaggerpaths "path" +) + +// RedirectToWebURL generates an URL for the redirect to web operation +type RedirectToWebURL struct { + _basePath string +} + +// WithBasePath sets the base path for this url builder, only required when it's different from the +// base path specified in the swagger spec. +// When the value of the base path is an empty string +func (o *RedirectToWebURL) WithBasePath(bp string) *RedirectToWebURL { + o.SetBasePath(bp) + return o +} + +// SetBasePath sets the base path for this url builder, only required when it's different from the +// base path specified in the swagger spec. +// When the value of the base path is an empty string +func (o *RedirectToWebURL) SetBasePath(bp string) { + o._basePath = bp +} + +// Build a url path and query string +func (o *RedirectToWebURL) Build() (*url.URL, error) { + var _result url.URL + + var _path = "/" + + _basePath := o._basePath + _result.Path = golangswaggerpaths.Join(_basePath, _path) + + return &_result, nil +} + +// Must is a helper function to panic when the url builder returns an error +func (o *RedirectToWebURL) Must(u *url.URL, err error) *url.URL { + if err != nil { + panic(err) + } + if u == nil { + panic("url can't be nil") + } + return u +} + +// String returns the string representation of the path with query string +func (o *RedirectToWebURL) String() string { + return o.Must(o.Build()).String() +} + +// BuildFull builds a full url with scheme, host, path and query string +func (o *RedirectToWebURL) BuildFull(scheme, host string) (*url.URL, error) { + if scheme == "" { + return nil, errors.New("scheme is required for a full url on RedirectToWebURL") + } + if host == "" { + return nil, errors.New("host is required for a full url on RedirectToWebURL") + } + + base, err := o.Build() + if err != nil { + return nil, err + } + + base.Scheme = scheme + base.Host = host + return base, nil +} + +// StringFull returns the string representation of a complete url +func (o *RedirectToWebURL) StringFull(scheme, host string) string { + return o.Must(o.BuildFull(scheme, host)).String() +} diff --git a/plugin/api/restapi/operations/update_settings.go b/plugin/api/restapi/operations/update_settings.go new file mode 100644 index 00000000..23ffc21b --- /dev/null +++ b/plugin/api/restapi/operations/update_settings.go @@ -0,0 +1,56 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package operations + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the generate command + +import ( + "net/http" + + "github.com/go-openapi/runtime/middleware" +) + +// UpdateSettingsHandlerFunc turns a function with the right signature into a update settings handler +type UpdateSettingsHandlerFunc func(UpdateSettingsParams) middleware.Responder + +// Handle executing the request and returning a response +func (fn UpdateSettingsHandlerFunc) Handle(params UpdateSettingsParams) middleware.Responder { + return fn(params) +} + +// UpdateSettingsHandler interface for that can handle valid update settings params +type UpdateSettingsHandler interface { + Handle(UpdateSettingsParams) middleware.Responder +} + +// NewUpdateSettings creates a new http.Handler for the update settings operation +func NewUpdateSettings(ctx *middleware.Context, handler UpdateSettingsHandler) *UpdateSettings { + return &UpdateSettings{Context: ctx, Handler: handler} +} + +/* + UpdateSettings swagger:route PUT /api/settings updateSettings + +Update plugin settings +*/ +type UpdateSettings struct { + Context *middleware.Context + Handler UpdateSettingsHandler +} + +func (o *UpdateSettings) ServeHTTP(rw http.ResponseWriter, r *http.Request) { + route, rCtx, _ := o.Context.RouteInfo(r) + if rCtx != nil { + *r = *rCtx + } + var Params = NewUpdateSettingsParams() + if err := o.Context.BindValidRequest(r, route, &Params); err != nil { // bind params + o.Context.Respond(rw, r, route.Produces, route, err) + return + } + + res := o.Handler.Handle(Params) // actually handle the request + o.Context.Respond(rw, r, route.Produces, route, res) + +} diff --git a/plugin/api/restapi/operations/update_settings_parameters.go b/plugin/api/restapi/operations/update_settings_parameters.go new file mode 100644 index 00000000..28c21f4b --- /dev/null +++ b/plugin/api/restapi/operations/update_settings_parameters.go @@ -0,0 +1,84 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package operations + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "io" + "net/http" + + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + "github.com/go-openapi/runtime/middleware" + "github.com/go-openapi/validate" + + "github.com/massalabs/deweb-plugin/api/models" +) + +// NewUpdateSettingsParams creates a new UpdateSettingsParams object +// +// There are no default values defined in the spec. +func NewUpdateSettingsParams() UpdateSettingsParams { + + return UpdateSettingsParams{} +} + +// UpdateSettingsParams contains all the bound params for the update settings operation +// typically these are obtained from a http.Request +// +// swagger:parameters UpdateSettings +type UpdateSettingsParams struct { + + // HTTP Request Object + HTTPRequest *http.Request `json:"-"` + + /*New settings + Required: true + In: body + */ + Settings *models.Settings +} + +// BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls. +// +// To ensure default values, the struct must have been initialized with NewUpdateSettingsParams() beforehand. +func (o *UpdateSettingsParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error { + var res []error + + o.HTTPRequest = r + + if runtime.HasBody(r) { + defer r.Body.Close() + var body models.Settings + if err := route.Consumer.Consume(r.Body, &body); err != nil { + if err == io.EOF { + res = append(res, errors.Required("settings", "body", "")) + } else { + res = append(res, errors.NewParseError("settings", "body", "", err)) + } + } else { + // validate body object + if err := body.Validate(route.Formats); err != nil { + res = append(res, err) + } + + ctx := validate.WithOperationRequest(r.Context()) + if err := body.ContextValidate(ctx, route.Formats); err != nil { + res = append(res, err) + } + + if len(res) == 0 { + o.Settings = &body + } + } + } else { + res = append(res, errors.Required("settings", "body", "")) + } + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} diff --git a/plugin/api/restapi/operations/update_settings_responses.go b/plugin/api/restapi/operations/update_settings_responses.go new file mode 100644 index 00000000..7a6aa6eb --- /dev/null +++ b/plugin/api/restapi/operations/update_settings_responses.go @@ -0,0 +1,84 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package operations + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "net/http" + + "github.com/go-openapi/runtime" + + "github.com/massalabs/deweb-plugin/api/models" +) + +// UpdateSettingsOKCode is the HTTP code returned for type UpdateSettingsOK +const UpdateSettingsOKCode int = 200 + +/* +UpdateSettingsOK Settings updated successfully + +swagger:response updateSettingsOK +*/ +type UpdateSettingsOK struct { +} + +// NewUpdateSettingsOK creates UpdateSettingsOK with default headers values +func NewUpdateSettingsOK() *UpdateSettingsOK { + + return &UpdateSettingsOK{} +} + +// WriteResponse to the client +func (o *UpdateSettingsOK) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { + + rw.Header().Del(runtime.HeaderContentType) //Remove Content-Type on empty responses + + rw.WriteHeader(200) +} + +// UpdateSettingsBadRequestCode is the HTTP code returned for type UpdateSettingsBadRequest +const UpdateSettingsBadRequestCode int = 400 + +/* +UpdateSettingsBadRequest Error updating settings + +swagger:response updateSettingsBadRequest +*/ +type UpdateSettingsBadRequest struct { + + /* + In: Body + */ + Payload *models.Error `json:"body,omitempty"` +} + +// NewUpdateSettingsBadRequest creates UpdateSettingsBadRequest with default headers values +func NewUpdateSettingsBadRequest() *UpdateSettingsBadRequest { + + return &UpdateSettingsBadRequest{} +} + +// WithPayload adds the payload to the update settings bad request response +func (o *UpdateSettingsBadRequest) WithPayload(payload *models.Error) *UpdateSettingsBadRequest { + o.Payload = payload + return o +} + +// SetPayload sets the payload to the update settings bad request response +func (o *UpdateSettingsBadRequest) SetPayload(payload *models.Error) { + o.Payload = payload +} + +// WriteResponse to the client +func (o *UpdateSettingsBadRequest) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { + + rw.WriteHeader(400) + if o.Payload != nil { + payload := o.Payload + if err := producer.Produce(rw, payload); err != nil { + panic(err) // let the recovery middleware deal with this + } + } +} diff --git a/plugin/api/restapi/operations/update_settings_urlbuilder.go b/plugin/api/restapi/operations/update_settings_urlbuilder.go new file mode 100644 index 00000000..7c8f78ef --- /dev/null +++ b/plugin/api/restapi/operations/update_settings_urlbuilder.go @@ -0,0 +1,84 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package operations + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the generate command + +import ( + "errors" + "net/url" + golangswaggerpaths "path" +) + +// UpdateSettingsURL generates an URL for the update settings operation +type UpdateSettingsURL struct { + _basePath string +} + +// WithBasePath sets the base path for this url builder, only required when it's different from the +// base path specified in the swagger spec. +// When the value of the base path is an empty string +func (o *UpdateSettingsURL) WithBasePath(bp string) *UpdateSettingsURL { + o.SetBasePath(bp) + return o +} + +// SetBasePath sets the base path for this url builder, only required when it's different from the +// base path specified in the swagger spec. +// When the value of the base path is an empty string +func (o *UpdateSettingsURL) SetBasePath(bp string) { + o._basePath = bp +} + +// Build a url path and query string +func (o *UpdateSettingsURL) Build() (*url.URL, error) { + var _result url.URL + + var _path = "/api/settings" + + _basePath := o._basePath + _result.Path = golangswaggerpaths.Join(_basePath, _path) + + return &_result, nil +} + +// Must is a helper function to panic when the url builder returns an error +func (o *UpdateSettingsURL) Must(u *url.URL, err error) *url.URL { + if err != nil { + panic(err) + } + if u == nil { + panic("url can't be nil") + } + return u +} + +// String returns the string representation of the path with query string +func (o *UpdateSettingsURL) String() string { + return o.Must(o.Build()).String() +} + +// BuildFull builds a full url with scheme, host, path and query string +func (o *UpdateSettingsURL) BuildFull(scheme, host string) (*url.URL, error) { + if scheme == "" { + return nil, errors.New("scheme is required for a full url on UpdateSettingsURL") + } + if host == "" { + return nil, errors.New("host is required for a full url on UpdateSettingsURL") + } + + base, err := o.Build() + if err != nil { + return nil, err + } + + base.Scheme = scheme + base.Host = host + return base, nil +} + +// StringFull returns the string representation of a complete url +func (o *UpdateSettingsURL) StringFull(scheme, host string) string { + return o.Must(o.BuildFull(scheme, host)).String() +} diff --git a/plugin/api/restapi/server.go b/plugin/api/restapi/server.go new file mode 100644 index 00000000..e25c6891 --- /dev/null +++ b/plugin/api/restapi/server.go @@ -0,0 +1,507 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package restapi + +import ( + "context" + "crypto/tls" + "crypto/x509" + "errors" + "fmt" + "log" + "net" + "net/http" + "os" + "os/signal" + "strconv" + "sync" + "sync/atomic" + "syscall" + "time" + + "github.com/go-openapi/runtime/flagext" + "github.com/go-openapi/swag" + flags "github.com/jessevdk/go-flags" + "golang.org/x/net/netutil" + + "github.com/massalabs/deweb-plugin/api/restapi/operations" +) + +const ( + schemeHTTP = "http" + schemeHTTPS = "https" + schemeUnix = "unix" +) + +var defaultSchemes []string + +func init() { + defaultSchemes = []string{ + schemeHTTP, + } +} + +// NewServer creates a new api deweb plugin server but does not configure it +func NewServer(api *operations.DewebPluginAPI) *Server { + s := new(Server) + + s.shutdown = make(chan struct{}) + s.api = api + s.interrupt = make(chan os.Signal, 1) + return s +} + +// ConfigureAPI configures the API and handlers. +func (s *Server) ConfigureAPI() { + if s.api != nil { + s.handler = configureAPI(s.api) + } +} + +// ConfigureFlags configures the additional flags defined by the handlers. Needs to be called before the parser.Parse +func (s *Server) ConfigureFlags() { + if s.api != nil { + configureFlags(s.api) + } +} + +// Server for the deweb plugin API +type Server struct { + EnabledListeners []string `long:"scheme" description:"the listeners to enable, this can be repeated and defaults to the schemes in the swagger spec"` + CleanupTimeout time.Duration `long:"cleanup-timeout" description:"grace period for which to wait before killing idle connections" default:"10s"` + GracefulTimeout time.Duration `long:"graceful-timeout" description:"grace period for which to wait before shutting down the server" default:"15s"` + MaxHeaderSize flagext.ByteSize `long:"max-header-size" description:"controls the maximum number of bytes the server will read parsing the request header's keys and values, including the request line. It does not limit the size of the request body." default:"1MiB"` + + SocketPath flags.Filename `long:"socket-path" description:"the unix socket to listen on" default:"/var/run/deweb-plugin.sock"` + domainSocketL net.Listener + + Host string `long:"host" description:"the IP to listen on" default:"localhost" env:"HOST"` + Port int `long:"port" description:"the port to listen on for insecure connections, defaults to a random value" env:"PORT"` + ListenLimit int `long:"listen-limit" description:"limit the number of outstanding requests"` + KeepAlive time.Duration `long:"keep-alive" description:"sets the TCP keep-alive timeouts on accepted connections. It prunes dead TCP connections ( e.g. closing laptop mid-download)" default:"3m"` + ReadTimeout time.Duration `long:"read-timeout" description:"maximum duration before timing out read of the request" default:"30s"` + WriteTimeout time.Duration `long:"write-timeout" description:"maximum duration before timing out write of the response" default:"30s"` + httpServerL net.Listener + + TLSHost string `long:"tls-host" description:"the IP to listen on for tls, when not specified it's the same as --host" env:"TLS_HOST"` + TLSPort int `long:"tls-port" description:"the port to listen on for secure connections, defaults to a random value" env:"TLS_PORT"` + TLSCertificate flags.Filename `long:"tls-certificate" description:"the certificate to use for secure connections" env:"TLS_CERTIFICATE"` + TLSCertificateKey flags.Filename `long:"tls-key" description:"the private key to use for secure connections" env:"TLS_PRIVATE_KEY"` + TLSCACertificate flags.Filename `long:"tls-ca" description:"the certificate authority file to be used with mutual tls auth" env:"TLS_CA_CERTIFICATE"` + TLSListenLimit int `long:"tls-listen-limit" description:"limit the number of outstanding requests"` + TLSKeepAlive time.Duration `long:"tls-keep-alive" description:"sets the TCP keep-alive timeouts on accepted connections. It prunes dead TCP connections ( e.g. closing laptop mid-download)"` + TLSReadTimeout time.Duration `long:"tls-read-timeout" description:"maximum duration before timing out read of the request"` + TLSWriteTimeout time.Duration `long:"tls-write-timeout" description:"maximum duration before timing out write of the response"` + httpsServerL net.Listener + + api *operations.DewebPluginAPI + handler http.Handler + hasListeners bool + shutdown chan struct{} + shuttingDown int32 + interrupted bool + interrupt chan os.Signal +} + +// Logf logs message either via defined user logger or via system one if no user logger is defined. +func (s *Server) Logf(f string, args ...interface{}) { + if s.api != nil && s.api.Logger != nil { + s.api.Logger(f, args...) + } else { + log.Printf(f, args...) + } +} + +// Fatalf logs message either via defined user logger or via system one if no user logger is defined. +// Exits with non-zero status after printing +func (s *Server) Fatalf(f string, args ...interface{}) { + if s.api != nil && s.api.Logger != nil { + s.api.Logger(f, args...) + os.Exit(1) + } else { + log.Fatalf(f, args...) + } +} + +// SetAPI configures the server with the specified API. Needs to be called before Serve +func (s *Server) SetAPI(api *operations.DewebPluginAPI) { + if api == nil { + s.api = nil + s.handler = nil + return + } + + s.api = api + s.handler = configureAPI(api) +} + +func (s *Server) hasScheme(scheme string) bool { + schemes := s.EnabledListeners + if len(schemes) == 0 { + schemes = defaultSchemes + } + + for _, v := range schemes { + if v == scheme { + return true + } + } + return false +} + +// Serve the api +func (s *Server) Serve() (err error) { + if !s.hasListeners { + if err = s.Listen(); err != nil { + return err + } + } + + // set default handler, if none is set + if s.handler == nil { + if s.api == nil { + return errors.New("can't create the default handler, as no api is set") + } + + s.SetHandler(s.api.Serve(nil)) + } + + wg := new(sync.WaitGroup) + once := new(sync.Once) + signalNotify(s.interrupt) + go handleInterrupt(once, s) + + servers := []*http.Server{} + + if s.hasScheme(schemeUnix) { + domainSocket := new(http.Server) + domainSocket.MaxHeaderBytes = int(s.MaxHeaderSize) + domainSocket.Handler = s.handler + if int64(s.CleanupTimeout) > 0 { + domainSocket.IdleTimeout = s.CleanupTimeout + } + + configureServer(domainSocket, "unix", string(s.SocketPath)) + + servers = append(servers, domainSocket) + wg.Add(1) + s.Logf("Serving deweb plugin at unix://%s", s.SocketPath) + go func(l net.Listener) { + defer wg.Done() + if err := domainSocket.Serve(l); err != nil && err != http.ErrServerClosed { + s.Fatalf("%v", err) + } + s.Logf("Stopped serving deweb plugin at unix://%s", s.SocketPath) + }(s.domainSocketL) + } + + if s.hasScheme(schemeHTTP) { + httpServer := new(http.Server) + httpServer.MaxHeaderBytes = int(s.MaxHeaderSize) + httpServer.ReadTimeout = s.ReadTimeout + httpServer.WriteTimeout = s.WriteTimeout + httpServer.SetKeepAlivesEnabled(int64(s.KeepAlive) > 0) + if s.ListenLimit > 0 { + s.httpServerL = netutil.LimitListener(s.httpServerL, s.ListenLimit) + } + + if int64(s.CleanupTimeout) > 0 { + httpServer.IdleTimeout = s.CleanupTimeout + } + + httpServer.Handler = s.handler + + configureServer(httpServer, "http", s.httpServerL.Addr().String()) + + servers = append(servers, httpServer) + wg.Add(1) + s.Logf("Serving deweb plugin at http://%s", s.httpServerL.Addr()) + go func(l net.Listener) { + defer wg.Done() + if err := httpServer.Serve(l); err != nil && err != http.ErrServerClosed { + s.Fatalf("%v", err) + } + s.Logf("Stopped serving deweb plugin at http://%s", l.Addr()) + }(s.httpServerL) + } + + if s.hasScheme(schemeHTTPS) { + httpsServer := new(http.Server) + httpsServer.MaxHeaderBytes = int(s.MaxHeaderSize) + httpsServer.ReadTimeout = s.TLSReadTimeout + httpsServer.WriteTimeout = s.TLSWriteTimeout + httpsServer.SetKeepAlivesEnabled(int64(s.TLSKeepAlive) > 0) + if s.TLSListenLimit > 0 { + s.httpsServerL = netutil.LimitListener(s.httpsServerL, s.TLSListenLimit) + } + if int64(s.CleanupTimeout) > 0 { + httpsServer.IdleTimeout = s.CleanupTimeout + } + httpsServer.Handler = s.handler + + // Inspired by https://blog.bracebin.com/achieving-perfect-ssl-labs-score-with-go + httpsServer.TLSConfig = &tls.Config{ + // Causes servers to use Go's default ciphersuite preferences, + // which are tuned to avoid attacks. Does nothing on clients. + PreferServerCipherSuites: true, + // Only use curves which have assembly implementations + // https://github.com/golang/go/tree/master/src/crypto/elliptic + CurvePreferences: []tls.CurveID{tls.CurveP256}, + // Use modern tls mode https://wiki.mozilla.org/Security/Server_Side_TLS#Modern_compatibility + NextProtos: []string{"h2", "http/1.1"}, + // https://www.owasp.org/index.php/Transport_Layer_Protection_Cheat_Sheet#Rule_-_Only_Support_Strong_Protocols + MinVersion: tls.VersionTLS12, + // These ciphersuites support Forward Secrecy: https://en.wikipedia.org/wiki/Forward_secrecy + CipherSuites: []uint16{ + tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, + tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, + }, + } + + // build standard config from server options + if s.TLSCertificate != "" && s.TLSCertificateKey != "" { + httpsServer.TLSConfig.Certificates = make([]tls.Certificate, 1) + httpsServer.TLSConfig.Certificates[0], err = tls.LoadX509KeyPair(string(s.TLSCertificate), string(s.TLSCertificateKey)) + if err != nil { + return err + } + } + + if s.TLSCACertificate != "" { + // include specified CA certificate + caCert, caCertErr := os.ReadFile(string(s.TLSCACertificate)) + if caCertErr != nil { + return caCertErr + } + caCertPool := x509.NewCertPool() + ok := caCertPool.AppendCertsFromPEM(caCert) + if !ok { + return fmt.Errorf("cannot parse CA certificate") + } + httpsServer.TLSConfig.ClientCAs = caCertPool + httpsServer.TLSConfig.ClientAuth = tls.RequireAndVerifyClientCert + } + + // call custom TLS configurator + configureTLS(httpsServer.TLSConfig) + + if len(httpsServer.TLSConfig.Certificates) == 0 && httpsServer.TLSConfig.GetCertificate == nil { + // after standard and custom config are passed, this ends up with no certificate + if s.TLSCertificate == "" { + if s.TLSCertificateKey == "" { + s.Fatalf("the required flags `--tls-certificate` and `--tls-key` were not specified") + } + s.Fatalf("the required flag `--tls-certificate` was not specified") + } + if s.TLSCertificateKey == "" { + s.Fatalf("the required flag `--tls-key` was not specified") + } + // this happens with a wrong custom TLS configurator + s.Fatalf("no certificate was configured for TLS") + } + + configureServer(httpsServer, "https", s.httpsServerL.Addr().String()) + + servers = append(servers, httpsServer) + wg.Add(1) + s.Logf("Serving deweb plugin at https://%s", s.httpsServerL.Addr()) + go func(l net.Listener) { + defer wg.Done() + if err := httpsServer.Serve(l); err != nil && err != http.ErrServerClosed { + s.Fatalf("%v", err) + } + s.Logf("Stopped serving deweb plugin at https://%s", l.Addr()) + }(tls.NewListener(s.httpsServerL, httpsServer.TLSConfig)) + } + + wg.Add(1) + go s.handleShutdown(wg, &servers) + + wg.Wait() + return nil +} + +// Listen creates the listeners for the server +func (s *Server) Listen() error { + if s.hasListeners { // already done this + return nil + } + + if s.hasScheme(schemeHTTPS) { + // Use http host if https host wasn't defined + if s.TLSHost == "" { + s.TLSHost = s.Host + } + // Use http listen limit if https listen limit wasn't defined + if s.TLSListenLimit == 0 { + s.TLSListenLimit = s.ListenLimit + } + // Use http tcp keep alive if https tcp keep alive wasn't defined + if int64(s.TLSKeepAlive) == 0 { + s.TLSKeepAlive = s.KeepAlive + } + // Use http read timeout if https read timeout wasn't defined + if int64(s.TLSReadTimeout) == 0 { + s.TLSReadTimeout = s.ReadTimeout + } + // Use http write timeout if https write timeout wasn't defined + if int64(s.TLSWriteTimeout) == 0 { + s.TLSWriteTimeout = s.WriteTimeout + } + } + + if s.hasScheme(schemeUnix) { + domSockListener, err := net.Listen("unix", string(s.SocketPath)) + if err != nil { + return err + } + s.domainSocketL = domSockListener + } + + if s.hasScheme(schemeHTTP) { + listener, err := net.Listen("tcp", net.JoinHostPort(s.Host, strconv.Itoa(s.Port))) + if err != nil { + return err + } + + h, p, err := swag.SplitHostPort(listener.Addr().String()) + if err != nil { + return err + } + s.Host = h + s.Port = p + s.httpServerL = listener + } + + if s.hasScheme(schemeHTTPS) { + tlsListener, err := net.Listen("tcp", net.JoinHostPort(s.TLSHost, strconv.Itoa(s.TLSPort))) + if err != nil { + return err + } + + sh, sp, err := swag.SplitHostPort(tlsListener.Addr().String()) + if err != nil { + return err + } + s.TLSHost = sh + s.TLSPort = sp + s.httpsServerL = tlsListener + } + + s.hasListeners = true + return nil +} + +// Shutdown server and clean up resources +func (s *Server) Shutdown() error { + if atomic.CompareAndSwapInt32(&s.shuttingDown, 0, 1) { + close(s.shutdown) + } + return nil +} + +func (s *Server) handleShutdown(wg *sync.WaitGroup, serversPtr *[]*http.Server) { + // wg.Done must occur last, after s.api.ServerShutdown() + // (to preserve old behaviour) + defer wg.Done() + + <-s.shutdown + + servers := *serversPtr + + ctx, cancel := context.WithTimeout(context.TODO(), s.GracefulTimeout) + defer cancel() + + // first execute the pre-shutdown hook + s.api.PreServerShutdown() + + shutdownChan := make(chan bool) + for i := range servers { + server := servers[i] + go func() { + var success bool + defer func() { + shutdownChan <- success + }() + if err := server.Shutdown(ctx); err != nil { + // Error from closing listeners, or context timeout: + s.Logf("HTTP server Shutdown: %v", err) + } else { + success = true + } + }() + } + + // Wait until all listeners have successfully shut down before calling ServerShutdown + success := true + for range servers { + success = success && <-shutdownChan + } + if success { + s.api.ServerShutdown() + } +} + +// GetHandler returns a handler useful for testing +func (s *Server) GetHandler() http.Handler { + return s.handler +} + +// SetHandler allows for setting a http handler on this server +func (s *Server) SetHandler(handler http.Handler) { + s.handler = handler +} + +// UnixListener returns the domain socket listener +func (s *Server) UnixListener() (net.Listener, error) { + if !s.hasListeners { + if err := s.Listen(); err != nil { + return nil, err + } + } + return s.domainSocketL, nil +} + +// HTTPListener returns the http listener +func (s *Server) HTTPListener() (net.Listener, error) { + if !s.hasListeners { + if err := s.Listen(); err != nil { + return nil, err + } + } + return s.httpServerL, nil +} + +// TLSListener returns the https listener +func (s *Server) TLSListener() (net.Listener, error) { + if !s.hasListeners { + if err := s.Listen(); err != nil { + return nil, err + } + } + return s.httpsServerL, nil +} + +func handleInterrupt(once *sync.Once, s *Server) { + once.Do(func() { + for range s.interrupt { + if s.interrupted { + s.Logf("Server already shutting down") + continue + } + s.interrupted = true + s.Logf("Shutting down... ") + if err := s.Shutdown(); err != nil { + s.Logf("HTTP server Shutdown: %v", err) + } + } + }) +} + +func signalNotify(interrupt chan<- os.Signal) { + signal.Notify(interrupt, syscall.SIGINT, syscall.SIGTERM) +} From 05e58fd9b7c2ca20b6052cccb3685e725d4fbf7c Mon Sep 17 00:00:00 2001 From: thomas-senechal Date: Tue, 29 Apr 2025 17:56:00 +0200 Subject: [PATCH 42/57] Update plugin frontend to show server status and build output to plugin api dir --- plugin/home/.env | 4 +- plugin/home/.env.massastation | 3 + plugin/home/README.md | 7 +- plugin/home/build.mjs | 32 ------- plugin/home/gen.go | 2 +- plugin/home/package.json | 3 +- plugin/home/src/App.tsx | 133 +++++++++++++++++++--------- plugin/home/src/QuickAccessItem.tsx | 20 +++++ plugin/home/src/types/server.ts | 28 ++++++ plugin/home/vite.config.ts | 5 +- 10 files changed, 151 insertions(+), 86 deletions(-) create mode 100644 plugin/home/.env.massastation delete mode 100644 plugin/home/build.mjs create mode 100644 plugin/home/src/QuickAccessItem.tsx create mode 100644 plugin/home/src/types/server.ts diff --git a/plugin/home/.env b/plugin/home/.env index d5999655..369c6d48 100644 --- a/plugin/home/.env +++ b/plugin/home/.env @@ -1 +1,3 @@ -BASE_URL=/plugin/massa-labs/deweb-plugin/ \ No newline at end of file +VITE_BASE_APP="" +VITE_BASE_API="" +VITE_ENV="dev" \ No newline at end of file diff --git a/plugin/home/.env.massastation b/plugin/home/.env.massastation new file mode 100644 index 00000000..afb17d4c --- /dev/null +++ b/plugin/home/.env.massastation @@ -0,0 +1,3 @@ +VITE_BASE_APP="/plugin/massa-labs/deweb-plugin/web" +VITE_BASE_API="/plugin/massa-labs/deweb-plugin/api" +VITE_ENV="massastation" \ No newline at end of file diff --git a/plugin/home/README.md b/plugin/home/README.md index 1605a64d..a3112158 100644 --- a/plugin/home/README.md +++ b/plugin/home/README.md @@ -41,14 +41,9 @@ The development server will start at http://localhost:5173 (or another port if 5 ```bash # Build the project npm run build - -# Build and package for plugin deployment -npm run build:plugin ``` -The `build:plugin` command will: -1. Build the project -2. Create a zip file (`dist/home.zip`) for deployment +The `build` command builds and output the project in the plugin `int/api/html` directory to be served by the plugin API. ## Dependencies diff --git a/plugin/home/build.mjs b/plugin/home/build.mjs deleted file mode 100644 index 97491700..00000000 --- a/plugin/home/build.mjs +++ /dev/null @@ -1,32 +0,0 @@ -import { execSync } from "child_process"; -import fs from "fs"; -import archiver from "archiver"; - -console.log(`Building home...`); -execSync(`npm run build`, { - stdio: "inherit", - env: { - ...process.env, - BASE_URL: "/plugin/massa-labs/deweb-plugin/", - }, -}); - -console.log(`Zipping home.zip...`); -const output = fs.createWriteStream(`./dist/home.zip`); -const archive = archiver('zip', { - zlib: { level: 9 } // Sets the compression level. -}); - -output.on('close', function () { - console.log(`home.zip has been created and contains ${archive.pointer()} total bytes`); -}); - -archive.on('error', function (err) { - throw err; -}); - -archive.pipe(output); - -archive.directory(`dist/`, false); - -archive.finalize(); diff --git a/plugin/home/gen.go b/plugin/home/gen.go index e30bf5e7..67a7dc93 100644 --- a/plugin/home/gen.go +++ b/plugin/home/gen.go @@ -1,4 +1,4 @@ package main //go:generate npm ci -//go:generate npm run build:plugin +//go:generate npm run build diff --git a/plugin/home/package.json b/plugin/home/package.json index 465ed662..66401137 100644 --- a/plugin/home/package.json +++ b/plugin/home/package.json @@ -5,8 +5,7 @@ "type": "module", "scripts": { "dev": "vite", - "build": "tsc -b && vite build", - "build:plugin": "node ./build.mjs", + "build": "tsc -b && vite build --mode massastation", "lint": "eslint .", "preview": "vite preview" }, diff --git a/plugin/home/src/App.tsx b/plugin/home/src/App.tsx index fa7cefdc..20b0f7cb 100644 --- a/plugin/home/src/App.tsx +++ b/plugin/home/src/App.tsx @@ -1,62 +1,109 @@ -import { FiSearch, FiInfo } from "react-icons/fi"; +import { FiSearch, FiInfo, FiCheckCircle, FiAlertTriangle, FiXCircle, FiClock } from "react-icons/fi"; import { useEffect, useState } from "react"; import { UseGenerateTheme } from "deweb-pages/src/hooks/UseGenerateTheme"; +import { ServerStatusResponse, NetworkInfo } from "./types/server"; +import { QuickAccessItem } from "./QuickAccessItem"; -type QuickAccessItemProps = { - path: string; - title: string; - description: string; - href: string; -}; - -const QuickAccessItem = ({ path, title, description, href }: QuickAccessItemProps) => ( - -
- {path} -
-

{title}

-

{description}

-
-); +const POLLING_INTERVAL = 1000; export default function App() { const [searchQuery, setSearchQuery] = useState(""); - const [port, setPort] = useState(""); - const [networkName, setNetworkName] = useState(null); - const [networkVersion, setNetworkVersion] = useState(null); + const [port, setPort] = useState(null); + const [status, setStatus] = useState<"running" | "stopped" | "starting" | "stopping" | "error" | null>(null); + const [network, setNetwork] = useState(undefined); const [loading, setLoading] = useState(true); + const [errorMessage, setErrorMessage] = useState(null); - // On mount, get the port from the API by hitting /port and network info from /info - useEffect(() => { + const fetchStatus = () => { const url = window.location.href.endsWith("/") ? window.location.href : `${window.location.href}/`; - fetch(`${url}port`) - .then((res) => res.text()) - .then((port) => setPort(port)) - .catch(err => console.error("Failed to fetch port:", err)); + const urlWithoutWeb = url.endsWith("/web/index/") ? url.slice(0, -10) : url; - fetch(`${url}info`) + fetch(`${urlWithoutWeb}/api/server/status`) .then((res) => res.json()) - .then((info) => { - setNetworkName(info.Network || "Unknown Network"); - setNetworkVersion(info.Version || "Unknown Version"); + .then((data: ServerStatusResponse) => { + setPort(data.serverPort); + setStatus(data.status); + setNetwork(data.network); + if (data.errorMessage) { + setErrorMessage(data.errorMessage); + } else { + setErrorMessage(null); + } }) - .catch(err => { - console.error("Failed to fetch provider info:", err); - setNetworkName("Unknown Network"); - setNetworkVersion("Unknown Version"); - }).finally(() => { + .catch(err => console.error("Failed to fetch port:", err)) + .finally(() => { setLoading(false); }); + }; + + // On mount, fetch status and set up polling interval + useEffect(() => { + fetchStatus(); + + // Set up polling interval to fetch status every POLLING_INTERVAL + const intervalId = setInterval(fetchStatus, POLLING_INTERVAL); + + // Clean up interval on component unmount + return () => clearInterval(intervalId); }, []); + const getStatusIcon = () => { + if (loading) return ; + + switch (status) { + case "running": + return ; + case "stopped": + return ; + case "starting": + case "stopping": + return ; + case "error": + return ; + default: + return ; + } + }; + + const getStatusText = () => { + if (loading) return "Connecting..."; + + if (status === "error" && errorMessage) { + return `Error: ${errorMessage}`; + } + + if (status === "running" && network) { + return `Connected to ${network.network} ${network.version || ''}`; + } + + const statusMessages = { + running: "Server running", + stopped: "Server stopped", + starting: "Server starting...", + stopping: "Server stopping...", + error: "Server error" + }; + + return statusMessages[status || "stopped"]; + }; + + const getStatusClass = () => { + if (loading) return "bg-blue-100 text-blue-800"; + + const statusClasses = { + running: "bg-green-100 text-green-800", + stopped: "bg-gray-100 text-gray-800", + starting: "bg-yellow-100 text-yellow-800", + stopping: "bg-yellow-100 text-yellow-800", + error: "bg-red-100 text-red-800" + }; + + return statusClasses[status || "stopped"]; + }; + const generateUrl = (service: string, path: string = '') => { const { host } = new URL(window.location.href); return host === "station.massa" && port @@ -100,9 +147,9 @@ export default function App() { className={`${theme} bg-primary text-secondary flex flex-col items-center justify-center min-h-screen text-center gap-8 p-8 relative`} > {/* Network Status Indicator */} -
- - {loading ? "Connecting..." : `Connected to ${networkName} ${networkVersion}`} +
+ {getStatusIcon()} + {getStatusText()}

Search on DeWeb

diff --git a/plugin/home/src/QuickAccessItem.tsx b/plugin/home/src/QuickAccessItem.tsx new file mode 100644 index 00000000..9bad6a05 --- /dev/null +++ b/plugin/home/src/QuickAccessItem.tsx @@ -0,0 +1,20 @@ +type QuickAccessItemProps = { + path: string; + title: string; + description: string; + href: string; +}; +export const QuickAccessItem = ({ path, title, description, href }: QuickAccessItemProps) => ( + +
+ {path} +
+

{title}

+

{description}

+
+); diff --git a/plugin/home/src/types/server.ts b/plugin/home/src/types/server.ts new file mode 100644 index 00000000..3aa46c19 --- /dev/null +++ b/plugin/home/src/types/server.ts @@ -0,0 +1,28 @@ +export type ServerStatus = 'running' | 'stopped' | 'starting' | 'stopping' | 'error'; + +export interface NetworkInfo { + network: string; + version: string; + chainID: number; +} + +export interface ServerStatusResponse { + status: ServerStatus; + serverPort: number; + errorMessage?: string; + network?: NetworkInfo; +} + +export interface CacheSettings { + enabled: boolean; + siteRamCacheMaxItems?: number; + siteDiskCacheMaxItems?: number; + diskCacheDir?: string; + fileListCacheDurationSeconds?: number; +} + +export interface Settings { + networkUrl: string; + serverPort?: number; + cache?: CacheSettings; +} \ No newline at end of file diff --git a/plugin/home/vite.config.ts b/plugin/home/vite.config.ts index 54abef61..84c68168 100644 --- a/plugin/home/vite.config.ts +++ b/plugin/home/vite.config.ts @@ -8,6 +8,9 @@ export default ({ mode }: any) => { return defineConfig({ plugins: [react()], - base: process.env.BASE_URL, + base: process.env.VITE_BASE_APP, + build: { + outDir: '../int/api/html/dist', + }, }) } From 0c51b9fec6d7e089533521e30b862aa218a6612b Mon Sep 17 00:00:00 2001 From: thomas-senechal Date: Tue, 29 Apr 2025 18:05:33 +0200 Subject: [PATCH 43/57] Add plugin API implem and configuration management --- plugin/.gitignore | 8 +- plugin/gen.go | 4 + plugin/go.mod | 62 ++++---- plugin/go.sum | 90 +++++------ plugin/int/api/api.go | 108 +++++++++++++ plugin/int/api/html/html.go | 54 +++++++ plugin/int/api/middleware.go | 29 ++++ plugin/int/api/server/handlers.go | 190 +++++++++++++++++++++++ plugin/int/server/config.go | 148 ++++++++++++++++++ plugin/int/server/errors.go | 21 +++ plugin/int/server/manager.go | 241 ++++++++++++++++++++++++++++++ plugin/int/server/status.go | 13 ++ plugin/main.go | 36 +---- 13 files changed, 881 insertions(+), 123 deletions(-) create mode 100644 plugin/gen.go create mode 100644 plugin/int/api/api.go create mode 100644 plugin/int/api/html/html.go create mode 100644 plugin/int/api/middleware.go create mode 100644 plugin/int/api/server/handlers.go create mode 100644 plugin/int/server/config.go create mode 100644 plugin/int/server/errors.go create mode 100644 plugin/int/server/manager.go create mode 100644 plugin/int/server/status.go diff --git a/plugin/.gitignore b/plugin/.gitignore index e9fa34e1..c251093d 100644 --- a/plugin/.gitignore +++ b/plugin/.gitignore @@ -1,2 +1,8 @@ +# build directory build/ -*.log \ No newline at end of file + +# generated files +int/api/html/dist/ + +# log files +*.log diff --git a/plugin/gen.go b/plugin/gen.go new file mode 100644 index 00000000..1a062293 --- /dev/null +++ b/plugin/gen.go @@ -0,0 +1,4 @@ +package main + +// Swagger API +//go:generate swagger generate server --quiet --target api --name DewebPlugin --spec api/pluginAPI-V0.yml --exclude-main diff --git a/plugin/go.mod b/plugin/go.mod index 39161925..51bb9e2f 100644 --- a/plugin/go.mod +++ b/plugin/go.mod @@ -7,65 +7,53 @@ toolchain go1.24.0 replace github.com/massalabs/deweb-server => ../server require ( - github.com/massalabs/deweb-server v0.0.0 - github.com/massalabs/station v0.6.5 + github.com/go-openapi/errors v0.22.1 + github.com/go-openapi/loads v0.22.0 + github.com/go-openapi/runtime v0.28.0 + github.com/go-openapi/spec v0.21.0 + github.com/go-openapi/strfmt v0.23.0 + github.com/go-openapi/swag v0.23.1 + github.com/go-openapi/validate v0.24.0 + github.com/jessevdk/go-flags v1.6.1 + github.com/massalabs/deweb-server v0.0.0-00010101000000-000000000000 + github.com/massalabs/station v0.6.9 + github.com/massalabs/station-massa-hello-world v0.0.11-0.20240503070604-6b14a27fcdff + github.com/massalabs/station-massa-wallet v0.4.5 + github.com/shirou/gopsutil/v4 v4.25.3 + golang.org/x/net v0.39.0 gopkg.in/yaml.v2 v2.4.0 ) require ( github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect - github.com/awnumar/memcall v0.1.2 // indirect - github.com/awnumar/memguard v0.22.3 // indirect github.com/btcsuite/btcutil v1.0.2 // indirect - github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/dgraph-io/badger/v4 v4.7.0 // indirect - github.com/dgraph-io/ristretto/v2 v2.2.0 // indirect github.com/docker/go-units v0.5.0 // indirect - github.com/dustin/go-humanize v1.0.1 // indirect - github.com/go-logr/logr v1.4.2 // indirect - github.com/go-logr/stdr v1.2.2 // indirect + github.com/ebitengine/purego v0.8.2 // indirect + github.com/go-ole/go-ole v1.2.6 // indirect github.com/go-openapi/analysis v0.23.0 // indirect - github.com/go-openapi/errors v0.22.0 // indirect github.com/go-openapi/jsonpointer v0.21.0 // indirect github.com/go-openapi/jsonreference v0.21.0 // indirect - github.com/go-openapi/loads v0.22.0 // indirect - github.com/go-openapi/runtime v0.28.0 // indirect - github.com/go-openapi/spec v0.21.0 // indirect - github.com/go-openapi/strfmt v0.23.0 // indirect - github.com/go-openapi/swag v0.23.0 // indirect - github.com/go-openapi/validate v0.24.0 // indirect - github.com/google/flatbuffers v25.2.10+incompatible // indirect github.com/google/uuid v1.6.0 // indirect - github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect - github.com/jessevdk/go-flags v1.6.1 // indirect github.com/josharian/intern v1.0.0 // indirect - github.com/klauspost/compress v1.18.0 // indirect - github.com/klauspost/cpuid/v2 v2.1.0 // indirect - github.com/mailru/easyjson v0.7.7 // indirect - github.com/massalabs/station-massa-hello-world v0.0.11-0.20240503070604-6b14a27fcdff // indirect - github.com/massalabs/station-massa-wallet v0.4.5 // indirect + github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect + github.com/mailru/easyjson v0.9.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/oklog/ulid v1.3.1 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect + github.com/rogpeppe/go-internal v1.13.1 // indirect github.com/shopspring/decimal v1.3.1 // indirect - github.com/stretchr/testify v1.10.0 // indirect + github.com/stretchr/objx v0.5.2 // indirect + github.com/tklauser/go-sysconf v0.3.12 // indirect + github.com/tklauser/numcpus v0.6.1 // indirect github.com/ybbus/jsonrpc/v3 v3.1.4 // indirect + github.com/yusufpapurcu/wmi v1.2.4 // indirect go.mongodb.org/mongo-driver v1.14.0 // indirect - go.opentelemetry.io/auto/sdk v1.1.0 // indirect - go.opentelemetry.io/otel v1.35.0 // indirect - go.opentelemetry.io/otel/metric v1.35.0 // indirect - go.opentelemetry.io/otel/trace v1.35.0 // indirect go.uber.org/atomic v1.10.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.24.0 // indirect - golang.org/x/crypto v0.36.0 // indirect - golang.org/x/net v0.38.0 // indirect golang.org/x/sync v0.10.0 // indirect - golang.org/x/sys v0.31.0 // indirect - google.golang.org/protobuf v1.36.6 // indirect + golang.org/x/sys v0.32.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect howett.net/plist v1.0.0 // indirect - lukechampine.com/blake3 v1.1.7 // indirect ) diff --git a/plugin/go.sum b/plugin/go.sum index cf0b8818..a80158b7 100644 --- a/plugin/go.sum +++ b/plugin/go.sum @@ -1,10 +1,6 @@ github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= -github.com/awnumar/memcall v0.1.2 h1:7gOfDTL+BJ6nnbtAp9+HQzUFjtP1hEseRQq8eP055QY= -github.com/awnumar/memcall v0.1.2/go.mod h1:S911igBPR9CThzd/hYQQmTc9SWNu3ZHIlCGaWsWsoJo= -github.com/awnumar/memguard v0.22.3 h1:b4sgUXtbUjhrGELPbuC62wU+BsPQy+8lkWed9Z+pj0Y= -github.com/awnumar/memguard v0.22.3/go.mod h1:mmGunnffnLHlxE5rRgQc3j+uwPZ27eYb61ccr8Clz2Y= github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= @@ -17,31 +13,20 @@ github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVa github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= -github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= -github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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/dgraph-io/badger/v4 v4.7.0 h1:Q+J8HApYAY7UMpL8d9owqiB+odzEc0zn/aqOD9jhc6Y= -github.com/dgraph-io/badger/v4 v4.7.0/go.mod h1:He7TzG3YBy3j4f5baj5B7Zl2XyfNe5bl4Udl0aPemVA= -github.com/dgraph-io/ristretto/v2 v2.2.0 h1:bkY3XzJcXoMuELV8F+vS8kzNgicwQFAaGINAEJdWGOM= -github.com/dgraph-io/ristretto/v2 v2.2.0/go.mod h1:RZrm63UmcBAaYWC1DotLYBmTvgkrs0+XhBd7Npn7/zI= -github.com/dgryski/go-farm v0.0.0-20240924180020-3414d57e47da h1:aIftn67I1fkbMa512G+w+Pxci9hJPB8oMnkcP3iZF38= -github.com/dgryski/go-farm v0.0.0-20240924180020-3414d57e47da/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -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/ebitengine/purego v0.8.2 h1:jPPGWs2sZ1UgOSgD2bClL0MJIqu58nOmIcBuXr62z1I= +github.com/ebitengine/purego v0.8.2/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= -github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= -github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= -github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= +github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-openapi/analysis v0.23.0 h1:aGday7OWupfMs+LbmLZG4k0MYXIANxcuBTYUC03zFCU= github.com/go-openapi/analysis v0.23.0/go.mod h1:9mz9ZWaSlV8TvjQHLl2mUW2PbZtemkE8yA5v22ohupo= -github.com/go-openapi/errors v0.22.0 h1:c4xY/OLxUBSTiepAg3j/MHuAv5mJhnf53LLMWFB+u/w= -github.com/go-openapi/errors v0.22.0/go.mod h1:J3DmZScxCDufmIMsdOuDHxJbdOGC0xtUynjIx092vXE= +github.com/go-openapi/errors v0.22.1 h1:kslMRRnK7NCb/CvR1q1VWuEQCEIsBGn5GgKD9e+HYhU= +github.com/go-openapi/errors v0.22.1/go.mod h1:+n/5UdIqdVnLIJ6Q9Se8HNGUXYaY6CN8ImWzfi/Gzp0= 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/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ= @@ -54,19 +39,16 @@ github.com/go-openapi/spec v0.21.0 h1:LTVzPc3p/RzRnkQqLRndbAzjY0d0BCL72A6j3CdL9Z github.com/go-openapi/spec v0.21.0/go.mod h1:78u6VdPw81XU44qEWGhtr982gJ5BWg2c0I5XwVMotYk= github.com/go-openapi/strfmt v0.23.0 h1:nlUS6BCqcnAk0pyhi9Y+kdDVZdZMHfEKQiS4HaMgO/c= github.com/go-openapi/strfmt v0.23.0/go.mod h1:NrtIpfKtWIygRkKVsxh7XQMDQW5HKQl6S5ik2elW+K4= -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-openapi/swag v0.23.1 h1:lpsStH0n2ittzTnbaSloVZLuB5+fvSY/+hnagBjSNZU= +github.com/go-openapi/swag v0.23.1/go.mod h1:STZs8TbRvEQQKUA+JZNAm3EWlgaOBGpyFDqQnDHMef0= github.com/go-openapi/validate v0.24.0 h1:LdfDKwNbpB6Vn40xhTdNZAnfLECL81w+VX3BumrGD58= github.com/go-openapi/validate v0.24.0/go.mod h1:iyeX1sEufmv3nPbBdX3ieNviWnOZaJ1+zquzJEf2BAQ= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/google/flatbuffers v25.2.10+incompatible h1:F3vclr7C3HpB1k9mxCGRMXq6FdUalZ6H/pNX4FP1v0Q= -github.com/google/flatbuffers v25.2.10+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -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/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= @@ -76,19 +58,16 @@ github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8Hm github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= -github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= -github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= -github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.1.0 h1:eyi1Ad2aNJMW95zcSbmGg7Cg6cq3ADwLpMAP96d8rF0= -github.com/klauspost/cpuid/v2 v2.1.0/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= 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/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/massalabs/station v0.6.5 h1:lkWWYB0/dPsRHSoAqN0wh/mFx8+InsVGMfraXQFZ76U= -github.com/massalabs/station v0.6.5/go.mod h1:i9d/zAqeDYxY0Od5LEfEkP6V2osUhA13GwA72ByM8bQ= +github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= +github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= +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/massalabs/station v0.6.9 h1:eampc2dndCq8BHUydRlcMSy1i1dBhxqI5tKWKGMMj+4= +github.com/massalabs/station v0.6.9/go.mod h1:fvIMuIS8v1/tu5e4FPvvqEJEcLsZN+wUD5OMSHD/rO8= github.com/massalabs/station-massa-hello-world v0.0.11-0.20240503070604-6b14a27fcdff h1:SZoRmXdbolVjhbsxO/3KWX8429Q1VnaQdQy0h718CqE= github.com/massalabs/station-massa-hello-world v0.0.11-0.20240503070604-6b14a27fcdff/go.mod h1:QbRHQvJFrm4mO+vPzr4Uiwa5REL/CgBlV4PDFdhewa0= github.com/massalabs/station-massa-wallet v0.4.5 h1:0rTHxGPlJ5cKjgB/yQclOBHbWiZO5rOwO0lT7ZjFuVQ= @@ -104,26 +83,28 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 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/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw= +github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= +github.com/shirou/gopsutil/v4 v4.25.3 h1:SeA68lsu8gLggyMbmCn8cmp97V1TI9ld9sVzAUcKcKE= +github.com/shirou/gopsutil/v4 v4.25.3/go.mod h1:xbuxyoZj+UsgnZrENu3lQivsngRR5BdjbJwf2fv4szA= github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= 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/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= +github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= +github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= +github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= github.com/ybbus/jsonrpc/v3 v3.1.4 h1:pPmgfWXnqR2GdIlealyCzmV6LV3nxm3w9gwA1B3cP3Y= github.com/ybbus/jsonrpc/v3 v3.1.4/go.mod h1:4HQTl0UzErqWGa6bSXhp8rIjifMAMa55E4D5wdhe768= +github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= +github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= go.mongodb.org/mongo-driver v1.14.0 h1:P98w8egYRjYe3XDjxhYJagTokP/H6HzlsnojRgZRd80= go.mongodb.org/mongo-driver v1.14.0/go.mod h1:Vzb0Mk/pa7e6cWw85R4F/endUC3u0U9jGcNU603k65c= -go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= -go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= -go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ= -go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y= -go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M= -go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE= -go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs= -go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc= go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= @@ -135,25 +116,24 @@ go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= -golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= -golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= +golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY= +golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 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.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= -golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= +golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= -google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 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= @@ -169,5 +149,3 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= howett.net/plist v1.0.0 h1:7CrbWYbPPO/PyNy38b2EB/+gYbjCe2DXBxgtOOZbSQM= howett.net/plist v1.0.0/go.mod h1:lqaXoTrLY4hg8tnEzNru53gicrbv7rrk+2xJA/7hw9g= -lukechampine.com/blake3 v1.1.7 h1:GgRMhmdsuK8+ii6UZFDL8Nb+VyMwadAgcJyfYHxG6n0= -lukechampine.com/blake3 v1.1.7/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= diff --git a/plugin/int/api/api.go b/plugin/int/api/api.go new file mode 100644 index 00000000..00ab2088 --- /dev/null +++ b/plugin/int/api/api.go @@ -0,0 +1,108 @@ +package api + +import ( + "log" + "net/http" + + "github.com/go-openapi/loads" + "github.com/massalabs/deweb-plugin/api/restapi" + "github.com/massalabs/deweb-plugin/api/restapi/operations" + "github.com/massalabs/deweb-plugin/int/api/html" + apiserver "github.com/massalabs/deweb-plugin/int/api/server" + "github.com/massalabs/deweb-plugin/int/server" + "github.com/massalabs/station-massa-hello-world/pkg/plugin" + "github.com/massalabs/station/pkg/logger" +) + +type API struct { + apiServer *restapi.Server + pluginAPI *operations.DewebPluginAPI + serverManager *server.ServerManager + configDir string +} + +// NewAPI creates a new API with the provided plugin directory +func NewAPI(configDir string) *API { + swaggerSpec, err := loads.Analyzed(restapi.SwaggerJSON, "") + if err != nil { + log.Fatalln(err) + } + + dewebAPI := operations.NewDewebPluginAPI(swaggerSpec) + apiServer := restapi.NewServer(dewebAPI) + + manager, err := server.NewServerManager(configDir) + if err != nil { + logger.Errorf("Failed to create server manager: %v", err) + } + + return &API{ + apiServer: apiServer, + pluginAPI: dewebAPI, + configDir: configDir, + serverManager: manager, + } +} + +// Start starts the API server. +func (a *API) Start() { + defer func() { + if err := a.apiServer.Shutdown(); err != nil { + log.Fatalln(err) + } + + // Shutdown the server manager if it is running + if a.serverManager != nil { + if err := a.serverManager.Stop(); err != nil { + logger.Errorf("Error stopping server on shutdown: %v", err) + } + } + }() + + // We don't care about the port of the plugin API as MassaStation will handle the port mapping + a.apiServer.Port = 0 + + a.configureAPI() + + a.apiServer.ConfigureAPI() + + a.apiServer.SetHandler(webAppMiddleware(a.pluginAPI.Serve(nil))) + + listener, err := a.apiServer.HTTPListener() + if err != nil { + logger.Fatalf("Failed to get HTTP listener: %v", err) + } + + if err := plugin.RegisterPlugin(listener); err != nil { + logger.Fatalf("Failed to register plugin: %v", err) + } + + // Start the server if manager exists + if a.serverManager != nil { + go func() { + if err := a.serverManager.Start(); err != nil && err != server.ErrServerAlreadyRunning { + logger.Errorf("Failed to start DeWeb server: %v", err) + } + }() + } + + if err := a.apiServer.Serve(); err != nil { + log.Fatalln(err) + } +} + +// ConfigureAPI sets up the API handlers and error handling. +func (a *API) configureAPI() { + a.pluginAPI.ServeError = func(w http.ResponseWriter, r *http.Request, err error) { + log.Printf("ServeError: %v", err) + w.WriteHeader(http.StatusInternalServerError) + } + + html.AppendEndpoints(a.pluginAPI) + + if a.serverManager != nil { + apiserver.RegisterHandlers(a.pluginAPI, a.serverManager, a.configDir) + } else { + logger.Errorf("Server manager not available for registering handlers") + } +} diff --git a/plugin/int/api/html/html.go b/plugin/int/api/html/html.go new file mode 100644 index 00000000..d9685516 --- /dev/null +++ b/plugin/int/api/html/html.go @@ -0,0 +1,54 @@ +package html + +import ( + "embed" + "mime" + "net/http" + "path/filepath" + + "github.com/go-openapi/runtime/middleware" + "github.com/massalabs/deweb-plugin/api/restapi/operations" + "github.com/massalabs/station-massa-wallet/pkg/openapi" +) + +const ( + indexHTML = "index.html" + basePathWebApp = "dist/" +) + +//nolint:typecheck +//go:embed dist +var contentWebApp embed.FS + +// Handle a Web request. +func HandleWebApp(params operations.PluginWebAppParams) middleware.Responder { + resourceName := params.Resource + + resourceContent, err := contentWebApp.ReadFile(basePathWebApp + resourceName) + if err != nil { + resourceName = "index.html" + + resourceContent, err = contentWebApp.ReadFile(basePathWebApp + resourceName) + if err != nil { + return operations.NewPluginWebAppNotFound() + } + } + + fileExtension := filepath.Ext(resourceName) + + mimeType := mime.TypeByExtension(fileExtension) + + header := map[string]string{"Content-Type": mimeType} + + return openapi.NewCustomResponder(resourceContent, header, http.StatusOK) +} + +// DefaultRedirectHandler redirects request to "/" URL to "web/index" +func DefaultRedirectHandler(_ operations.DefaultPageParams) middleware.Responder { + return openapi.NewCustomResponder(nil, map[string]string{"Location": "web/index"}, http.StatusPermanentRedirect) +} + +// AppendEndpoints appends web endpoints to the API. +func AppendEndpoints(api *operations.DewebPluginAPI) { + api.DefaultPageHandler = operations.DefaultPageHandlerFunc(DefaultRedirectHandler) +} diff --git a/plugin/int/api/middleware.go b/plugin/int/api/middleware.go new file mode 100644 index 00000000..ebde0ba9 --- /dev/null +++ b/plugin/int/api/middleware.go @@ -0,0 +1,29 @@ +package api + +import ( + "net/http" + "strings" + + "github.com/go-openapi/runtime" + "github.com/massalabs/deweb-plugin/api/restapi/operations" + "github.com/massalabs/deweb-plugin/int/api/html" +) + +const frontendPrefix = "/web/" + +func webAppMiddleware(handler http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if strings.HasPrefix(r.URL.Path, frontendPrefix) { + params := operations.PluginWebAppParams{ + HTTPRequest: r, + Resource: strings.TrimPrefix(r.URL.Path, frontendPrefix), + } + responder := html.HandleWebApp(params) + responder.WriteResponse(w, runtime.JSONProducer()) + + return + } + + handler.ServeHTTP(w, r) + }) +} diff --git a/plugin/int/api/server/handlers.go b/plugin/int/api/server/handlers.go new file mode 100644 index 00000000..87c0e3d0 --- /dev/null +++ b/plugin/int/api/server/handlers.go @@ -0,0 +1,190 @@ +package server + +import ( + "net/http" + "os" + "path/filepath" + + "github.com/go-openapi/runtime" + "github.com/go-openapi/runtime/middleware" + "github.com/massalabs/deweb-plugin/api/models" + "github.com/massalabs/deweb-plugin/api/restapi/operations" + "github.com/massalabs/deweb-plugin/int/server" + "github.com/massalabs/deweb-server/int/api/config" + "github.com/massalabs/station/pkg/logger" + "gopkg.in/yaml.v2" +) + +// RegisterHandlers registers the server-related API handlers +func RegisterHandlers(api *operations.DewebPluginAPI, manager *server.ServerManager, configDir string) { + configPath := filepath.Join(configDir, "deweb_server_config.yaml") + + api.GetServerStatusHandler = operations.GetServerStatusHandlerFunc(handleGetServerStatus(manager)) + api.GetSettingsHandler = operations.GetSettingsHandlerFunc(handleGetSettings(configPath)) + api.UpdateSettingsHandler = operations.UpdateSettingsHandlerFunc(handleUpdateSettings(manager, configPath)) +} + +// handleGetServerStatus returns a handler function for the GET /api/server/status endpoint +func handleGetServerStatus(manager *server.ServerManager) func(operations.GetServerStatusParams) middleware.Responder { + return func(params operations.GetServerStatusParams) middleware.Responder { + status := manager.GetStatus() + + response := &models.ServerStatus{ + Status: string(status), + } + + if status == server.StatusError { + errorMsg := manager.GetLastError() + response.ErrorMessage = errorMsg + } + + if status == server.StatusRunning { + serverConfig, err := manager.GetConfig() + if err != nil { + return createErrorResponse(http.StatusInternalServerError, "Failed to get server config") + } + + response.Network = &models.ServerStatusNetwork{ + ChainID: serverConfig.NetworkInfos.ChainID, + Network: serverConfig.NetworkInfos.Network, + Version: serverConfig.NetworkInfos.Version, + } + + apiPort, err := manager.GetServerPort() + if err != nil { + return createErrorResponse(http.StatusInternalServerError, "Failed to get server port") + } + + response.ServerPort = int32(apiPort) + } + + return operations.NewGetServerStatusOK().WithPayload(response) + } +} + +// handleGetSettings returns a handler function for the GET /api/settings endpoint +func handleGetSettings(configPath string) func(operations.GetSettingsParams) middleware.Responder { + return func(params operations.GetSettingsParams) middleware.Responder { + serverConfig, err := config.LoadServerConfig(configPath) + if err != nil { + return createErrorResponse(http.StatusInternalServerError, "Failed to load server configuration") + } + + // Map server config to API model + networkURL := serverConfig.NetworkInfos.NodeURL + enabled := serverConfig.CacheConfig.Enabled + diskCacheDir := serverConfig.CacheConfig.DiskCacheDir + + cacheSettings := &models.CacheSettings{ + Enabled: &enabled, + SiteRAMCacheMaxItems: int32(serverConfig.CacheConfig.SiteRAMCacheMaxItems), + SiteDiskCacheMaxItems: int32(serverConfig.CacheConfig.SiteDiskCacheMaxItems), + DiskCacheDir: diskCacheDir, + FileListCacheDurationSeconds: int32(serverConfig.CacheConfig.FileListCacheDurationSeconds), + } + + return operations.NewGetSettingsOK().WithPayload(&models.Settings{ + NetworkURL: &networkURL, + ServerPort: int32(serverConfig.APIPort), + Cache: cacheSettings, + }) + } +} + +// handleUpdateSettings returns a handler function for the PUT /api/settings endpoint +func handleUpdateSettings(manager *server.ServerManager, configPath string) func(operations.UpdateSettingsParams) middleware.Responder { + return func(params operations.UpdateSettingsParams) middleware.Responder { + if params.Settings == nil { + return createErrorResponse(http.StatusBadRequest, "Settings data is required") + } + + // Load current config + serverConfig, err := config.LoadServerConfig(configPath) + if err != nil { + return createErrorResponse(http.StatusInternalServerError, "Failed to load server configuration") + } + + // Update config with new settings + settings := params.Settings + if settings.NetworkURL != nil { + serverConfig.NetworkInfos.NodeURL = *settings.NetworkURL + } + + if settings.ServerPort != 0 { + serverConfig.APIPort = int(settings.ServerPort) + } + + if settings.Cache != nil { + if settings.Cache.Enabled != nil { + serverConfig.CacheConfig.Enabled = *settings.Cache.Enabled + } + + if settings.Cache.SiteRAMCacheMaxItems != 0 { + serverConfig.CacheConfig.SiteRAMCacheMaxItems = uint64(settings.Cache.SiteRAMCacheMaxItems) + } + + if settings.Cache.SiteDiskCacheMaxItems != 0 { + serverConfig.CacheConfig.SiteDiskCacheMaxItems = uint64(settings.Cache.SiteDiskCacheMaxItems) + } + + if settings.Cache.DiskCacheDir != "" { + serverConfig.CacheConfig.DiskCacheDir = settings.Cache.DiskCacheDir + } + + if settings.Cache.FileListCacheDurationSeconds != 0 { + serverConfig.CacheConfig.FileListCacheDurationSeconds = int(settings.Cache.FileListCacheDurationSeconds) + } + } + + // Marshal config to YAML + yamlData, err := yaml.Marshal(serverConfig) + if err != nil { + return createErrorResponse(http.StatusInternalServerError, "Failed to marshal configuration") + } + + // Stop the server + if err := manager.Stop(); err != nil && err != server.ErrServerNotRunning { + return createErrorResponse(http.StatusInternalServerError, "Failed to stop server") + } + + // Write config file + if err := os.WriteFile(configPath, yamlData, 0o644); err != nil { + return createErrorResponse(http.StatusInternalServerError, "Failed to write configuration file") + } + + // Restart the server + go func() { + if err := manager.Start(); err != nil { + logger.Errorf("Failed to restart server: %v", err) + } + }() + + return operations.NewUpdateSettingsOK() + } +} + +// Create an error response with the given status code and message +func createErrorResponse(statusCode int, message string) middleware.Responder { + code := int32(statusCode) + return &customErrorResponder{ + statusCode: statusCode, + payload: &models.Error{ + Code: &code, + Message: &message, + }, + } +} + +// customErrorResponder implements the Responder interface for error responses +type customErrorResponder struct { + statusCode int + payload *models.Error +} + +// WriteResponse writes the error response +func (r *customErrorResponder) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { + rw.WriteHeader(r.statusCode) + if err := producer.Produce(rw, r.payload); err != nil { + panic(err) + } +} diff --git a/plugin/int/server/config.go b/plugin/int/server/config.go new file mode 100644 index 00000000..6f171390 --- /dev/null +++ b/plugin/int/server/config.go @@ -0,0 +1,148 @@ +package server + +import ( + "fmt" + "os" + "path/filepath" + + "github.com/massalabs/deweb-server/int/api/config" + "github.com/massalabs/station/pkg/logger" + "gopkg.in/yaml.v2" +) + +const ( + defaultAPIPort = 0 + + DefaultConfigFileName = "deweb_server_config.yaml" +) + +// ensureConfigFileExists makes sure the config file exists, creating it with defaults if needed +func ensureConfigFileExists(configDir string) error { + configPath := filepath.Join(configDir, DefaultConfigFileName) + + if _, err := os.Stat(configPath); os.IsNotExist(err) { + yamlConfig := createDefaultYamlConfig(configDir) + + if err := saveYamlConfig(yamlConfig, configPath); err != nil { + return fmt.Errorf("failed to save default config: %w", err) + } + + logger.Infof("Created default server config at: %s", configPath) + } + + return nil +} + +// createDefaultYamlConfig creates a default YAML config with proper paths +func createDefaultYamlConfig(configDir string) config.YamlServerConfig { + domain := config.DefaultDomain + networkNodeURL := config.DefaultNetworkNodeURL + apiPort := defaultAPIPort + + yamlConfig := config.YamlServerConfig{ + Domain: &domain, + NetworkNodeURL: &networkNodeURL, + APIPort: &apiPort, + AllowList: []string{}, + BlockList: []string{}, + } + + cacheDir := filepath.Join(configDir, "cache") + if err := os.MkdirAll(cacheDir, 0o755); err != nil { + logger.Errorf("Failed to create cache directory: %v", err) + } + + enabled := true + cacheDirPtr := cacheDir + ramItems := config.DefaultMaxRAMItems + diskItems := config.DefaultMaxDiskItems + cacheDuration := config.DefaultFileListCachePeriod + + yamlConfig.CacheConfig = &config.YamlCacheConfig{ + Enabled: &enabled, + DiskCacheDir: &cacheDirPtr, + SiteRAMCacheMaxItems: &ramItems, + SiteDiskCacheMaxItems: &diskItems, + FileListCacheDurationSeconds: &cacheDuration, + } + + return yamlConfig +} + +// SaveServerConfig saves a ServerConfig to the given path +func SaveServerConfig(serverConfig *config.ServerConfig, configPath string) error { + yamlConfig := convertToYamlConfig(serverConfig) + + return saveYamlConfig(yamlConfig, configPath) +} + +// convertToYamlConfig converts a ServerConfig to YamlServerConfig +func convertToYamlConfig(serverConfig *config.ServerConfig) config.YamlServerConfig { + if serverConfig == nil { + return createDefaultYamlConfig("") + } + + domain := serverConfig.Domain + networkNodeURL := serverConfig.NetworkInfos.NodeURL + apiPort := serverConfig.APIPort + + // Create YAML config from server config + yamlConfig := config.YamlServerConfig{ + Domain: &domain, + NetworkNodeURL: &networkNodeURL, + APIPort: &apiPort, + AllowList: serverConfig.AllowList, + BlockList: serverConfig.BlockList, + MiscPublicInfoJson: serverConfig.MiscPublicInfoJson, + } + + // Convert cache config to YAML format + enabled := serverConfig.CacheConfig.Enabled + diskCacheDir := serverConfig.CacheConfig.DiskCacheDir + ramItems := serverConfig.CacheConfig.SiteRAMCacheMaxItems + diskItems := serverConfig.CacheConfig.SiteDiskCacheMaxItems + cacheDuration := serverConfig.CacheConfig.FileListCacheDurationSeconds + + yamlConfig.CacheConfig = &config.YamlCacheConfig{ + Enabled: &enabled, + DiskCacheDir: &diskCacheDir, + SiteRAMCacheMaxItems: &ramItems, + SiteDiskCacheMaxItems: &diskItems, + FileListCacheDurationSeconds: &cacheDuration, + } + + return yamlConfig +} + +// saveYamlConfig saves a YamlServerConfig to disk +func saveYamlConfig(yamlConfig config.YamlServerConfig, configPath string) error { + if err := os.MkdirAll(filepath.Dir(configPath), 0o755); err != nil { + return fmt.Errorf("failed to create config directory: %w", err) + } + + yamlData, err := yaml.Marshal(yamlConfig) + if err != nil { + return fmt.Errorf("failed to marshal config to YAML: %w", err) + } + + if err := os.WriteFile(configPath, yamlData, 0o644); err != nil { + return fmt.Errorf("failed to write config file: %w", err) + } + + return nil +} + +// GetConfigPath returns the path to the server config file +func getConfigPath(configDir string) string { + return filepath.Join(configDir, DefaultConfigFileName) +} + +// loadConfig loads a ServerConfig from the given path +func loadConfig(configPath string) (*config.ServerConfig, error) { + serverConfig, err := config.LoadServerConfig(configPath) + if err != nil { + return nil, fmt.Errorf("failed to load config: %w", err) + } + + return serverConfig, nil +} diff --git a/plugin/int/server/errors.go b/plugin/int/server/errors.go new file mode 100644 index 00000000..1138504e --- /dev/null +++ b/plugin/int/server/errors.go @@ -0,0 +1,21 @@ +package server + +var ( + ErrServerNotRunning = NewError("server is not running") + ErrServerAlreadyRunning = NewError("server is already running") +) + +// Error represents a server manager error +type Error struct { + message string +} + +// NewError creates a new Error +func NewError(msg string) *Error { + return &Error{message: msg} +} + +// Error returns the error message +func (e *Error) Error() string { + return e.message +} diff --git a/plugin/int/server/manager.go b/plugin/int/server/manager.go new file mode 100644 index 00000000..145f83c9 --- /dev/null +++ b/plugin/int/server/manager.go @@ -0,0 +1,241 @@ +package server + +import ( + "fmt" + "os" + "os/exec" + "path/filepath" + "sync" + "syscall" + "time" + + "github.com/massalabs/deweb-server/int/api/config" + "github.com/massalabs/station/pkg/logger" + "github.com/shirou/gopsutil/v4/process" +) + +const ( + DefaultLogPath = "deweb-server.log" +) + +// ServerManager handles DeWeb server operations with thread safety +type ServerManager struct { + mu sync.Mutex + serverProcess *os.Process + serverBinPath string + configDir string + isRunning bool + lastError string + binaryExists bool +} + +// NewServerManager creates a new server manager +func NewServerManager(configDir string) (*ServerManager, error) { + // Ensure config directory exists + if err := os.MkdirAll(configDir, 0o755); err != nil { + return nil, fmt.Errorf("failed to create config directory: %v", err) + } + + // Determine the plugin's executable path + execPath, err := os.Executable() + if err != nil { + return nil, fmt.Errorf("failed to get executable path: %v", err) + } + + // Server binary should be in the same directory as the plugin + pluginDir := filepath.Dir(execPath) + serverBinPath := filepath.Join(pluginDir, "deweb-server") + + // On Windows, add .exe extension + if filepath.Ext(execPath) == ".exe" { + serverBinPath += ".exe" + } + + manager := &ServerManager{ + serverBinPath: serverBinPath, + configDir: configDir, + binaryExists: true, + } + + // Check if config file exists, if not, create it with defaults + if err := ensureConfigFileExists(configDir); err != nil { + manager.lastError = fmt.Sprintf("Failed to ensure config file exists: %v", err) + logger.Errorf(manager.lastError) + } + + return manager, nil +} + +// Start launches the server process +func (m *ServerManager) Start() error { + m.mu.Lock() + defer m.mu.Unlock() + + // Check if binary exists + if _, err := os.Stat(m.serverBinPath); os.IsNotExist(err) { + m.binaryExists = false + m.lastError = fmt.Sprintf("Server binary not found at %s", m.serverBinPath) + return fmt.Errorf(m.lastError) + } + + if m.isRunning { + logger.Infof("Server is already running") + return ErrServerAlreadyRunning + } + + configPath := m.GetConfigPath() + logger.Infof("Starting DeWeb server with config: %s", configPath) + + logPath := filepath.Join(m.configDir, DefaultLogPath) + + cmd := exec.Command(m.serverBinPath, "--configPath", configPath, "--logPath", logPath) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + + if err := cmd.Start(); err != nil { + m.lastError = fmt.Sprintf("Failed to start server: %v", err) + logger.Errorf(m.lastError) + return err + } + + m.serverProcess = cmd.Process + m.isRunning = true + m.lastError = "" + + // Start a goroutine to monitor the process + go func() { + err := cmd.Wait() + if err != nil { + m.mu.Lock() + m.lastError = fmt.Sprintf("Server process exited with error: %v", err) + m.mu.Unlock() + logger.Errorf(m.lastError) + } + + m.mu.Lock() + m.isRunning = false + m.serverProcess = nil + m.mu.Unlock() + + logger.Infof("Server process exited") + }() + + return nil +} + +// Stop terminates the server process +func (m *ServerManager) Stop() error { + m.mu.Lock() + defer m.mu.Unlock() + + if !m.isRunning || m.serverProcess == nil { + logger.Infof("Server is not running") + return ErrServerNotRunning + } + + logger.Infof("Stopping DeWeb server") + + // Send a SIGTERM signal to gracefully shut down + if err := m.serverProcess.Signal(syscall.SIGTERM); err != nil { + logger.Errorf("Failed to send SIGTERM: %v", err) + + // Force kill as a fallback + if err = m.serverProcess.Kill(); err != nil { + return err + } + } + + // Wait for the process to exit + timeout := time.Now().Add(5 * time.Second) + for time.Now().Before(timeout) && m.isRunning { + time.Sleep(100 * time.Millisecond) + } + + // If still running after timeout, force kill + if m.isRunning { + _ = m.serverProcess.Kill() + m.isRunning = false + m.serverProcess = nil + } + + logger.Infof("Server stopped") + + return nil +} + +// Restart restarts the server +func (m *ServerManager) Restart() error { + if err := m.Stop(); err != nil && err != ErrServerNotRunning { + return err + } + + return m.Start() +} + +// GetStatus returns the current server status +func (m *ServerManager) GetStatus() Status { + m.mu.Lock() + defer m.mu.Unlock() + + if !m.binaryExists || m.lastError != "" { + return StatusError + } + + if m.isRunning { + return StatusRunning + } + return StatusStopped +} + +// IsRunning returns whether the server is currently running +func (m *ServerManager) IsRunning() bool { + m.mu.Lock() + defer m.mu.Unlock() + + return m.isRunning +} + +func (m *ServerManager) GetConfigPath() string { + return getConfigPath(m.configDir) +} + +func (m *ServerManager) GetConfig() (*config.ServerConfig, error) { + return loadConfig(m.GetConfigPath()) +} + +// GetLastError returns the last error message +func (m *ServerManager) GetLastError() string { + m.mu.Lock() + defer m.mu.Unlock() + + return m.lastError +} + +// GetServerPort retrieves the actual port the server is running on +func (m *ServerManager) GetServerPort() (uint32, error) { + m.mu.Lock() + defer m.mu.Unlock() + + if !m.isRunning || m.serverProcess == nil { + return 0, ErrServerNotRunning + } + + proc, err := process.NewProcess(int32(m.serverProcess.Pid)) + if err != nil { + return 0, fmt.Errorf("failed to access process: %v", err) + } + + connections, err := proc.Connections() + if err != nil { + return 0, fmt.Errorf("failed to get process connections: %v", err) + } + + // Find TCP connections in LISTEN state + for _, conn := range connections { + if conn.Status == "LISTEN" { + return conn.Laddr.Port, nil + } + } + + return 0, fmt.Errorf("no listening ports found for server process") +} diff --git a/plugin/int/server/status.go b/plugin/int/server/status.go new file mode 100644 index 00000000..eb301ef2 --- /dev/null +++ b/plugin/int/server/status.go @@ -0,0 +1,13 @@ +package server + +// Status represents the current status of the server +type Status string + +// Server status constants +const ( + StatusRunning Status = "running" + StatusStopped Status = "stopped" + StatusStarting Status = "starting" + StatusStopping Status = "stopping" + StatusError Status = "error" +) diff --git a/plugin/main.go b/plugin/main.go index cdaf90eb..e4de7b5f 100644 --- a/plugin/main.go +++ b/plugin/main.go @@ -7,18 +7,10 @@ import ( "os" "path/filepath" - pluginConfig "github.com/massalabs/deweb-plugin/config" - "github.com/massalabs/deweb-server/int/api" - "github.com/massalabs/deweb-server/int/api/config" - pkgConfig "github.com/massalabs/deweb-server/pkg/config" + "github.com/massalabs/deweb-plugin/int/api" "github.com/massalabs/station/pkg/logger" ) -const directoryName = "station-deweb-plugin" - -//go:embed home/dist/home.zip -var homeZip []byte - func main() { pluginDir, err := PluginDir() if err != nil { @@ -32,29 +24,15 @@ func main() { log.Fatalf("failed to initialize logger: %v", err) } - // Load configuration from YAML file with fallback to defaults - conf, err := pluginConfig.LoadConfig(pluginDir) - if err != nil { - logger.Warnf("%v", err) - } - - // Convert PluginConfig to ServerConfig - serverConfig := config.ServerConfig{ - APIPort: conf.APIPort, - Domain: "localhost", - NetworkInfos: pkgConfig.NewNetworkConfig(conf.NetworkURL), - CacheConfig: conf.CacheConfig, - } - - logger.Infof("Starting DeWeb plugin with configuration:") - logger.Infof(" API Port: %d", serverConfig.APIPort) - logger.Infof(" Network URL: %s", serverConfig.NetworkInfos.NodeURL) - logger.Infof(" Cache Directory: %s", serverConfig.CacheConfig.DiskCacheDir) + // Create and start the API with the plugin directory + apiInstance := api.NewAPI(pluginDir) + apiInstance.Start() - api := api.NewPluginAPI(&serverConfig, homeZip) - api.Start() + logger.Warnf("DeWeb plugin stopped") } +const directoryName = "station-deweb-plugin" + func PluginDir() (string, error) { configDir, err := os.UserConfigDir() if err != nil { From afaeedd5f30355fcacc4633ba5587c75f6e418d5 Mon Sep 17 00:00:00 2001 From: thomas-senechal Date: Tue, 29 Apr 2025 18:05:57 +0200 Subject: [PATCH 44/57] Remove now useless old plugin config code and example file --- plugin/config.yaml.example | 24 --------- plugin/config/config.go | 100 ------------------------------------- 2 files changed, 124 deletions(-) delete mode 100644 plugin/config.yaml.example delete mode 100644 plugin/config/config.go diff --git a/plugin/config.yaml.example b/plugin/config.yaml.example deleted file mode 100644 index dff97c74..00000000 --- a/plugin/config.yaml.example +++ /dev/null @@ -1,24 +0,0 @@ -# DeWeb plugin Configuration - -# Network node URL to connect to (default: "https://mainnet.massa.net/api/v2") -network_node_url: "https://mainnet.massa.net/api/v2" - -# API port to listen on (default: 0 -> which means a random port will be assigned by OS) -api_port: 0 - -# Cache configuration -cache: - # Whether caching is enabled (default: true) - enabled: true - - # Maximum number of files stored in RAM cache (default: 1000) - site_ram_cache_max_items: 1000 - - # Maximum number of files stored in disk cache (default: 10000) - site_disk_cache_max_items: 10000 - - # Directory to store the disk cache (default: "./websitesCache/") - disk_cache_dir: "./websitesCache/" - - # Duration in seconds for file list cache (default: 60s) - file_list_cache_duration_seconds: 60 diff --git a/plugin/config/config.go b/plugin/config/config.go deleted file mode 100644 index 90ba9d92..00000000 --- a/plugin/config/config.go +++ /dev/null @@ -1,100 +0,0 @@ -package config - -import ( - "fmt" - "os" - "path/filepath" - - apiConfig "github.com/massalabs/deweb-server/int/api/config" - "gopkg.in/yaml.v2" -) - -const ( - DefaultNetworkURL = "https://mainnet.massa.net/api/v2" - DefaultCacheDir = "websiteCache" - ConfigFileName = "config.yaml" -) - -// PluginConfig represents the configuration for the DeWeb plugin -type PluginConfig struct { - APIPort int - NetworkURL string - CacheConfig apiConfig.CacheConfig -} - -type YamlPluginConfig struct { - APIPort *int `yaml:"api_port"` - NetworkURL string `yaml:"network_url"` - CacheConfig apiConfig.YamlCacheConfig `yaml:"cache"` -} - -// LoadConfig loads the configuration from a YAML file -// It falls back to default values if the file doesn't exist or if values are missing -func LoadConfig(pluginDir string) (PluginConfig, error) { - config := PluginConfig{ - APIPort: 0, // Default port (0 means a random port will be assigned by OS) - NetworkURL: DefaultNetworkURL, - CacheConfig: apiConfig.CacheConfig{ - DiskCacheDir: filepath.Join(pluginDir, DefaultCacheDir), - SiteRAMCacheMaxItems: apiConfig.DefaultMaxRAMItems, - SiteDiskCacheMaxItems: apiConfig.DefaultMaxDiskItems, - FileListCacheDurationSeconds: apiConfig.DefaultFileListCachePeriod, - }, - } - - configPath := filepath.Join(pluginDir, ConfigFileName) - fileConfig, err := loadFromFile(configPath) - if err != nil { - return config, fmt.Errorf("using default configuration: %w", err) - } - - mergeConfig(fileConfig, &config, pluginDir) - return config, nil -} - -// loadFromFile attempts to load config from a file -// Returns the loaded config and an error if loading failed -func loadFromFile(configPath string) (YamlPluginConfig, error) { - var pluginConfig YamlPluginConfig - - // Check if config file exists - _, err := os.Stat(configPath) - if os.IsNotExist(err) { - return pluginConfig, fmt.Errorf("config file not found at %s", configPath) - } else if err != nil { - return pluginConfig, fmt.Errorf("error checking config file: %w", err) - } - - // Read config file - yamlFile, err := os.ReadFile(configPath) - if err != nil { - return pluginConfig, fmt.Errorf("error reading config file: %w", err) - } - - // Parse YAML - err = yaml.Unmarshal(yamlFile, &pluginConfig) - if err != nil { - return pluginConfig, fmt.Errorf("error parsing config file: %w", err) - } - - return pluginConfig, nil -} - -// mergeConfig applies non-empty values from source to target -// Handles both absolute and relative paths for CacheDir -func mergeConfig(source YamlPluginConfig, target *PluginConfig, pluginDir string) { - if source.APIPort != nil { - target.APIPort = *source.APIPort - } - - if source.NetworkURL != "" { - target.NetworkURL = source.NetworkURL - } - - cacheConfig := apiConfig.ConvertYamlCacheConfig(&source.CacheConfig) - target.CacheConfig = cacheConfig - - if !filepath.IsAbs(target.CacheConfig.DiskCacheDir) { - target.CacheConfig.DiskCacheDir = filepath.Join(pluginDir, target.CacheConfig.DiskCacheDir) - } -} From 4adf0afb7e67d28ea55af72903c85cf44d73e7f3 Mon Sep 17 00:00:00 2001 From: thomas-senechal Date: Tue, 29 Apr 2025 18:06:39 +0200 Subject: [PATCH 45/57] Add build-server task and update file copy commands to add the server binary to the archive --- plugin/Taskfile.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/plugin/Taskfile.yml b/plugin/Taskfile.yml index 308f2a06..230e87b5 100644 --- a/plugin/Taskfile.yml +++ b/plugin/Taskfile.yml @@ -8,6 +8,16 @@ tasks: generate: cmds: - cmd: go generate ./... + - task: build-server + + build-server: + internal: true + dir: ../server + cmds: + - cmd: task build + - cmd: cp build/deweb-server{{.BIN_EXT}} ../plugin/build + vars: + BIN_EXT: '{{if eq .OS "windows"}}.exe{{end}}' run: cmds: @@ -53,6 +63,8 @@ tasks: platforms: [linux, darwin] - cmd: cp build/deweb-plugin /usr/local/share/massastation/plugins/deweb-plugin platforms: [linux, darwin] + - cmd: cp build/deweb-server /usr/local/share/massastation/plugins/deweb-plugin + platforms: [linux, darwin] - cmd: cp favicon.png /usr/local/share/massastation/plugins/deweb-plugin platforms: [linux, darwin] - cmd: cp manifest.json /usr/local/share/massastation/plugins/deweb-plugin @@ -61,6 +73,8 @@ tasks: platforms: [windows] - cmd: cp build/deweb-plugin.exe "C:/Program Files (x86)/MassaStation/plugins/deweb-plugin" platforms: [windows] + - cmd: cp build/deweb-server.exe "C:/Program Files (x86)/MassaStation/plugins/deweb-plugin" + platforms: [windows] - cmd: cp favicon.png "C:/Program Files (x86)/MassaStation/plugins/deweb-plugin" platforms: [windows] - cmd: cp manifest.json "C:/Program Files (x86)/MassaStation/plugins/deweb-plugin" From bbf9fe2e62c8395844bbb0753106952dead64fd8 Mon Sep 17 00:00:00 2001 From: thomas-senechal Date: Tue, 29 Apr 2025 18:17:23 +0200 Subject: [PATCH 46/57] Add mkdir command to create build directory in Taskfile.yml --- plugin/Taskfile.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/plugin/Taskfile.yml b/plugin/Taskfile.yml index 230e87b5..69cb72b5 100644 --- a/plugin/Taskfile.yml +++ b/plugin/Taskfile.yml @@ -7,6 +7,7 @@ tasks: generate: cmds: + - cmd: mkdir -p ./build - cmd: go generate ./... - task: build-server From f6ac1b6ee7d6fa7f41c8523cc50af3f938e70524 Mon Sep 17 00:00:00 2001 From: thomas-senechal Date: Mon, 5 May 2025 12:08:40 +0200 Subject: [PATCH 47/57] Refactor workflows for building and releasing server and plugin --- .github/workflows/build.yml | 29 ++++++++++ .github/workflows/plugin.yml | 40 ++++++++----- .../{plugin-release.yml => release.yml} | 58 +++++++++---------- .github/workflows/server-release.yml | 57 ------------------ .github/workflows/server.yml | 9 --- plugin/Taskfile.yml | 2 - 6 files changed, 83 insertions(+), 112 deletions(-) create mode 100644 .github/workflows/build.yml rename .github/workflows/{plugin-release.yml => release.yml} (63%) delete mode 100644 .github/workflows/server-release.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 00000000..52fc5cb8 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,29 @@ +name: Build Server and Plugin + +on: + push: + branches: [main] + paths: + - 'plugin/**' + - 'server/**' + - '.github/workflows/**' + - '.github/actions/**' + pull_request: + paths: + - 'plugin/**' + - 'server/**' + - '.github/workflows/**' + - '.github/actions/**' + workflow_dispatch: + +jobs: + build-server: + name: Build server + uses: ./.github/workflows/server.yml + secrets: inherit + + build-plugin: + name: Build plugin + needs: build-server + uses: ./.github/workflows/plugin.yml + secrets: inherit diff --git a/.github/workflows/plugin.yml b/.github/workflows/plugin.yml index f316f238..a9347fa1 100644 --- a/.github/workflows/plugin.yml +++ b/.github/workflows/plugin.yml @@ -1,17 +1,6 @@ name: Plugin on: - push: - branches: [main] - paths: - - 'plugin/**' - - 'server/**' - - '.github/workflows/plugin.yml' - pull_request: - paths: - - 'plugin/**' - - 'server/**' - - '.github/workflows/plugin.yml' workflow_dispatch: workflow_call: inputs: @@ -112,6 +101,18 @@ jobs: echo "PRODUCTION=true" >> $GITHUB_ENV fi + - name: Download server artifacts + uses: actions/download-artifact@v4 + with: + name: deweb-server_${{ matrix.target }}_${{ matrix.arch }} + path: server/build + + - name: Rename server binary + shell: bash + run: | + mkdir -p build + mv server/build/deweb-server_${{ matrix.target }}_${{ matrix.arch }}${{ matrix.ext }} build/deweb-server${{ matrix.ext }} + - name: Build Plugin shell: bash run: task build @@ -122,16 +123,25 @@ jobs: - name: Rename Plugin artifact run: mv build/deweb-plugin${{ matrix.ext }} deweb-plugin_${{ matrix.target }}_${{ matrix.arch }}${{ matrix.ext }} - - name: Copy shared files to platform directory + - name: Create platform directory with all required files shell: bash run: | mkdir -p platform_${{ matrix.target }}_${{ matrix.arch }} cp deweb-plugin_${{ matrix.target }}_${{ matrix.arch }}${{ matrix.ext }} platform_${{ matrix.target }}_${{ matrix.arch }}/ + cp build/deweb-server${{ matrix.ext }} platform_${{ matrix.target }}_${{ matrix.arch }}/ cp favicon.png platform_${{ matrix.target }}_${{ matrix.arch }}/ cp manifest.json platform_${{ matrix.target }}_${{ matrix.arch }}/ - - name: Upload Plugin artifact + - name: Create zip package + shell: bash + run: | + cd platform_${{ matrix.target }}_${{ matrix.arch }} + zip -r ../deweb-plugin_${{ matrix.target }}_${{ matrix.arch }}.zip * + cd .. + ls -la deweb-plugin_${{ matrix.target }}_${{ matrix.arch }}.zip + + - name: Upload Plugin zip package uses: actions/upload-artifact@v4 with: - name: deweb-plugin_${{ matrix.target }}_${{ matrix.arch }} - path: plugin/platform_${{ matrix.target }}_${{ matrix.arch }}/ \ No newline at end of file + name: deweb-plugin_${{ matrix.target }}_${{ matrix.arch }}_zip + path: plugin/deweb-plugin_${{ matrix.target }}_${{ matrix.arch }}.zip diff --git a/.github/workflows/plugin-release.yml b/.github/workflows/release.yml similarity index 63% rename from .github/workflows/plugin-release.yml rename to .github/workflows/release.yml index 6414932c..13441881 100644 --- a/.github/workflows/plugin-release.yml +++ b/.github/workflows/release.yml @@ -1,10 +1,10 @@ -name: Plugin Release +name: Release DeWeb on: workflow_dispatch: inputs: version: - description: 'Plugin version for this release (without v prefix)' + description: 'Version for this release (without v prefix)' required: true type: string release-as-draft: @@ -42,52 +42,52 @@ jobs: fi echo "Manifest version matches input version: $version" + build-server: + needs: check-manifest + uses: ./.github/workflows/server.yml + with: + version: ${{ inputs.version }} + secrets: inherit + build-plugin: + needs: build-server uses: ./.github/workflows/plugin.yml - needs: check-manifest with: version: ${{ inputs.version }} secrets: inherit create-release: - needs: [check-manifest, build-plugin] + needs: [build-server, build-plugin] runs-on: ubuntu-latest permissions: contents: write steps: - - name: Download all artifacts + - name: Download server artifacts uses: actions/download-artifact@v4 with: - path: artifacts - pattern: 'deweb-plugin_*' + path: artifacts/server + pattern: 'deweb-server_*' - - name: List artifacts - run: ls -R artifacts - - - name: Create zip packages for each platform - run: | - mkdir -p release_zips - - # Find all artifact folders - for platform_dir in artifacts/deweb-plugin_*; do - # Extract the platform name from the directory - platform_name=$(basename "$platform_dir") - - # Create a zip package for this platform - (cd "$platform_dir" && zip -r "../../release_zips/${platform_name}.zip" *) - - echo "Created zip package for $platform_name" - done - - ls -la release_zips/ + - name: Download plugin zip packages + uses: actions/download-artifact@v4 + with: + path: artifacts/plugin + pattern: 'deweb-plugin_*_zip' + + - name: ls -la artifacts/server + run: ls -la artifacts/server + + - name: ls -la artifacts/plugin + run: ls -la artifacts/plugin - name: Create Release uses: softprops/action-gh-release@v2 with: - tag_name: plugin-v${{ inputs.version }} - name: plugin v${{ inputs.version }} + tag_name: v${{ inputs.version }} + name: DeWeb v${{ inputs.version }} draft: ${{ inputs.release-as-draft }} prerelease: ${{ inputs.release-as-prerelease }} generate_release_notes: ${{ inputs.generate-release-notes }} files: | - release_zips/*.zip + artifacts/deweb-server_*/deweb-server_* + artifacts/plugin/deweb-plugin_*_zip/deweb-plugin_*.zip diff --git a/.github/workflows/server-release.yml b/.github/workflows/server-release.yml deleted file mode 100644 index f96f7e7b..00000000 --- a/.github/workflows/server-release.yml +++ /dev/null @@ -1,57 +0,0 @@ -name: Server Release - -on: - workflow_dispatch: - inputs: - version: - description: 'Server version for this release (without v prefix)' - required: true - type: string - release-as-draft: - description: "Whether it's a draft or not" - required: true - type: boolean - default: true - release-as-prerelease: - description: "Whether it's a prerelease or not" - required: true - type: boolean - default: false - generate-release-notes: - description: "Generate release notes" - required: true - type: boolean - default: true - -jobs: - build-server: - uses: ./.github/workflows/server.yml - with: - version: ${{ inputs.version }} - secrets: inherit - - create-release: - needs: build-server - runs-on: ubuntu-latest - permissions: - contents: write - steps: - - name: Download all server artifacts - uses: actions/download-artifact@v4 - with: - path: artifacts - pattern: 'deweb-server_*' - - - name: List artifacts - run: ls -R artifacts - - - name: Create Release - uses: softprops/action-gh-release@v2 - with: - tag_name: v${{ inputs.version }} - name: server v${{ inputs.version }} - draft: ${{ inputs.release-as-draft }} - prerelease: ${{ inputs.release-as-prerelease }} - generate_release_notes: ${{ inputs.generate-release-notes }} - files: | - artifacts/deweb-server_*/deweb-server_* diff --git a/.github/workflows/server.yml b/.github/workflows/server.yml index d5e766bd..e22966e2 100644 --- a/.github/workflows/server.yml +++ b/.github/workflows/server.yml @@ -1,15 +1,6 @@ name: Server on: - push: - branches: [main] - paths: - - 'server/**' - - '.github/workflows/server.yml' - pull_request: - paths: - - 'server/**' - - '.github/workflows/server.yml' workflow_dispatch: workflow_call: inputs: diff --git a/plugin/Taskfile.yml b/plugin/Taskfile.yml index 69cb72b5..0d0f1cc2 100644 --- a/plugin/Taskfile.yml +++ b/plugin/Taskfile.yml @@ -9,10 +9,8 @@ tasks: cmds: - cmd: mkdir -p ./build - cmd: go generate ./... - - task: build-server build-server: - internal: true dir: ../server cmds: - cmd: task build From ae67fe0b9312b1c43f3379ad63cda5008c6890b7 Mon Sep 17 00:00:00 2001 From: thomas-senechal Date: Mon, 5 May 2025 12:36:49 +0200 Subject: [PATCH 48/57] Fix wrong path for downloaded artifacts in plugin workflow --- .github/workflows/plugin.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/plugin.yml b/.github/workflows/plugin.yml index a9347fa1..5b244e0b 100644 --- a/.github/workflows/plugin.yml +++ b/.github/workflows/plugin.yml @@ -111,7 +111,8 @@ jobs: shell: bash run: | mkdir -p build - mv server/build/deweb-server_${{ matrix.target }}_${{ matrix.arch }}${{ matrix.ext }} build/deweb-server${{ matrix.ext }} + mv ../server/build/deweb-server_${{ matrix.target }}_${{ matrix.arch }}${{ matrix.ext }} build/deweb-server${{ matrix.ext }} + chmod +x build/deweb-server${{ matrix.ext }} - name: Build Plugin shell: bash From 8209971392a80348719aa4fc7e3a210d69cf2d40 Mon Sep 17 00:00:00 2001 From: thomas-senechal Date: Mon, 5 May 2025 15:29:23 +0200 Subject: [PATCH 49/57] Use Ubuntu to build windows --- .github/workflows/plugin.yml | 8 ++++---- .github/workflows/server.yml | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/plugin.yml b/.github/workflows/plugin.yml index 5b244e0b..3693b049 100644 --- a/.github/workflows/plugin.yml +++ b/.github/workflows/plugin.yml @@ -54,14 +54,14 @@ jobs: strategy: matrix: include: - - os: windows-2022 + - os: ubuntu-24.04 arch: amd64 target: windows ext: .exe - - os: ubuntu-22.04 + - os: ubuntu-24.04 arch: amd64 target: linux - - os: ubuntu-22.04 + - os: ubuntu-24.04 arch: arm64 target: linux - os: macos-13 @@ -144,5 +144,5 @@ jobs: - name: Upload Plugin zip package uses: actions/upload-artifact@v4 with: - name: deweb-plugin_${{ matrix.target }}_${{ matrix.arch }}_zip + name: deweb-plugin_${{ matrix.target }}_${{ matrix.arch }} path: plugin/deweb-plugin_${{ matrix.target }}_${{ matrix.arch }}.zip diff --git a/.github/workflows/server.yml b/.github/workflows/server.yml index e22966e2..1b6fc5da 100644 --- a/.github/workflows/server.yml +++ b/.github/workflows/server.yml @@ -68,14 +68,14 @@ jobs: strategy: matrix: include: - - os: windows-2022 + - os: ubuntu-24.04 arch: amd64 target: windows ext: .exe - - os: ubuntu-22.04 + - os: ubuntu-24.04 arch: amd64 target: linux - - os: ubuntu-22.04 + - os: ubuntu-24.04 arch: arm64 target: linux - os: macos-13 From 340dcb2fde18c8ede6b46309695261b1d7548723 Mon Sep 17 00:00:00 2001 From: thomas-senechal Date: Mon, 5 May 2025 15:45:20 +0200 Subject: [PATCH 50/57] Update server command to include --accept-disclaimer flag --- plugin/int/server/manager.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin/int/server/manager.go b/plugin/int/server/manager.go index 145f83c9..6f81cc37 100644 --- a/plugin/int/server/manager.go +++ b/plugin/int/server/manager.go @@ -88,7 +88,7 @@ func (m *ServerManager) Start() error { logPath := filepath.Join(m.configDir, DefaultLogPath) - cmd := exec.Command(m.serverBinPath, "--configPath", configPath, "--logPath", logPath) + cmd := exec.Command(m.serverBinPath, "--configPath", configPath, "--logPath", logPath, "--accept-disclaimer") cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr From fd9330b3a84cad83322323618296fad4db2aaf9f Mon Sep 17 00:00:00 2001 From: thomas-senechal Date: Wed, 7 May 2025 09:45:57 +0200 Subject: [PATCH 51/57] Remove deprecated PluginAPI implementation from the server API package. --- server/int/api/plugin.go | 149 --------------------------------------- 1 file changed, 149 deletions(-) delete mode 100644 server/int/api/plugin.go diff --git a/server/int/api/plugin.go b/server/int/api/plugin.go deleted file mode 100644 index 27f8d26b..00000000 --- a/server/int/api/plugin.go +++ /dev/null @@ -1,149 +0,0 @@ -package api - -import ( - "encoding/json" - "fmt" - "log" - "net" - "net/http" - - "github.com/go-openapi/runtime" - "github.com/go-openapi/runtime/middleware" - "github.com/massalabs/deweb-server/api/read/restapi/operations" - "github.com/massalabs/deweb-server/int/api/config" - "github.com/massalabs/station-massa-hello-world/pkg/plugin" - "github.com/massalabs/station/pkg/logger" -) - -type PluginAPI struct { - *API - homeZip []byte -} - -func NewPluginAPI(conf *config.ServerConfig, homeZip []byte) *PluginAPI { - baseAPI := NewAPI(conf) - - return &PluginAPI{ - API: baseAPI, - homeZip: homeZip, - } -} - -// createHandler overrides the base API's createHandler to add StationMiddleware -func (a *PluginAPI) createHandler() http.Handler { - baseHandler := a.API.createHandler() - return StationMiddleware(baseHandler, a.homeZip, a.Conf) -} - -// Start starts the API server. -func (a *PluginAPI) Start() { - defer func() { - if a.Cache != nil { - a.Cache.Close() - } - - if err := a.APIServer.Shutdown(); err != nil { - log.Fatalln(err) - } - }() - - a.APIServer.Port = a.Conf.APIPort - - a.configurePluginAPI() - - a.APIServer.ConfigureAPI() - - // Set handler using the createHandler method - a.APIServer.SetHandler(a.createHandler()) - - listener, err := a.APIServer.HTTPListener() - if err != nil { - logger.Fatalf("Failed to get HTTP listener: %v", err) - } - - // We get the port from the listener in case the port was set to 0 and the OS assigned a port - a.Conf.APIPort = listener.Addr().(*net.TCPAddr).Port - - if err := plugin.RegisterPlugin(listener); err != nil { - logger.Fatalf("Failed to register plugin: %v", err) - } - - if err := a.APIServer.Serve(); err != nil { - log.Fatalln(err) - } -} - -// ConfigureAPI sets up the API handlers and error handling. -func (a *PluginAPI) configurePluginAPI() { - a.DewebAPI.ServeError = func(w http.ResponseWriter, r *http.Request, err error) { - log.Printf("ServeError: %v", err) - w.WriteHeader(http.StatusInternalServerError) - } - - a.DewebAPI.GetResourceHandler = operations.GetResourceHandlerFunc(getPluginResourceHandler) - a.DewebAPI.DefaultPageHandler = operations.DefaultPageHandlerFunc(getPluginDefaultPageHandler) -} - -// StationMiddleware handles station website serving. -// It is used by the plugin to serve massastation plugin page if the request domain is `station.massa`. -func StationMiddleware(handler http.Handler, homePageZip []byte, conf *config.ServerConfig) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - logger.Debugf("StationMiddleware: Handling request for %s", r.Host) - - if r.Host != "station.massa" { - logger.Debug("StationMiddleware: Request is not for station.massa. Proceeding with the next handler.") - handler.ServeHTTP(w, r) - - return - } - - path := cleanPath(r.URL.Path) - - if path == "port" { - w.WriteHeader(http.StatusOK) - - _, err := w.Write([]byte(fmt.Sprintf("%d", conf.APIPort))) - if err != nil { - logger.Errorf("Failed to write port: %v", err) - } - - return - } - - if path == "info" { - w.WriteHeader(http.StatusOK) - - json, err := json.Marshal(conf.NetworkInfos) - if err != nil { - logger.Errorf("Failed to marshal network infos: %v", err) - } - - _, err = w.Write(json) - if err != nil { - logger.Errorf("Failed to write info: %v", err) - } - - return - } - - logger.Debugf("StationMiddleware: Serving station.massa plugin page") - - localHandler(w, homePageZip, path) - }) -} - -func getPluginResourceHandler(params operations.GetResourceParams) middleware.Responder { - return middleware.ResponderFunc(func(w http.ResponseWriter, _ runtime.Producer) { - logger.Debugf("getPluginResourceHandler: redirecting to plugin") - - http.Redirect(w, params.HTTPRequest, "https://station.massa/plugin/massa-labs/deweb-plugin", http.StatusSeeOther) - }) -} - -func getPluginDefaultPageHandler(params operations.DefaultPageParams) middleware.Responder { - return middleware.ResponderFunc(func(w http.ResponseWriter, _ runtime.Producer) { - logger.Debugf("getPluginDefaultPageHandler: redirecting to plugin") - - http.Redirect(w, params.HTTPRequest, "https://station.massa/plugin/massa-labs/deweb-plugin", http.StatusSeeOther) - }) -} From 545b84a61d8c30819cd967999ca22201a12a7ffe Mon Sep 17 00:00:00 2001 From: thomas-senechal Date: Wed, 7 May 2025 11:05:02 +0200 Subject: [PATCH 52/57] Remove useless helloworld plugin from server go mod --- server/go.mod | 1 - server/go.sum | 2 -- 2 files changed, 3 deletions(-) diff --git a/server/go.mod b/server/go.mod index ebc5e7ea..7818cbe0 100644 --- a/server/go.mod +++ b/server/go.mod @@ -15,7 +15,6 @@ require ( github.com/hashicorp/golang-lru/v2 v2.0.7 github.com/jessevdk/go-flags v1.6.1 github.com/massalabs/station v0.6.5 - github.com/massalabs/station-massa-hello-world v0.0.11-0.20240503070604-6b14a27fcdff github.com/massalabs/station-massa-wallet v0.4.5 golang.org/x/net v0.38.0 gopkg.in/yaml.v2 v2.4.0 diff --git a/server/go.sum b/server/go.sum index cf0b8818..ef283d03 100644 --- a/server/go.sum +++ b/server/go.sum @@ -89,8 +89,6 @@ github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0 github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/massalabs/station v0.6.5 h1:lkWWYB0/dPsRHSoAqN0wh/mFx8+InsVGMfraXQFZ76U= github.com/massalabs/station v0.6.5/go.mod h1:i9d/zAqeDYxY0Od5LEfEkP6V2osUhA13GwA72ByM8bQ= -github.com/massalabs/station-massa-hello-world v0.0.11-0.20240503070604-6b14a27fcdff h1:SZoRmXdbolVjhbsxO/3KWX8429Q1VnaQdQy0h718CqE= -github.com/massalabs/station-massa-hello-world v0.0.11-0.20240503070604-6b14a27fcdff/go.mod h1:QbRHQvJFrm4mO+vPzr4Uiwa5REL/CgBlV4PDFdhewa0= github.com/massalabs/station-massa-wallet v0.4.5 h1:0rTHxGPlJ5cKjgB/yQclOBHbWiZO5rOwO0lT7ZjFuVQ= github.com/massalabs/station-massa-wallet v0.4.5/go.mod h1:Eu6Zlijs0uAuGM5CxEUOxFrcIlWtuZVAbiWPCUni9XY= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= From 9940db3eb9a17c44a93e65bcfc1dcda2d0b6a145 Mon Sep 17 00:00:00 2001 From: thomas-senechal Date: Wed, 14 May 2025 10:21:08 +0200 Subject: [PATCH 53/57] Add private kill function and improve error handling at start in server manager --- plugin/int/server/manager.go | 39 +++++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/plugin/int/server/manager.go b/plugin/int/server/manager.go index 6f81cc37..07877bf9 100644 --- a/plugin/int/server/manager.go +++ b/plugin/int/server/manager.go @@ -71,11 +71,15 @@ func (m *ServerManager) Start() error { m.mu.Lock() defer m.mu.Unlock() - // Check if binary exists - if _, err := os.Stat(m.serverBinPath); os.IsNotExist(err) { - m.binaryExists = false - m.lastError = fmt.Sprintf("Server binary not found at %s", m.serverBinPath) - return fmt.Errorf(m.lastError) + _, err := os.Stat(m.serverBinPath) + if err != nil { + if os.IsNotExist(err) { + m.binaryExists = false + m.lastError = fmt.Sprintf("Server binary not found at %s", m.serverBinPath) + return fmt.Errorf(m.lastError) + } + + return fmt.Errorf("failed to check server binary: %v", err) } if m.isRunning { @@ -123,6 +127,25 @@ func (m *ServerManager) Start() error { return nil } +// kill forcefully terminates the server process and updates state +// NOTE: This is an unsafe internal method that doesn't handle mutex locking. +// It should only be called by methods that have already acquired the mutex lock. +func (m *ServerManager) kill() error { + if !m.isRunning || m.serverProcess == nil { + return ErrServerNotRunning + } + + err := m.serverProcess.Kill() + if err != nil { + return err + } + + m.isRunning = false + m.serverProcess = nil + + return nil +} + // Stop terminates the server process func (m *ServerManager) Stop() error { m.mu.Lock() @@ -140,7 +163,7 @@ func (m *ServerManager) Stop() error { logger.Errorf("Failed to send SIGTERM: %v", err) // Force kill as a fallback - if err = m.serverProcess.Kill(); err != nil { + if err = m.kill(); err != nil { return err } } @@ -153,9 +176,7 @@ func (m *ServerManager) Stop() error { // If still running after timeout, force kill if m.isRunning { - _ = m.serverProcess.Kill() - m.isRunning = false - m.serverProcess = nil + _ = m.kill() } logger.Infof("Server stopped") From 5ab3d3e54858a25321b16aebcf5b1e664ca00a57 Mon Sep 17 00:00:00 2001 From: thomas-senechal Date: Thu, 15 May 2025 11:55:26 +0200 Subject: [PATCH 54/57] Update plugin manifest to reflect new name and description, and change version to 0.4.4 --- plugin/manifest.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugin/manifest.json b/plugin/manifest.json index 9817a092..7e1ca083 100644 --- a/plugin/manifest.json +++ b/plugin/manifest.json @@ -1,9 +1,9 @@ { "author": "Massa Labs", - "name": "DeWeb Plugin", - "description": "DeWeb is your gateway to the decentralized web, enabling seamless access to websites stored on-chain from any device, anywhere in the world.", + "name": "Local DeWeb Provider", + "description": "Local DeWeb Provider is a plugin that allows you to access the DeWeb from your computer.", "logo": "favicon.png", "home": "", - "version": "0.0.1", + "version": "0.1.0", "apispec": "" } \ No newline at end of file From 9581c5c80b2545e9d074a4aeb47c8845bb672826 Mon Sep 17 00:00:00 2001 From: thomas-senechal Date: Thu, 15 May 2025 12:20:53 +0200 Subject: [PATCH 55/57] Update favicon and manifest description, and adjust environment paths for local DeWeb provider --- plugin/favicon.png | Bin 6128 -> 680 bytes plugin/home/.env.massastation | 4 ++-- plugin/manifest.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/plugin/favicon.png b/plugin/favicon.png index baa5d9b102378cddc1b008cd9fcb5b90e5824887..77a993eabf0a9c9919ace730bab9ca15327cc867 100644 GIT binary patch delta 607 zcmV-l0-*iyFQ^3}iBL{Q4GJ0x0000DNk~Le0000m0000m2nGNE09OL}hmj#Pe*z;( zL_t(|0qvNvPr^_T#_zQ?CMIkS>VP9|3So5VAfvcBFc}yA3XQJ*16_<0CT`&Bz~X4o zQC9~O6E_kP4W;@uDXG|E3-1n^@Jk3Gkn+Cw?%v&fYJF|nqm<;-3KdkIY_mkRD$<5p zjs5M;=MizDCJ`{ozPU?vvl=Oce_Mb-8n|`u>G1268txrQqeTGdQjaeB*W|b@l0=(; z0H@y+Jqhgs07SfbA0z>b0EE*?|B@tN5daR=0ynGzBocWc zVAik;7}w}cOO95uEudiJ`302K7I9%4C4K=lYmd0FjUvAQ#A(^ke+rmEe-NG`x6rwD z>`!sJz_Tzw0TBV%sk%`mU4*AUu{uz*D#KlyhPqXynpqiswn&h=b>QcOGiasmRD-Yy zFCK^r05}QTEBT`*X6Yp05tJx8o;i z&E%`RQT!6%^jrSoCn4~K@UG*!OvIiWX=~FB{RNI9O9K2CvmfM<{JSzm`h(M4d1YM^j8rzD4>(d7bfc52g3jW literal 6128 zcmeHLXH-+`whf5V!3aViG(knwPy|5@MFIu|1QjfF2rURfL7H@=g^~m=3erUm^-x4Z zKtk`zL4rU6NRLVvB2oi#cQ|*9_kO&8?~eQHW{f@d-fMq7YpuEFjJsuGz|SMj0|J5g zZ(P^E0|K#)vM#P8fTidwwi38;KfZ491O(z0VqI*Yj4TLXWP5VQ00FA_Bry-XaJcH; z)CGa62)w%vhe04w_Z#}U<^gQW<2MtZ->qwA(C1$8RzdS4iha~*)N>Oi7<#zPn2+J&X)Zk0GL42OnP(8gbU?DbD(zq3!j zKX<=k_ufl!@L)l~Vq`PVxvz1j5O_kYca^5m_J1{lPL@n6|LlFhvprw^Pg%y z7diK1oLsGJ6Xo~pntfl+UP;#FHTu+LN)u#WO1nPf=-BkAQp!!V{NVN)?PH1AWTsS1 ze8-v1xqjMV|5onhsJJ&$@Qrc>6#9C*pMyiD?-=(fqR>fXRTrT$<8;iCj$-v^(0uFD z2^16TKv5XP`1m1ALNbPfHs|Nfwal@#Mc;=dBdmZ?-+dcA~MTAcLlVIN6aaYk~3yz;xD zEVj87J>x4%-eK~2p8vA@O$m-kdYD8}KP?OY;d8J4st$AMW<<0~hj(wB(ET8*E*$w# zM>kbFjx_8$mh`e!T;r`5X5zlxvarR2*ho%0$$I>b_}xwy7_Fzq01X94Xa#L_UBJIQ z{rhXm<&|d+hkk|N-0P?P+8rDu%O!E3363LnJ*kRC!@^X;o3?YGXk8 z^4RbhUi1#8)XOv%RSKO6$eRp#F*l4^> zt@0?bs{i~id6(xiiVtj5L#%c3%7;IG%y#`f_CWeVMs(=%mrd_^J&E4y4N)Xietp2$ zpT~A+G|UomTf^{jDPYozA9>{q6PW>Chr)!5 zuKD&3dW{3kdwObex1TTr91anvG%PiyIFK7tfE4Qo)~5CSyZQ@lV0mejdk>$B;=r)M z{7M>qVL>VS3imR{V?F<31G~zuOpTk8G(*<-SW;!l*(m~Q)=S!0l4is*koUbU$| z{WOVk@1p?1UKmMS|2u8sRIeSrrSb1csY=4(T@S37)md6hv-eNea-AIk^J>EL zq7{7B7shojrKLR*L{>7~Wnw9<90|$uy_roDgohmKp9`!A5>?v0ySv}n6HU;04sA)u zt8{RmTrq>Ga=1QOZU{(IyvkSdqGPP<1M($w8m|OQtou|-b}35%w%zSMolR2CS)#HO z=e?_XJBitp)_^Dx@z1j{C-b5iTrf2!KT^|BPPtXNTFa$_4_Io2BZNRf=#}*&f&j~a z!K#ZZ&c(qR!Hb)Bl!$f+K4{o5C=N?BMMo4} z@a3ZmS)%^}Qt9W5W?jnKdC{G`=t?8)!KCCr|e8#Ws4}0&ZBHBCrSl8Vy3P> zxF~U9VJJvi$*%G4r<^^vRZSE*Xw%4f|94u?M1vJC1vpRFqxqk?77L8rBMFQ}KJe<= zY$d;x%IJ8_BlpVzt3$fM5$fD9%}(VCAju0NvqOUS9DE%A2>La*7`ciJkMQGyX`Xyt zNA%ePoYM&U9)A{D*M$#(b9p8{4r4CYuoHFB({{3NicCT#d*;?Hu05s)ag3fI8aIfr z^Ae5F>6YxgKDy}iD^))NcefVoQ@~f%^PEfD*GpC6%bin%l((Z&OO(f|-7_F_8I%i* zL{x+}H%#bUYv975U{mZy*FR1O;IWlp8cCqb_b4+?l+i5$>jW2rpnnf5b` zHo>Nm)sh)5S1f#~eeNO(dK))MAg^dbhGKQJZ|ss8SUC~Lc&o<_Z@FMXr>KsmSr1@P z7)qQF9gT?$=rmv5-A!%LNw^-fo}(+Vzn3CEDK1e3f!3hR1&F5TbV!luev-H5bi|>` zF*|=;t-y+0=BY+15bt~y>kR=6B-`jl5xbC#+*|Mf*27pxP;gD!Gx(#3-E4x=gj8_I zD-6PD?X4`_IuP1;HyOU`=Ku{EjRc$NKmu4=7%Oc=#X6w{#a$9T-`75WmEK%(QvPvv77cmBs zp=#5;b2wMtnyGSHT!lxao(^7Z(J@Tr@<>F>eW&U~;7$|Gl?oG81&0Z>or;d|zz9Bs z(U9yL*H2%^YPI-^5*+~#I+9oLuu75Kzxg7B;y*bK>(kn_X6u$Enx8|yOV`jP;7p}M zeq|^)%DkZ5DKE3>)T>fw)-;WK+v_A5qD$^H=ZiSs6!;T9!W7%8<0QV(O&* z0+mFip0#NV{?jR;dPHMli@=_A16^WbEaqyf0T*_E=Ox4zZj3PURkW_Pt+N*rrX0>I zIP3LewIe~pkTlG7Jo8mqANxpDYN=0^I#hNJYyrndcp!}KrluN052ai~ml)oc8-;xM z)QbTU-ycGjrC>OYJdDv)Q>9nxB=wn!msSBW?elHoI<=Q0JQ!hg5eW3OiuS>(%ngtY zu+;vc9Scn*bd}-8lX!){@znc zQ|utl0kt;|;a^6>vH?Gxkl+T86WFqJz!%+@+jK8LlLl=AQu&a@gJIh`ryWT5Nus&@ zkFNvk#eQCl+0Xx|Fi1yM1E5l1Xh3MRt@B~b;9UG@ohP6`K;H^i2aYlxj7f8q?)t?@ zSJg=!?dblQPiR!Iv9j4K0MUVoe1Xcez{oCi+ib|}4@N@>;NOAUQa4#BnEFssbL-)3 z{-|SDBkbaW>f2^uC3hDC&7ow1J9(@qrkh6-z{L{F#E0aGh~Sy_hZh~S0mbi3L`&o^S{5c``?CPFR8($MFP8K|vE%v$syma%*t$_Dx%|{)Bnur2 zxK&D*y&cW5R&&0RU#0_>0FIEBQCkH9W^zMhiTM8fYE|G4{<1k?HSeVFzp-Q*S$UW4 zmGpOKF_q|DMi<OZ;1v=_S9>z;?=1-6^vy|udW$^S$w*4S9C%Tex` zkS^}AL37v0s+#Ir@O%dUZRH$M9<}dleUpkSO--MBxX#T$2-v;V&-t!4aQv-~IiQTG zep?%WS$cfUsV_Uob#?!hkzH5_ndLa3d{&lPtOjRjD}}__3()S&&T0svpx}(mFFyNE zP>1?^GxsHe35@s9^@beH?eA0W$j4*}XYqcZl1V*%Z5ZWb)pknROW~F#if&H2q~Jc; zn8w*h=Ql_T+t^ZN&wqzBdWSL>mHVPiJ;ywn9J0EKuh<_0wl0-d;5KmV%OOtN?KW-; z8@u}+`Ul(9NW{>l=MD8YZqtr-0kMX{jTDO@0T7D1fm^1_LU$k?@Dn^NLn79rokUpl zP(6R%BWT9$feitzXPv`?n9e{so2x6i>53`Z!3WXP9hu7h5FUjXFL7s9vrZMd_&GC{!EJST)L zi{nm7N}VJM*#o(aZD9(hBq%h>JvFX6*tVD)3-FoM)|kLy)t0s>KXz*Xia@?wJMKo8 zcj0;2Ab>H{C&U;A(0hQd2Igw*avAgqwy`{fMr(T=3vc^f}Q*B~F3*J0K~MfliaC(p-xA)KtrT-sZM? z?njXnbs5E)s%f@>mu_@*E{q&rDx?9#*MX)Iy`X>`q4HV_;Qee|6TvlrsBlc_JUodl ze*_RE^iZ5XKcqZ5ZXbBf9_R8!mWYc>d2M{6?bj9WuNU)2I=L{BfWq*}O<6e_^>O%H z=rVW|*&+NkvfUxD{fzpA(|}YS#=MM{1K-3a!;B-a9`zHL7>^W+`gs(yL-dg#)g%0a zFeg>tsl10|gqFX$bai*>okqh^ht~FtvToAKzZ5a9`;`+gfJ4}Q0x&w8=N$4qHvHi<(QKwQdhy##2h`bZ z9%%tka3B_5bs~$nJjS98?B&xaCV56_)Q>-ZX184Tcm9U&SM;%mPy^bXpOXDBV4A`S zA|J9AK%JnYW1P~{(}ZT}Ysz$Q@=k3C?r- tY;fPwOjuTQEFi-RI6t`Ia`PtWEbz<)T&&+`vlQ0t#x)cD3WWW$e*)@P`P~2j diff --git a/plugin/home/.env.massastation b/plugin/home/.env.massastation index afb17d4c..362e8b90 100644 --- a/plugin/home/.env.massastation +++ b/plugin/home/.env.massastation @@ -1,3 +1,3 @@ -VITE_BASE_APP="/plugin/massa-labs/deweb-plugin/web" -VITE_BASE_API="/plugin/massa-labs/deweb-plugin/api" +VITE_BASE_APP="/plugin/massa-labs/local-deweb-provider/web" +VITE_BASE_API="/plugin/massa-labs/local-deweb-provider/api" VITE_ENV="massastation" \ No newline at end of file diff --git a/plugin/manifest.json b/plugin/manifest.json index 7e1ca083..9067ac6c 100644 --- a/plugin/manifest.json +++ b/plugin/manifest.json @@ -1,7 +1,7 @@ { "author": "Massa Labs", "name": "Local DeWeb Provider", - "description": "Local DeWeb Provider is a plugin that allows you to access the DeWeb from your computer.", + "description": "Your private access to DeWeb.", "logo": "favicon.png", "home": "", "version": "0.1.0", From e9a85ebb668e92840ce2122979e101bcae0e6cf7 Mon Sep 17 00:00:00 2001 From: thomas-senechal Date: Thu, 15 May 2025 12:49:06 +0200 Subject: [PATCH 56/57] Update title in index.html to and update favicon for plugin frontend --- plugin/home/index.html | 2 +- plugin/home/public/favicon.png | Bin 5032 -> 680 bytes 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin/home/index.html b/plugin/home/index.html index 4f7e5dfe..679492c5 100644 --- a/plugin/home/index.html +++ b/plugin/home/index.html @@ -5,7 +5,7 @@ - DeWeb Plugin + Local DeWeb Provider diff --git a/plugin/home/public/favicon.png b/plugin/home/public/favicon.png index 297aa0c6c30b9cf4a5e2b28526c9736747b6893a..77a993eabf0a9c9919ace730bab9ca15327cc867 100644 GIT binary patch delta 641 zcmV-{0)G9dC#VG>iBL{Q4GJ0x0000DNk~Le0000m0000m2nGNE09OL}hmj#Pe*z;( zL_t(|0qvNvPr^_T#_zQ?CMIkS>VP9|3So5VAfvcBFc}yA3XQJ*16_<0CT`&Bz~X4o zQC9~O6E_kP4W;@uDXG|E3-1n^@Jk3Gkn+Cw?%v&fYJF|nqm<;-3KdkIY_mkRD$<5p zjs5M;=MizDCJ`{ozPU?vvl=Oce_Mb-8n|`u>G1268txrQqeTGdQjaeB*W|b@l0=(; z0H@y+Jqhgs07SfbA0z>b0EE*?|B@tN5daR=0ynGzBocWc zVAik;7}w}cOO95uEudiJ`302K7I9%4C4K=lYmd0FjUvAQ#A(^ke+rmEe-NG`x6rwD z>`!sJz_Tzw0TBV%sk%`mU4*AUu{uz*D#KlyhPqXynpqiswn&h=b>QcOGiasmRD-Yy zFCK^r05}QTEBT`*X6Yp05tJx8o;i z&E%`RQT!6%^jrSoCn4~K@UG*!OvIiWX=~FB{RNI9O9K2CvmfM<{JSzm`h(M4d1YM^j8rzD4+lU01jnXNoGw=04e|g b00;m8000000Mb*F00000NkvXXu0mjfXOs-@ literal 5032 zcmb_gXH*kix1K-md?6cNHpkxpodfP^9-BE1OGOHis1 z5dtW^DJ`KWf+AHE1ibNn>s{;K-}nC5>zwn<-gDN>?ERc)PrSLQ0gM^J3;+Pk$WZq> z0D#~$lZHZQ$O~N|0&QTz7~1*)01L-o0|D7NyfhHxcilh-s2M`8(H3C0%O;lrpgx)9 z$e95EI5drPFIxnGHs;N|INh?z+hw3d@i$ZkhPe7B8!?fO1I}5A;r6`EE}>12SAZc$ zsh4*@RV^gOF=M5OXPgsp%{|5a5ZW7Q&dXc38a^O5{$YM2 zqOEe_XLZG_ub)OTWbKK4-r}^Xkh)Hbl4vSw- znq)T!>yF6+&OAk*+>Y+ihUt={0t{t%KV#z%&7aFm7w1GGcxxl>RU}fL^6c?p&!5e@an#B;WGt?k zV?SCY+WPtgJ!g=URJFFGRKBjr(yfWztQSAI0;0vT%eMcF(b3V@ z6=#rt{Su>qZr3za{b_LQCYoZx$_hu%nT&|^O;(bbSPP6k?OfpF5B<`}_7BCrLet^v z_4`ScGHSXWa!NRS^1#NdW-MeRnndaz4PL2d3%b5C`K0N@IU_*~QFLUR4JC|@y4-c& zNd*jXaEGD%NNRnsT?ge_>5{a^fPbQdKsGxt2E7CItGlD zT01}>pL>#XEy*tviti|g8lOUFABKcdR9CZWcfH&u>#LXQ+R}h*X^^x`N zjt7;5goNeH9}5L)`*hTy(yIh-?h1_TYd zk6{jeMHh5H&1HV2M-Np*lf5ALg@J2R2M{j0=L%4O`Ja@fyp5ciYbNY^gO|6dT3M`_2CRc5;cVod~SXpSlrr^T&RYP zY2H@2nN9`XEN+VSXtkPP(g~`EpENavpxEKarVXyGuOcVgQ?Zk&yIab{8HdWQ4}>Dr`K|1@qNxV z^WcDI^y`KU8tg2JN~!4SvA)Lse(;zxF7CDd{wbtktQCAF{~=lw{>YQ7$Gf>D_!kte zBo2qbz?xQ8js_jj4K7rh)dD*mOu6*gkS$+J*R}DYFqB1 z%-Kj$*sM;o%Om9~tc?qM;A1BMoS|C4aV+tgNOs*h`|1;Y>`4>Beg#5iK zEX`{9pTOr47cBZA(e%m(yeh<3jZW$;P&ha)L5v>?pU~|DHL)Yh#xnE%Y|d-~zg^jPI+`hb9dmU~u;7Jt_yVHC~bulv77 z3v>HN@t%@86b?-NZv)3P$$Y$w5$1i59Hhkt_{MWivLk`2Q~w9s;J7oiv?TlVS*Ww% zE&abVrkh+@=~J{iyEbIkdhV9b=I^oTX~B8J*0R-bP_`ZhY)Zd4lv^q-{dx74Zt}jC z%d&6aev7g35wGTSZU>DZ`#v@bd`5|5VbNme?G%j7&NPhzApXvYS^$i_l@--}U@-lluW?G`*qV*sB}i)UjUO|0LR$((JA>G(mBR&LNsH7PsehSGn+bpw9-+g)oK}r>_VC7^Wr2?>o?QMgb z<1LR19@p-zuBUHJPEL=F?_MTy>rH1VsVQ8YZul}h@?!nx_iG@Li(rF9fA^gp9*Sxc zt|as1gno3GUqF+)<27cnTUyDk!>=8lKk%tcQCY8%yV}_{oMlfJ$(v=Sp`@lhyV9G) zan1bEqcBcO-fA3fEI``22Kl7zfmUXr$lbW2V6eesV!rRmQH<_yzV2>=Vv%@U9NcIu zd#75Y1aunD;gnc-g~MOb`uceNazqc6nmXwE{d;Ef*Uj;*krv4Z-_Np)NXx*l8sTwP zXYD-PoqpMj)o_ttQBHCg?$_z`IE(a;m?IF@wStrx3$oO)pL_9>11WbfmqAP#99GJ| z8q1ETN4>?)vm;@KVoLrIIEcPsXr!mRdl1kjf(kq}3^7UbMpPZcV1$vtk7HWnTU&U# z2{dM+aQ8xQFSmrzVNFd3_`W_)?QFCE3t48>0`BNyT#&vyLd&}LcI@jjbwj&O!`CKs zFcSrZg;K#|4T@`5WC^LME_4=Xj78z#h^Y?I7imJnaTnt zOTr%Y_phidy(mf2KR&Pvs8i?N!BRhzOzPW7HJ!|zob0=2y^%0o0g*&}e7bUQK^%gb zGqX&v6?&2gKh23aGcsaxi-$W!M3q?x>0!k$Bbe@TF*a%Len=YYTOu?{1CK}NVbm|vk9MeHOU!B&h4W4b3H9eb)Ns&NjLMN$ow zRHs7To#%C2_?qhhaW~n7eVF-?a%OjNGJVh9z%A|NxXKg~+RxnSDYU*m_B#8z(Iz+B zijhbR`ezSj%}vXt;^Ize3Td%{&Png=PI(H+cQbFcddnW32=FlTA?3;P0u|R;{sT#{gz6u&a$o$Jbgmhm$hG5ta#=x$IT%3y(04n<4jw=_ZvzR^tG^8GV~XY)uAy~WIfytLnI;}CvMJC74nz7#PJ zeR3yNHO`CB3TKNhRycYvK+u60_|(oikU##R4@UPa0-Gg${4#Jxe>&dBT`5v=tc2IE z1AUW1E58vigM`0Ne=9Q}T>i<~+eP+)oPh%^U)B5kmOWOONQ+Q(#=L?>Kj968OyixU zv^-8ZAOBoEut6ZF3W_+q7}4Ayt}VzJVjCW*6;4PwPmxe(7C`dIA-SIHy>)7i){yqc ze37u7?#_7eqAX3K<`uYLy$|A6}T0V#{m2G zUoo+LZtlYBP=ZNKCA_2cx}4VI6k3^qtyI{N&xq@o@HkhmZ_ekXu1IG;8U@(YjuV`TV9b@`mYN-CydE8lq{9_934UPiL1eJJZzx$|0fn7)Hu*<@k%4 z)-+4Jn9;GVGDVy$ z5tl4zK)>f;eKk;MIb29dNniicOvuI|nwxNfgoh5ww$s0d-{BT|fh=uT6|TKJ5r6(64Usbq$Twy8a3N~$}B1dTXj1+}e4kPQDrDE%v#{{P47 zMd}vD2eml0Z!U3WtuMR}Eyl9f);LvLL0^8CZ*6g%KO+QgWRkh`+ zS+oRgGlHlKw7P$*%7H9p@Q9XNcnd~zcS%&M47hIcNOK!ws?J?~+)EaEccjs11hUpC zS26CWpRn*#dXCPd9DNQw6u{EkEi#(l=e<|WfFBz{MV^2%7*j-Z8x>SuN=MnaUqq$j z$Sr=mdm30ycdhL=ag3)4!%C=yHhHE|-HFO`tPa>aU!K)l?SV{MAMF$ow~yL7pRx(0 z70}vBMH+jmssCgF)a_i|#gw|Z)-H(V=PkV2ZolJL#by{yj4#GR`bI`ht$kG&20X_r zbVB2zAo|}Tf1vGskA}j2#grJzvcZyRnrdwJchufqyS(;jPowtc{LPHDwNI>7^s=yo zuzx}?puF=G^MBE*X^Xlbt)XPz+PeRYtl~jy&BHI9tR5oz8k#9(Q3dLO=j2|eK6vQ6J?fQzd4HvGwH4@sf8FHdnvGtbR?GF*2dEAg zGUO|~1e#AWfUcXT{hY%Z! zD;H5OWuGyxZ2Dreiv8^uaQ*uRfcm-qS%z|!XXKq;mwx2EpZqO3GZm3^XKee71kkO@ Rv>$7Lk)Ek;jgC|Fe*rCbIN<;Q From 6ee6e2e2623647f591442a4ffc3fd4bd76bac1c9 Mon Sep 17 00:00:00 2001 From: thomas-senechal Date: Thu, 15 May 2025 12:59:41 +0200 Subject: [PATCH 57/57] Add AWS S3 upload step and configure AWS credentials in release workflow --- .github/workflows/release.yml | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 13441881..8cef8751 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -61,6 +61,7 @@ jobs: runs-on: ubuntu-latest permissions: contents: write + id-token: write steps: - name: Download server artifacts uses: actions/download-artifact@v4 @@ -89,5 +90,18 @@ jobs: prerelease: ${{ inputs.release-as-prerelease }} generate_release_notes: ${{ inputs.generate-release-notes }} files: | - artifacts/deweb-server_*/deweb-server_* + artifacts/server/deweb-server_*/deweb-server_* artifacts/plugin/deweb-plugin_*_zip/deweb-plugin_*.zip + + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + aws-region: eu-west-3 + aws-access-key-id: ${{ secrets.MS_S3_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ secrets.MS_S3_SECRET_ACCESS_KEY }} + + - name: s3 Upload + env: + AWS3: ${{ vars.MS_S3_BUCKET }} + TAG: ${{ inputs.version }} + run: aws s3 cp artifacts/plugin/deweb-plugin_*_zip/deweb-plugin_*.zip s3://${AWS3}/plugins/deweb/${TAG}/