From 74c6a0a43419170257f7dd3b1b3e2a164fafa589 Mon Sep 17 00:00:00 2001 From: Ralph Slooten Date: Tue, 20 May 2025 16:51:02 +1200 Subject: [PATCH 1/8] Chore: Switch from unnecessary float64 to uint64 API values for App Information, message & attachment sizes --- internal/pop3/server.go | 6 +-- internal/stats/stats.go | 30 +++++++------- internal/storage/cron.go | 12 +++--- internal/storage/database.go | 20 ++++----- internal/storage/messages.go | 18 ++++---- internal/storage/messages_test.go | 12 +++--- internal/storage/notifications.go | 4 +- internal/storage/search.go | 24 +++++------ internal/storage/search_test.go | 2 +- internal/storage/settings.go | 14 +++---- internal/storage/structs.go | 10 ++--- internal/storage/testing.go | 4 +- internal/storage/utils.go | 4 +- server/apiv1/messages.go | 20 ++++----- server/server_test.go | 6 +-- server/ui/api/v1/swagger.json | 68 ++++++++++++++++--------------- 16 files changed, 129 insertions(+), 125 deletions(-) diff --git a/internal/pop3/server.go b/internal/pop3/server.go index 19e8bb4..0ad614a 100644 --- a/internal/pop3/server.go +++ b/internal/pop3/server.go @@ -80,7 +80,7 @@ func Run() { type message struct { ID string - Size float64 + Size uint64 } func handleClient(conn net.Conn) { @@ -211,13 +211,13 @@ func handleClient(conn net.Conn) { func handleTransactionCommand(conn net.Conn, cmd string, args []string, messages []message, toDelete *[]string) { switch cmd { case "STAT": - totalSize := float64(0) + totalSize := uint64(0) for _, m := range messages { totalSize += m.Size } sendResponse(conn, fmt.Sprintf("+OK %d %d", len(messages), int64(totalSize))) case "LIST": - totalSize := float64(0) + totalSize := uint64(0) for _, m := range messages { totalSize += m.Size } diff --git a/internal/stats/stats.go b/internal/stats/stats.go index d4ff888..8074a84 100644 --- a/internal/stats/stats.go +++ b/internal/stats/stats.go @@ -20,10 +20,10 @@ var ( mu sync.RWMutex - smtpAccepted float64 - smtpAcceptedSize float64 - smtpRejected float64 - smtpIgnored float64 + smtpAccepted uint64 + smtpAcceptedSize uint64 + smtpRejected uint64 + smtpIgnored uint64 ) // AppInformation struct @@ -36,29 +36,29 @@ type AppInformation struct { // Database path Database string // Database size in bytes - DatabaseSize float64 + DatabaseSize uint64 // Total number of messages in the database - Messages float64 + Messages uint64 // Total number of messages in the database - Unread float64 + Unread uint64 // Tags and message totals per tag Tags map[string]int64 // Runtime statistics RuntimeStats struct { // Mailpit server uptime in seconds - Uptime float64 + Uptime uint64 // Current memory usage in bytes Memory uint64 // Database runtime messages deleted - MessagesDeleted float64 + MessagesDeleted uint64 // Accepted runtime SMTP messages - SMTPAccepted float64 + SMTPAccepted uint64 // Total runtime accepted messages size in bytes - SMTPAcceptedSize float64 + SMTPAcceptedSize uint64 // Rejected runtime SMTP messages - SMTPRejected float64 + SMTPRejected uint64 // Ignored runtime SMTP messages (when using --ignore-duplicate-ids) - SMTPIgnored float64 + SMTPIgnored uint64 } } @@ -71,7 +71,7 @@ func Load() AppInformation { runtime.ReadMemStats(&m) info.RuntimeStats.Memory = m.Sys - m.HeapReleased - info.RuntimeStats.Uptime = time.Since(startedAt).Seconds() + info.RuntimeStats.Uptime = uint64(time.Since(startedAt).Seconds()) info.RuntimeStats.MessagesDeleted = storage.StatsDeleted info.RuntimeStats.SMTPAccepted = smtpAccepted info.RuntimeStats.SMTPAcceptedSize = smtpAcceptedSize @@ -112,7 +112,7 @@ func Track() { func LogSMTPAccepted(size int) { mu.Lock() smtpAccepted = smtpAccepted + 1 - smtpAcceptedSize = smtpAcceptedSize + float64(size) + smtpAcceptedSize = smtpAcceptedSize + uint64(size) mu.Unlock() } diff --git a/internal/storage/cron.go b/internal/storage/cron.go index 992a83f..93707cf 100644 --- a/internal/storage/cron.go +++ b/internal/storage/cron.go @@ -32,7 +32,7 @@ func dbCron() { if total == 0 { deletedPercent = 100 } else { - deletedPercent = deletedSize * 100 / total + deletedPercent = float64(deletedSize * 100 / total) } // only vacuum the DB if at least 1% of mail storage size has been deleted if deletedPercent >= 1 { @@ -56,13 +56,13 @@ func pruneMessages() { start := time.Now() ids := []string{} - var prunedSize int64 - var size float64 + var prunedSize uint64 + var size uint64 // prune using `--max` if set if config.MaxMessages > 0 { total := CountTotal() - if total > float64(config.MaxAgeInHours) { + if total > uint64(config.MaxAgeInHours) { offset := config.MaxMessages if config.DemoMode { offset = 500 @@ -81,7 +81,7 @@ func pruneMessages() { return } ids = append(ids, id) - prunedSize = prunedSize + int64(size) + prunedSize = prunedSize + size }); err != nil { logger.Log().Errorf("[db] %s", err.Error()) @@ -110,7 +110,7 @@ func pruneMessages() { if !tools.InArray(id, ids) { ids = append(ids, id) - prunedSize = prunedSize + int64(size) + prunedSize = prunedSize + size } }); err != nil { diff --git a/internal/storage/database.go b/internal/storage/database.go index e0a98d5..3a1e0e4 100644 --- a/internal/storage/database.go +++ b/internal/storage/database.go @@ -210,8 +210,8 @@ func StatsGet() MailboxStats { } // CountTotal returns the number of emails in the database -func CountTotal() float64 { - var total float64 +func CountTotal() uint64 { + var total uint64 _ = sqlf.From(tenant("mailbox")). Select("COUNT(*)").To(&total). @@ -221,8 +221,8 @@ func CountTotal() float64 { } // CountUnread returns the number of emails in the database that are unread. -func CountUnread() float64 { - var total float64 +func CountUnread() uint64 { + var total uint64 _ = sqlf.From(tenant("mailbox")). Select("COUNT(*)").To(&total). @@ -233,8 +233,8 @@ func CountUnread() float64 { } // CountRead returns the number of emails in the database that are read. -func CountRead() float64 { - var total float64 +func CountRead() uint64 { + var total uint64 _ = sqlf.From(tenant("mailbox")). Select("COUNT(*)").To(&total). @@ -245,17 +245,17 @@ func CountRead() float64 { } // DbSize returns the size of the SQLite database. -func DbSize() float64 { - var total sql.NullFloat64 +func DbSize() uint64 { + var total sql.NullInt64 err := db.QueryRow("SELECT page_count * page_size AS size FROM pragma_page_count(), pragma_page_size()").Scan(&total) if err != nil { logger.Log().Errorf("[db] %s", err.Error()) - return total.Float64 + return uint64(total.Int64) } - return total.Float64 + return uint64(total.Int64) } // MessageIDExists checks whether a Message-ID exists in the DB diff --git a/internal/storage/messages.go b/internal/storage/messages.go index 2d359b4..e23192f 100644 --- a/internal/storage/messages.go +++ b/internal/storage/messages.go @@ -85,7 +85,7 @@ func Store(body *[]byte) (string, error) { defer tx.Rollback() subject := env.GetHeader("Subject") - size := float64(len(*body)) + size := uint64(len(*body)) inline := len(env.Inlines) attachments := len(env.Attachments) snippet := tools.CreateSnippet(env.Text, env.HTML) @@ -201,12 +201,12 @@ func List(start int, beforeTS int64, limit int) ([]MessageSummary, error) { } if err := q.QueryAndClose(context.TODO(), db, func(row *sql.Rows) { - var created float64 + var created uint64 var id string var messageID string var subject string var metadata string - var size float64 + var size uint64 var attachments int var read int var snippet string @@ -294,7 +294,7 @@ func GetMessage(id string) (*Message, error) { Where(`ID = ?`, id) if err := q.QueryAndClose(context.TODO(), db, func(row *sql.Rows) { - var created float64 + var created uint64 if err := row.Scan(&created); err != nil { logger.Log().Errorf("[db] %s", err.Error()) @@ -321,7 +321,7 @@ func GetMessage(id string) (*Message, error) { ReturnPath: returnPath, Subject: env.GetHeader("Subject"), Tags: getMessageTags(id), - Size: float64(len(raw)), + Size: uint64(len(raw)), Text: env.Text, } @@ -462,7 +462,7 @@ func AttachmentSummary(a *enmime.Part) Attachment { } o.ContentType = a.ContentType o.ContentID = a.ContentID - o.Size = float64(len(a.Content)) + o.Size = uint64(len(a.Content)) return o } @@ -617,11 +617,11 @@ func DeleteMessages(ids []string) error { defer rows.Close() toDelete := []string{} - var totalSize float64 + var totalSize uint64 for rows.Next() { var id string - var size float64 + var size uint64 if err := rows.Scan(&id, &size); err != nil { return err } @@ -663,7 +663,7 @@ func DeleteMessages(ids []string) error { } dbLastAction = time.Now() - addDeletedSize(int64(totalSize)) + addDeletedSize(totalSize) logMessagesDeleted(len(toDelete)) diff --git a/internal/storage/messages_test.go b/internal/storage/messages_test.go index 7f19d8d..30bf108 100644 --- a/internal/storage/messages_test.go +++ b/internal/storage/messages_test.go @@ -22,7 +22,7 @@ func TestTextEmailInserts(t *testing.T) { } } - assertEqual(t, CountTotal(), float64(testRuns), "Incorrect number of text emails stored") + assertEqual(t, CountTotal(), uint64(testRuns), "Incorrect number of text emails stored") t.Logf("Inserted %d text emails in %s", testRuns, time.Since(start)) @@ -32,7 +32,7 @@ func TestTextEmailInserts(t *testing.T) { t.Fail() } - assertEqual(t, CountTotal(), float64(0), "incorrect number of text emails deleted") + assertEqual(t, CountTotal(), uint64(0), "incorrect number of text emails deleted") t.Logf("deleted %d text emails in %s", testRuns, time.Since(delStart)) @@ -60,7 +60,7 @@ func TestMimeEmailInserts(t *testing.T) { } } - assertEqual(t, CountTotal(), float64(testRuns), "Incorrect number of mime emails stored") + assertEqual(t, CountTotal(), uint64(testRuns), "Incorrect number of mime emails stored") t.Logf("Inserted %d text emails in %s", testRuns, time.Since(start)) @@ -70,7 +70,7 @@ func TestMimeEmailInserts(t *testing.T) { t.Fail() } - assertEqual(t, CountTotal(), float64(0), "incorrect number of mime emails deleted") + assertEqual(t, CountTotal(), uint64(0), "incorrect number of mime emails deleted") t.Logf("Deleted %d mime emails in %s", testRuns, time.Since(delStart)) @@ -122,14 +122,14 @@ func TestRetrieveMimeEmail(t *testing.T) { t.Log("error ", err) t.Fail() } - assertEqual(t, float64(len(attachmentData.Content)), msg.Attachments[0].Size, "attachment size does not match") + assertEqual(t, uint64(len(attachmentData.Content)), msg.Attachments[0].Size, "attachment size does not match") inlineData, err := GetAttachmentPart(id, msg.Inline[0].PartID) if err != nil { t.Log("error ", err) t.Fail() } - assertEqual(t, float64(len(inlineData.Content)), msg.Inline[0].Size, "inline attachment size does not match") + assertEqual(t, uint64(len(inlineData.Content)), msg.Inline[0].Size, "inline attachment size does not match") Close() } diff --git a/internal/storage/notifications.go b/internal/storage/notifications.go index c54e122..ff42959 100644 --- a/internal/storage/notifications.go +++ b/internal/storage/notifications.go @@ -24,8 +24,8 @@ func BroadcastMailboxStats() { time.Sleep(250 * time.Millisecond) bcStatsDelay = false b := struct { - Total float64 - Unread float64 + Total uint64 + Unread uint64 Version string }{ Total: CountTotal(), diff --git a/internal/storage/search.go b/internal/storage/search.go index 85ab59b..9dc1cb3 100644 --- a/internal/storage/search.go +++ b/internal/storage/search.go @@ -39,12 +39,12 @@ func Search(search, timezone string, start int, beforeTS int64, limit int) ([]Me var err error if err := q.QueryAndClose(context.TODO(), db, func(row *sql.Rows) { - var created float64 + var created uint64 var id string var messageID string var subject string var metadata string - var size float64 + var size uint64 var attachments int var snippet string var read int @@ -141,15 +141,15 @@ func DeleteSearch(search, timezone string) error { q := searchQueryBuilder(search, timezone) ids := []string{} - deleteSize := float64(0) + deleteSize := uint64(0) if err := q.QueryAndClose(context.TODO(), db, func(row *sql.Rows) { - var created float64 + var created uint64 var id string var messageID string var subject string var metadata string - var size float64 + var size uint64 var attachments int var read int var snippet string @@ -247,7 +247,7 @@ func DeleteSearch(search, timezone string) error { } } - addDeletedSize(int64(deleteSize)) + addDeletedSize(deleteSize) logMessagesDeleted(total) @@ -264,12 +264,12 @@ func SetSearchReadStatus(search, timezone string, read bool) error { ids := []string{} if err := q.QueryAndClose(context.TODO(), db, func(row *sql.Rows) { - var created float64 + var created uint64 var id string var messageID string var subject string var metadata string - var size float64 + var size uint64 var attachments int var read int var snippet string @@ -519,7 +519,7 @@ func searchQueryBuilder(searchString, timezone string) *sqlf.Stmt { // // K, k, Kb, KB, kB and kb are treated as Kilobytes. // M, m, Mb, MB and mb are treated as Megabytes. -func sizeToBytes(v string) int64 { +func sizeToBytes(v string) uint64 { v = strings.ToLower(v) re := regexp.MustCompile(`^(\d+)(\.\d+)?\s?([a-z]{1,2})?$`) @@ -537,15 +537,15 @@ func sizeToBytes(v string) int64 { } if unit == "" { - return int64(i) + return uint64(i) } if unit == "k" || unit == "kb" { - return int64(i * 1024) + return uint64(i * 1024) } if unit == "m" || unit == "mb" { - return int64(i * 1024 * 1024) + return uint64(i * 1024 * 1024) } return 0 diff --git a/internal/storage/search_test.go b/internal/storage/search_test.go index 1506d04..1c574a3 100644 --- a/internal/storage/search_test.go +++ b/internal/storage/search_test.go @@ -203,7 +203,7 @@ func TestEscPercentChar(t *testing.T) { } func TestSizeToBytes(t *testing.T) { - tests := map[string]int64{} + tests := map[string]uint64{} tests["1m"] = 1048576 tests["1mb"] = 1048576 tests["1 M"] = 1048576 diff --git a/internal/storage/settings.go b/internal/storage/settings.go index 6f1754f..81a6bf1 100644 --- a/internal/storage/settings.go +++ b/internal/storage/settings.go @@ -35,8 +35,8 @@ func SettingPut(k, v string) error { } // The total deleted message size as an int64 value -func getDeletedSize() float64 { - var result sql.NullFloat64 +func getDeletedSize() uint64 { + var result sql.NullInt64 err := sqlf.From(tenant("settings")). Select("Value").To(&result). Where("Key = ?", "DeletedSize"). @@ -47,12 +47,12 @@ func getDeletedSize() float64 { return 0 } - return result.Float64 + return uint64(result.Int64) } // The total raw non-compressed messages size in bytes of all messages in the database -func totalMessagesSize() float64 { - var result sql.NullFloat64 +func totalMessagesSize() uint64 { + var result sql.NullInt64 err := sqlf.From(tenant("mailbox")). Select("SUM(Size)").To(&result). QueryAndClose(context.TODO(), db, func(row *sql.Rows) {}) @@ -61,11 +61,11 @@ func totalMessagesSize() float64 { return 0 } - return result.Float64 + return uint64(result.Int64) } // AddDeletedSize will add the value to the DeletedSize setting -func addDeletedSize(v int64) { +func addDeletedSize(v uint64) { if _, err := db.Exec(`INSERT OR IGNORE INTO `+tenant("settings")+` (Key, Value) VALUES(?, ?)`, "DeletedSize", 0); err != nil { logger.Log().Errorf("[db] %s", err.Error()) } diff --git a/internal/storage/structs.go b/internal/storage/structs.go index b9e9fc7..51068b2 100644 --- a/internal/storage/structs.go +++ b/internal/storage/structs.go @@ -38,7 +38,7 @@ type Message struct { // Message body HTML HTML string // Message size in bytes - Size float64 + Size uint64 // Inline message attachments Inline []Attachment // Message attachments @@ -58,7 +58,7 @@ type Attachment struct { // Content ID ContentID string // Size in bytes - Size float64 + Size uint64 } // MessageSummary struct for frontend messages @@ -88,7 +88,7 @@ type MessageSummary struct { // Message tags Tags []string // Message size in bytes (total) - Size float64 + Size uint64 // Whether the message has any attachments Attachments int // Message snippet includes up to 250 characters @@ -97,8 +97,8 @@ type MessageSummary struct { // MailboxStats struct for quick mailbox total/read lookups type MailboxStats struct { - Total float64 - Unread float64 + Total uint64 + Unread uint64 Tags []string } diff --git a/internal/storage/testing.go b/internal/storage/testing.go index 7526793..dc98da8 100644 --- a/internal/storage/testing.go +++ b/internal/storage/testing.go @@ -59,11 +59,11 @@ func assertEqual(t *testing.T, a interface{}, b interface{}, message string) { func assertEqualStats(t *testing.T, total int, unread int) { s := StatsGet() - if float64(total) != s.Total { + if uint64(total) != s.Total { t.Fatalf("Incorrect total mailbox stats: \"%v\" != \"%v\"", total, s.Total) } - if float64(unread) != s.Unread { + if uint64(unread) != s.Unread { t.Fatalf("Incorrect unread mailbox stats: \"%v\" != \"%v\"", unread, s.Unread) } } diff --git a/internal/storage/utils.go b/internal/storage/utils.go index c189c5d..5e4e816 100644 --- a/internal/storage/utils.go +++ b/internal/storage/utils.go @@ -16,7 +16,7 @@ var ( // for stats to prevent import cycle mu sync.RWMutex // StatsDeleted for counting the number of messages deleted - StatsDeleted float64 + StatsDeleted uint64 ) // AddTempFile adds a file to the slice of files to delete on exit @@ -88,7 +88,7 @@ func cleanString(str string) string { // LogMessagesDeleted logs the number of messages deleted func logMessagesDeleted(n int) { mu.Lock() - StatsDeleted = StatsDeleted + float64(n) + StatsDeleted = StatsDeleted + uint64(n) mu.Unlock() } diff --git a/server/apiv1/messages.go b/server/apiv1/messages.go index cd6e440..9832941 100644 --- a/server/apiv1/messages.go +++ b/server/apiv1/messages.go @@ -40,21 +40,21 @@ type messagesSummaryResponse struct { // MessagesSummary is a summary of a list of messages type MessagesSummary struct { // Total number of messages in mailbox - Total float64 `json:"total"` + Total uint64 `json:"total"` // Total number of unread messages in mailbox - Unread float64 `json:"unread"` + Unread uint64 `json:"unread"` // Legacy - now undocumented in API specs but left for backwards compatibility. // Removed from API documentation 2023-07-12 // swagger:ignore - Count float64 `json:"count"` + Count uint64 `json:"count"` // Total number of messages matching current query - MessagesCount float64 `json:"messages_count"` + MessagesCount uint64 `json:"messages_count"` // Total number of unread messages matching current query - MessagesUnreadCount float64 `json:"messages_unread"` + MessagesUnreadCount uint64 `json:"messages_unread"` // Pagination offset Start int `json:"start"` @@ -98,7 +98,7 @@ func GetMessages(w http.ResponseWriter, r *http.Request) { res.Start = start res.Messages = messages - res.Count = float64(len(messages)) // legacy - now undocumented in API specs + res.Count = uint64(len(messages)) // legacy - now undocumented in API specs res.Total = stats.Total res.Unread = stats.Unread res.Tags = stats.Tags @@ -349,9 +349,9 @@ func Search(w http.ResponseWriter, r *http.Request) { res.Start = start res.Messages = messages - res.Count = float64(len(messages)) // legacy - now undocumented in API specs - res.Total = stats.Total // total messages in mailbox - res.MessagesCount = float64(results) + res.Count = uint64(len(messages)) // legacy - now undocumented in API specs + res.Total = stats.Total // total messages in mailbox + res.MessagesCount = uint64(results) res.Unread = stats.Unread res.Tags = stats.Tags @@ -361,7 +361,7 @@ func Search(w http.ResponseWriter, r *http.Request) { return } - res.MessagesUnreadCount = float64(unread) + res.MessagesUnreadCount = uint64(unread) w.Header().Add("Content-Type", "application/json") if err := json.NewEncoder(w).Encode(res); err != nil { diff --git a/server/server_test.go b/server/server_test.go index 23f84e4..6681a54 100644 --- a/server/server_test.go +++ b/server/server_test.go @@ -340,8 +340,8 @@ func assertStatsEqual(t *testing.T, uri string, unread, total int) { return } - assertEqual(t, float64(unread), m.Unread, "wrong unread count") - assertEqual(t, float64(total), m.Total, "wrong total count") + assertEqual(t, uint64(unread), m.Unread, "wrong unread count") + assertEqual(t, uint64(total), m.Total, "wrong total count") } func assertSearchEqual(t *testing.T, uri, query string, count int) { @@ -361,7 +361,7 @@ func assertSearchEqual(t *testing.T, uri, query string, count int) { return } - assertEqual(t, float64(count), m.MessagesCount, "wrong search results count") + assertEqual(t, uint64(count), m.MessagesCount, "wrong search results count") } func insertEmailData(t *testing.T) { diff --git a/server/ui/api/v1/swagger.json b/server/ui/api/v1/swagger.json index 2a162c9..2e4de7e 100644 --- a/server/ui/api/v1/swagger.json +++ b/server/ui/api/v1/swagger.json @@ -1102,8 +1102,8 @@ }, "DatabaseSize": { "description": "Database size in bytes", - "type": "number", - "format": "double" + "type": "integer", + "format": "uint64" }, "LatestVersion": { "description": "Latest Mailpit version", @@ -1111,8 +1111,8 @@ }, "Messages": { "description": "Total number of messages in the database", - "type": "number", - "format": "double" + "type": "integer", + "format": "uint64" }, "RuntimeStats": { "description": "Runtime statistics", @@ -1125,33 +1125,33 @@ }, "MessagesDeleted": { "description": "Database runtime messages deleted", - "type": "number", - "format": "double" + "type": "integer", + "format": "uint64" }, "SMTPAccepted": { "description": "Accepted runtime SMTP messages", - "type": "number", - "format": "double" + "type": "integer", + "format": "uint64" }, "SMTPAcceptedSize": { "description": "Total runtime accepted messages size in bytes", - "type": "number", - "format": "double" + "type": "integer", + "format": "uint64" }, "SMTPIgnored": { "description": "Ignored runtime SMTP messages (when using --ignore-duplicate-ids)", - "type": "number", - "format": "double" + "type": "integer", + "format": "uint64" }, "SMTPRejected": { "description": "Rejected runtime SMTP messages", - "type": "number", - "format": "double" + "type": "integer", + "format": "uint64" }, "Uptime": { "description": "Mailpit server uptime in seconds", - "type": "number", - "format": "double" + "type": "integer", + "format": "uint64" } } }, @@ -1165,8 +1165,8 @@ }, "Unread": { "description": "Total number of messages in the database", - "type": "number", - "format": "double" + "type": "integer", + "format": "uint64" }, "Version": { "description": "Current Mailpit version", @@ -1197,8 +1197,8 @@ }, "Size": { "description": "Size in bytes", - "type": "number", - "format": "double" + "type": "integer", + "format": "uint64" } }, "x-go-package": "github.com/axllent/mailpit/internal/storage" @@ -1530,8 +1530,8 @@ }, "Size": { "description": "Message size in bytes", - "type": "number", - "format": "double" + "type": "integer", + "format": "uint64" }, "Subject": { "description": "Message subject", @@ -1622,8 +1622,8 @@ }, "Size": { "description": "Message size in bytes (total)", - "type": "number", - "format": "double" + "type": "integer", + "format": "uint64" }, "Snippet": { "description": "Message snippet includes up to 250 characters", @@ -1664,14 +1664,14 @@ }, "messages_count": { "description": "Total number of messages matching current query", - "type": "number", - "format": "double", + "type": "integer", + "format": "uint64", "x-go-name": "MessagesCount" }, "messages_unread": { "description": "Total number of unread messages matching current query", - "type": "number", - "format": "double", + "type": "integer", + "format": "uint64", "x-go-name": "MessagesUnreadCount" }, "start": { @@ -1690,14 +1690,14 @@ }, "total": { "description": "Total number of messages in mailbox", - "type": "number", - "format": "double", + "type": "integer", + "format": "uint64", "x-go-name": "Total" }, "unread": { "description": "Total number of unread messages in mailbox", - "type": "number", - "format": "double", + "type": "integer", + "format": "uint64", "x-go-name": "Unread" } }, @@ -1988,6 +1988,10 @@ "description": "Whether messages with duplicate IDs are ignored", "type": "boolean" }, + "HideDeleteAllButton": { + "description": "Whether the delete button should be hidden", + "type": "boolean" + }, "Label": { "description": "Optional label to identify this Mailpit instance", "type": "string" From ff272d1c5eb91acaf94d8b6293fba3b9a7e6c06b Mon Sep 17 00:00:00 2001 From: Ralph Slooten Date: Tue, 20 May 2025 16:55:37 +1200 Subject: [PATCH 2/8] Chore: Extend latest version cache expiration from 5 to 15 minutes --- internal/stats/stats.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/stats/stats.go b/internal/stats/stats.go index 8074a84..1d514a2 100644 --- a/internal/stats/stats.go +++ b/internal/stats/stats.go @@ -88,7 +88,7 @@ func Load() AppInformation { // clear latest version cache after 5 minutes go func() { - time.Sleep(5 * time.Minute) + time.Sleep(15 * time.Minute) latestVersionCache = "" }() } From 99a3e172435baa6d79bf69425ee98e9f727b0f98 Mon Sep 17 00:00:00 2001 From: Ralph Slooten Date: Fri, 23 May 2025 22:37:06 +1200 Subject: [PATCH 3/8] Fix: Update bootstrap5-tags to fix text pasting in message release modal (#498) --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 880bf0d..51eea01 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1709,9 +1709,9 @@ "license": "MIT" }, "node_modules/bootstrap5-tags": { - "version": "1.7.14", - "resolved": "https://registry.npmjs.org/bootstrap5-tags/-/bootstrap5-tags-1.7.14.tgz", - "integrity": "sha512-xN00X4eekFIVHDt8jo1y6jQwhWlTuVC9TOzOXi9FEFal/VzEtt78mToEgM+nPx6OV1xVNwgl5AX2s90ZHFsnYA==", + "version": "1.7.15", + "resolved": "https://registry.npmjs.org/bootstrap5-tags/-/bootstrap5-tags-1.7.15.tgz", + "integrity": "sha512-UnHmJC9p0ei5rZG1/5qOFBoKFJ+ZyXiVTi1+fJnN/+6d/htZZ9M4cALxsjxQR53K2PrOSApMBOR2QZDbIkdK+g==", "license": "MIT" }, "node_modules/brace-expansion": { From 91409310d768d356dbe7edab34eb10b6be70cc4d Mon Sep 17 00:00:00 2001 From: Ralph Slooten Date: Fri, 23 May 2025 23:19:54 +1200 Subject: [PATCH 4/8] Chore: Lighten outline-secondary buttons in dark mode --- server/ui-src/assets/styles.scss | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/server/ui-src/assets/styles.scss b/server/ui-src/assets/styles.scss index de15a73..3581816 100644 --- a/server/ui-src/assets/styles.scss +++ b/server/ui-src/assets/styles.scss @@ -89,6 +89,14 @@ .token.property { color: #ee6969; } + + .btn-outline-secondary { + color: #9c9c9c; + + &:hover { + color: $body-color-dark; + } + } } .text-spaces-nowrap { From b84b4284342a3a7706266ac76d9116642b4b5b74 Mon Sep 17 00:00:00 2001 From: Ralph Slooten Date: Sun, 25 May 2025 09:56:53 +1200 Subject: [PATCH 5/8] Chore: Add note to swagger docs about API date formats --- internal/storage/structs.go | 5 +++-- server/ui/api/v1/swagger.json | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/internal/storage/structs.go b/internal/storage/structs.go index 51068b2..edde6fa 100644 --- a/internal/storage/structs.go +++ b/internal/storage/structs.go @@ -29,7 +29,8 @@ type Message struct { Subject string // List-Unsubscribe header information ListUnsubscribe ListUnsubscribe - // Message date if set, else date received + // Message RFC3339Nano date & time (if set), else date & time received + // ([extended RFC3339](https://tools.ietf.org/html/rfc3339#section-5.6) format with optional nano seconds) Date time.Time // Message tags Tags []string @@ -83,7 +84,7 @@ type MessageSummary struct { ReplyTo []*mail.Address // Email subject Subject string - // Created time + // Received RFC3339Nano date & time ([extended RFC3339](https://tools.ietf.org/html/rfc3339#section-5.6) format with optional nano seconds) Created time.Time // Message tags Tags []string diff --git a/server/ui/api/v1/swagger.json b/server/ui/api/v1/swagger.json index 2e4de7e..f033dd1 100644 --- a/server/ui/api/v1/swagger.json +++ b/server/ui/api/v1/swagger.json @@ -1488,7 +1488,7 @@ } }, "Date": { - "description": "Message date if set, else date received", + "description": "Message RFC3339Nano date \u0026 time (if set), else date \u0026 time received\n([extended RFC3339](https://tools.ietf.org/html/rfc3339#section-5.6) format with optional nano seconds)", "type": "string", "format": "date-time" }, @@ -1594,7 +1594,7 @@ } }, "Created": { - "description": "Created time", + "description": "Received RFC3339Nano date \u0026 time ([extended RFC3339](https://tools.ietf.org/html/rfc3339#section-5.6) format with optional nano seconds)", "type": "string", "format": "date-time" }, From 04ea90561925449af105b27026fc18f8c6461562 Mon Sep 17 00:00:00 2001 From: Ralph Slooten Date: Sun, 25 May 2025 10:01:06 +1200 Subject: [PATCH 6/8] Chore: Update Go dependencies --- go.mod | 6 +++--- go.sum | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/go.mod b/go.mod index feff8f9..4377847 100644 --- a/go.mod +++ b/go.mod @@ -30,7 +30,7 @@ require ( golang.org/x/net v0.40.0 golang.org/x/text v0.25.0 golang.org/x/time v0.11.0 - modernc.org/sqlite v1.37.0 + modernc.org/sqlite v1.37.1 ) require ( @@ -46,7 +46,7 @@ require ( github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.16 // indirect github.com/ncruces/go-strftime v0.1.9 // indirect - github.com/olekukonko/tablewriter v1.0.5 // indirect + github.com/olekukonko/tablewriter v1.0.6 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/reiver/go-oi v1.0.0 // indirect github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect @@ -58,7 +58,7 @@ require ( golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6 // indirect golang.org/x/image v0.27.0 // indirect golang.org/x/sys v0.33.0 // indirect - modernc.org/libc v1.65.7 // indirect + modernc.org/libc v1.65.8 // indirect modernc.org/mathutil v1.7.1 // indirect modernc.org/memory v1.11.0 // indirect ) diff --git a/go.sum b/go.sum index 16896df..d9b418b 100644 --- a/go.sum +++ b/go.sum @@ -202,8 +202,8 @@ modernc.org/fileutil v1.3.1 h1:8vq5fe7jdtEvoCf3Zf9Nm0Q05sH6kGx0Op2CPx1wTC8= modernc.org/fileutil v1.3.1/go.mod h1:HxmghZSZVAz/LXcMNwZPA/DRrQZEVP9VX0V4LQGQFOc= modernc.org/gc/v2 v2.6.5 h1:nyqdV8q46KvTpZlsw66kWqwXRHdjIlJOhG6kxiV/9xI= modernc.org/gc/v2 v2.6.5/go.mod h1:YgIahr1ypgfe7chRuJi2gD7DBQiKSLMPgBQe9oIiito= -modernc.org/libc v1.65.7 h1:Ia9Z4yzZtWNtUIuiPuQ7Qf7kxYrxP1/jeHZzG8bFu00= -modernc.org/libc v1.65.7/go.mod h1:011EQibzzio/VX3ygj1qGFt5kMjP0lHb0qCW5/D/pQU= +modernc.org/libc v1.65.8 h1:7PXRJai0TXZ8uNA3srsmYzmTyrLoHImV5QxHeni108Q= +modernc.org/libc v1.65.8/go.mod h1:011EQibzzio/VX3ygj1qGFt5kMjP0lHb0qCW5/D/pQU= modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU= modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg= modernc.org/memory v1.11.0 h1:o4QC8aMQzmcwCK3t3Ux/ZHmwFPzE6hf2Y5LbkRs+hbI= @@ -212,8 +212,8 @@ modernc.org/opt v0.1.4 h1:2kNGMRiUjrp4LcaPuLY2PzUfqM/w9N23quVwhKt5Qm8= modernc.org/opt v0.1.4/go.mod h1:03fq9lsNfvkYSfxrfUhZCWPk1lm4cq4N+Bh//bEtgns= modernc.org/sortutil v1.2.1 h1:+xyoGf15mM3NMlPDnFqrteY07klSFxLElE2PVuWIJ7w= modernc.org/sortutil v1.2.1/go.mod h1:7ZI3a3REbai7gzCLcotuw9AC4VZVpYMjDzETGsSMqJE= -modernc.org/sqlite v1.37.0 h1:s1TMe7T3Q3ovQiK2Ouz4Jwh7dw4ZDqbebSDTlSJdfjI= -modernc.org/sqlite v1.37.0/go.mod h1:5YiWv+YviqGMuGw4V+PNplcyaJ5v+vQd7TQOgkACoJM= +modernc.org/sqlite v1.37.1 h1:EgHJK/FPoqC+q2YBXg7fUmES37pCHFc97sI7zSayBEs= +modernc.org/sqlite v1.37.1/go.mod h1:XwdRtsE1MpiBcL54+MbKcaDvcuej+IYSMfLN6gSKV8g= modernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0= modernc.org/strutil v1.2.1/go.mod h1:EHkiggD70koQxjVdSBM3JKM7k6L0FbGE5eymy9i3B9A= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= From 8f80a57c3ca7c8d64bb5fbcf1e3c06bbc5851827 Mon Sep 17 00:00:00 2001 From: Ralph Slooten Date: Sun, 25 May 2025 10:10:08 +1200 Subject: [PATCH 7/8] Chore: Update node dependencies --- package-lock.json | 372 +++++++++++++++++++++++----------------------- 1 file changed, 186 insertions(+), 186 deletions(-) diff --git a/package-lock.json b/package-lock.json index 51eea01..f6b69e6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -103,9 +103,9 @@ } }, "node_modules/@bufbuild/protobuf": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@bufbuild/protobuf/-/protobuf-2.4.0.tgz", - "integrity": "sha512-RN9M76x7N11QRihKovEglEjjVCQEA9PRBVnDgk9xw8JHLrcUrp4FpAVSPSH91cNbcTft3u2vpLN4GMbiKY9PJw==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@bufbuild/protobuf/-/protobuf-2.5.0.tgz", + "integrity": "sha512-nniMblXT+dNyubek2OLKAYJnG/in4tmfS2c5CDnIvqfF9kFlERSG3FCBvmdqerpkWuPv0qhdGKReQ2OqKPG20w==", "dev": true, "license": "(Apache-2.0 AND BSD-3-Clause)", "peer": true @@ -884,13 +884,13 @@ "license": "Apache-2.0" }, "node_modules/@swagger-api/apidom-ast": { - "version": "1.0.0-beta.38", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ast/-/apidom-ast-1.0.0-beta.38.tgz", - "integrity": "sha512-sqzXna89mDYHPb2ocshflIixuYIisuwes4DG39LXiFGrTQ1ZjKWiWPwjJfJVN3AB2ZMycEPNxTOKpJ7uvcAoeg==", + "version": "1.0.0-beta.39", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ast/-/apidom-ast-1.0.0-beta.39.tgz", + "integrity": "sha512-EWeSOtvI8XpbYMRkDyu4qAIlivhcplrskpau2cbrWfXGBjrqEtmHqWlbJ9xoXJbNshbIcZ0Z77QdxicimGjs0w==", "license": "Apache-2.0", "dependencies": { "@babel/runtime-corejs3": "^7.26.10", - "@swagger-api/apidom-error": "^1.0.0-beta.38", + "@swagger-api/apidom-error": "^1.0.0-beta.39", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0", @@ -898,14 +898,14 @@ } }, "node_modules/@swagger-api/apidom-core": { - "version": "1.0.0-beta.38", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-core/-/apidom-core-1.0.0-beta.38.tgz", - "integrity": "sha512-VG+AJ142ZoVl9rOwx/6cu+NPPHFICxNvntkRTboAw5dxKSZqX05mMsS+IYy+Z44r4VgEQyp5oLQWM0WzAKor4g==", + "version": "1.0.0-beta.39", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-core/-/apidom-core-1.0.0-beta.39.tgz", + "integrity": "sha512-tYZSVA+uDFvBJmnP104d8Qb/mye8B6ykNviohHAngHsy8ElcOPzSi5GKwwmJgf3taWzipMqWNM0ch5KytbXTqw==", "license": "Apache-2.0", "dependencies": { "@babel/runtime-corejs3": "^7.26.10", - "@swagger-api/apidom-ast": "^1.0.0-beta.38", - "@swagger-api/apidom-error": "^1.0.0-beta.38", + "@swagger-api/apidom-ast": "^1.0.0-beta.39", + "@swagger-api/apidom-error": "^1.0.0-beta.39", "@types/ramda": "~0.30.0", "minim": "~0.23.8", "ramda": "~0.30.0", @@ -915,37 +915,37 @@ } }, "node_modules/@swagger-api/apidom-error": { - "version": "1.0.0-beta.38", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-error/-/apidom-error-1.0.0-beta.38.tgz", - "integrity": "sha512-F2gj3SEQl6Tw5+Il+GyRedHxwsbAqffeMaInRAiXtCiKma1zd8wjpFF8Ixjr82ntFzPItUonGMCRm9SgDV5XOQ==", + "version": "1.0.0-beta.39", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-error/-/apidom-error-1.0.0-beta.39.tgz", + "integrity": "sha512-vQ3xQaRQGP9kNNBEDcFCmUd2PT9rCtYdkCyqYWZMxHBm5dXSBC/dQaC5VN1DbqQygE16fSQC+c5sqOrwg5d5WQ==", "license": "Apache-2.0", "dependencies": { "@babel/runtime-corejs3": "^7.20.7" } }, "node_modules/@swagger-api/apidom-json-pointer": { - "version": "1.0.0-beta.38", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-json-pointer/-/apidom-json-pointer-1.0.0-beta.38.tgz", - "integrity": "sha512-ZJF1dSrDTOvfAT0NUk56wj7G2qnwBiq4uty7KvGWrbXAXGSXs1hPbKOeB+hHe71XDgIMVwIAJqb2MCA+J6fo8w==", + "version": "1.0.0-beta.39", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-json-pointer/-/apidom-json-pointer-1.0.0-beta.39.tgz", + "integrity": "sha512-gPDNT+MCs/B1XYuNpmnz0rOHQ0ssN9YjVDqeGkX61v03BLJUF/JZKMo3J3FA2mgKb6ap+kRHzpzw5PpHLwRKAw==", "license": "Apache-2.0", "dependencies": { "@babel/runtime-corejs3": "^7.26.10", - "@swagger-api/apidom-core": "^1.0.0-beta.38", - "@swagger-api/apidom-error": "^1.0.0-beta.38", + "@swagger-api/apidom-core": "^1.0.0-beta.39", + "@swagger-api/apidom-error": "^1.0.0-beta.39", "@swaggerexpert/json-pointer": "^2.10.1" } }, "node_modules/@swagger-api/apidom-ns-api-design-systems": { - "version": "1.0.0-beta.38", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-api-design-systems/-/apidom-ns-api-design-systems-1.0.0-beta.38.tgz", - "integrity": "sha512-F5fCGWlGIkavYKGruKHK2X8jdXo8CVtGZJUZeJoYlTqM2onaxySiGH7skV7IV+HVteGMsi18GXCrlg1sjyXHag==", + "version": "1.0.0-beta.39", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-api-design-systems/-/apidom-ns-api-design-systems-1.0.0-beta.39.tgz", + "integrity": "sha512-MpdCb8KS3Tz1mGTrU0XC0Q2OcsrUWKB+buFPzLFOv0dU36ArARERX+Mz6aCJQ1CqnkFVM49uMe2NECO93ZR52w==", "license": "Apache-2.0", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.26.10", - "@swagger-api/apidom-core": "^1.0.0-beta.38", - "@swagger-api/apidom-error": "^1.0.0-beta.38", - "@swagger-api/apidom-ns-openapi-3-1": "^1.0.0-beta.38", + "@swagger-api/apidom-core": "^1.0.0-beta.39", + "@swagger-api/apidom-error": "^1.0.0-beta.39", + "@swagger-api/apidom-ns-openapi-3-1": "^1.0.0-beta.39", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0", @@ -953,15 +953,15 @@ } }, "node_modules/@swagger-api/apidom-ns-arazzo-1": { - "version": "1.0.0-beta.38", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-arazzo-1/-/apidom-ns-arazzo-1-1.0.0-beta.38.tgz", - "integrity": "sha512-h/kEjUVF0ESQ66YbOxzz9E5teo54qbVGR9R5PwP0LE8vLyJt2QFPf6qpdbyih0CGM2tTJiJkBEvG5disQUaq6Q==", + "version": "1.0.0-beta.39", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-arazzo-1/-/apidom-ns-arazzo-1-1.0.0-beta.39.tgz", + "integrity": "sha512-gIiZhlt51JxEZBAZ5PfHV1c73SMQJiwJX5DnazGehMO+ojR4HyLPFh1lc6mChMxPyPlRFOfqnmx/hmNcJ/XRiA==", "license": "Apache-2.0", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.26.10", - "@swagger-api/apidom-core": "^1.0.0-beta.38", - "@swagger-api/apidom-ns-json-schema-2020-12": "^1.0.0-beta.38", + "@swagger-api/apidom-core": "^1.0.0-beta.39", + "@swagger-api/apidom-ns-json-schema-2020-12": "^1.0.0-beta.39", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0", @@ -969,15 +969,15 @@ } }, "node_modules/@swagger-api/apidom-ns-asyncapi-2": { - "version": "1.0.0-beta.38", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-asyncapi-2/-/apidom-ns-asyncapi-2-1.0.0-beta.38.tgz", - "integrity": "sha512-cCuzq0qqLvyofVU8QQJNxKTpV54NFgy7XB5qcuZ0kIiF+7BZTxx08crURhnwDfQM4Qyaz6xdeSkecV7JZbrqBA==", + "version": "1.0.0-beta.39", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-asyncapi-2/-/apidom-ns-asyncapi-2-1.0.0-beta.39.tgz", + "integrity": "sha512-Jtdo+6MgVhf8HynjRo5pIj+aYYICAQGwRkd0n0YtOhvvKoI0gWEMpcRkDbJrNcNYOHaSxMlQfotGlTCaMl7QJQ==", "license": "Apache-2.0", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.26.10", - "@swagger-api/apidom-core": "^1.0.0-beta.38", - "@swagger-api/apidom-ns-json-schema-draft-7": "^1.0.0-beta.38", + "@swagger-api/apidom-core": "^1.0.0-beta.39", + "@swagger-api/apidom-ns-json-schema-draft-7": "^1.0.0-beta.39", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0", @@ -985,15 +985,15 @@ } }, "node_modules/@swagger-api/apidom-ns-json-schema-2019-09": { - "version": "1.0.0-beta.38", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-json-schema-2019-09/-/apidom-ns-json-schema-2019-09-1.0.0-beta.38.tgz", - "integrity": "sha512-Bb93qs8dJ5ck6/sLdzv5M0WADWRm7W54Oov5hz18iCCUCRvaIlnCRzyGIgdL9UdKYqmeEpUOSk9U1t6J1gRrdA==", + "version": "1.0.0-beta.39", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-json-schema-2019-09/-/apidom-ns-json-schema-2019-09-1.0.0-beta.39.tgz", + "integrity": "sha512-I/XP4zbrWAmnq2KWPtbb9DKLWgzYFovIiSQOyh47bJqbYgz64/IhoZb/uGihZojVVHSqeeJH9o6JOahqHQzKOw==", "license": "Apache-2.0", "dependencies": { "@babel/runtime-corejs3": "^7.26.10", - "@swagger-api/apidom-core": "^1.0.0-beta.38", - "@swagger-api/apidom-error": "^1.0.0-beta.38", - "@swagger-api/apidom-ns-json-schema-draft-7": "^1.0.0-beta.38", + "@swagger-api/apidom-core": "^1.0.0-beta.39", + "@swagger-api/apidom-error": "^1.0.0-beta.39", + "@swagger-api/apidom-ns-json-schema-draft-7": "^1.0.0-beta.39", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0", @@ -1001,15 +1001,15 @@ } }, "node_modules/@swagger-api/apidom-ns-json-schema-2020-12": { - "version": "1.0.0-beta.38", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-json-schema-2020-12/-/apidom-ns-json-schema-2020-12-1.0.0-beta.38.tgz", - "integrity": "sha512-rlgl0wGCVll11+yzz3pwlZwN5g/CDYpu277MtY+tDRimgy+FfC6aGL5MQewYxVRWn79yUSrTiG7LhOO6eXCYtQ==", + "version": "1.0.0-beta.39", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-json-schema-2020-12/-/apidom-ns-json-schema-2020-12-1.0.0-beta.39.tgz", + "integrity": "sha512-9bpMp96fb76lOqeggtyCU457K/XBLyw3O9fxdVS3Tevhf8P3SJ6QpabmweRb6kFt4vI3+DiBschJGn0iqmlcXw==", "license": "Apache-2.0", "dependencies": { "@babel/runtime-corejs3": "^7.26.10", - "@swagger-api/apidom-core": "^1.0.0-beta.38", - "@swagger-api/apidom-error": "^1.0.0-beta.38", - "@swagger-api/apidom-ns-json-schema-2019-09": "^1.0.0-beta.38", + "@swagger-api/apidom-core": "^1.0.0-beta.39", + "@swagger-api/apidom-error": "^1.0.0-beta.39", + "@swagger-api/apidom-ns-json-schema-2019-09": "^1.0.0-beta.39", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0", @@ -1017,14 +1017,14 @@ } }, "node_modules/@swagger-api/apidom-ns-json-schema-draft-4": { - "version": "1.0.0-beta.38", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-json-schema-draft-4/-/apidom-ns-json-schema-draft-4-1.0.0-beta.38.tgz", - "integrity": "sha512-KswOYv3tZoFRIsGI6hHHuEyLgz8IaHygXHwjeF8dTjCuDGgr57gp+/XzsVF48UUl75PmhGJxoOPwTBg1/5FAtQ==", + "version": "1.0.0-beta.39", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-json-schema-draft-4/-/apidom-ns-json-schema-draft-4-1.0.0-beta.39.tgz", + "integrity": "sha512-F25tm/nwPl1rRnUHzaVw4SAeASodO60oAtWX+GF3K61WEx/Aao4Maldv3CQtAoUk8L0Ml0l1KZL00sgfikwqlw==", "license": "Apache-2.0", "dependencies": { "@babel/runtime-corejs3": "^7.26.10", - "@swagger-api/apidom-ast": "^1.0.0-beta.38", - "@swagger-api/apidom-core": "^1.0.0-beta.38", + "@swagger-api/apidom-ast": "^1.0.0-beta.39", + "@swagger-api/apidom-core": "^1.0.0-beta.39", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0", @@ -1032,15 +1032,15 @@ } }, "node_modules/@swagger-api/apidom-ns-json-schema-draft-6": { - "version": "1.0.0-beta.38", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-json-schema-draft-6/-/apidom-ns-json-schema-draft-6-1.0.0-beta.38.tgz", - "integrity": "sha512-+6+fs6YEIaeyCabXG0YxIHYofVN7e4mnwc8CGSOK/O88mrnJPpRACLHnq9z/s98vTVmfBzjL/h6yjcOugHpzzw==", + "version": "1.0.0-beta.39", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-json-schema-draft-6/-/apidom-ns-json-schema-draft-6-1.0.0-beta.39.tgz", + "integrity": "sha512-E2fQQHWIRtbM5C1m1EL95MQNDPL98mlgYomPQDDUEFbYrH3u9BQGAgpIu4KuYasKquyuhx9YXqS/jLRhMCRfAQ==", "license": "Apache-2.0", "dependencies": { "@babel/runtime-corejs3": "^7.26.10", - "@swagger-api/apidom-core": "^1.0.0-beta.38", - "@swagger-api/apidom-error": "^1.0.0-beta.38", - "@swagger-api/apidom-ns-json-schema-draft-4": "^1.0.0-beta.38", + "@swagger-api/apidom-core": "^1.0.0-beta.39", + "@swagger-api/apidom-error": "^1.0.0-beta.39", + "@swagger-api/apidom-ns-json-schema-draft-4": "^1.0.0-beta.39", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0", @@ -1048,15 +1048,15 @@ } }, "node_modules/@swagger-api/apidom-ns-json-schema-draft-7": { - "version": "1.0.0-beta.38", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-json-schema-draft-7/-/apidom-ns-json-schema-draft-7-1.0.0-beta.38.tgz", - "integrity": "sha512-jDc4RUbKn3WGsTbTM1rMlEoSuud7T2X1xdl7x9jAvn4wH2Qvx8iUOIiSYDLKcK13qcg46UP1RmOFb/KZrfu4Mw==", + "version": "1.0.0-beta.39", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-json-schema-draft-7/-/apidom-ns-json-schema-draft-7-1.0.0-beta.39.tgz", + "integrity": "sha512-mhzb7n3pm0yfYuM9bZowYMp6L61Cz+HrbjBowUIt5iOMMAATQd6x209pj81hnSmgHmEJCgv+8IO9dvweme698A==", "license": "Apache-2.0", "dependencies": { "@babel/runtime-corejs3": "^7.26.10", - "@swagger-api/apidom-core": "^1.0.0-beta.38", - "@swagger-api/apidom-error": "^1.0.0-beta.38", - "@swagger-api/apidom-ns-json-schema-draft-6": "^1.0.0-beta.38", + "@swagger-api/apidom-core": "^1.0.0-beta.39", + "@swagger-api/apidom-error": "^1.0.0-beta.39", + "@swagger-api/apidom-ns-json-schema-draft-6": "^1.0.0-beta.39", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0", @@ -1064,16 +1064,16 @@ } }, "node_modules/@swagger-api/apidom-ns-openapi-2": { - "version": "1.0.0-beta.38", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-openapi-2/-/apidom-ns-openapi-2-1.0.0-beta.38.tgz", - "integrity": "sha512-h2HYtUnrFa0az8ZbilJVemQtxZI2YU2NwrWA1cv1IjNYd3D2tq/C94SPUnVfs42AJCyW1I6ACfcaNtMvbyPq8A==", + "version": "1.0.0-beta.39", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-openapi-2/-/apidom-ns-openapi-2-1.0.0-beta.39.tgz", + "integrity": "sha512-/Cjggp0eAM1GfKeLu53sLjCV9lFVUMucFruXJnD1TWdCKv5S5JAKsGBASbchw8hvwrfx6sPHslzZFV+tZKbn2Q==", "license": "Apache-2.0", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.26.10", - "@swagger-api/apidom-core": "^1.0.0-beta.38", - "@swagger-api/apidom-error": "^1.0.0-beta.38", - "@swagger-api/apidom-ns-json-schema-draft-4": "^1.0.0-beta.38", + "@swagger-api/apidom-core": "^1.0.0-beta.39", + "@swagger-api/apidom-error": "^1.0.0-beta.39", + "@swagger-api/apidom-ns-json-schema-draft-4": "^1.0.0-beta.39", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0", @@ -1081,15 +1081,15 @@ } }, "node_modules/@swagger-api/apidom-ns-openapi-3-0": { - "version": "1.0.0-beta.38", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-openapi-3-0/-/apidom-ns-openapi-3-0-1.0.0-beta.38.tgz", - "integrity": "sha512-OUYkbFt1vgRB/l5ZqGG4AIRXHubcZul50eMh5icuwsDmtnc/ZxupDzebACpxKbyHjkvtLK8Qq8E7T4tFHZYDbA==", + "version": "1.0.0-beta.39", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-openapi-3-0/-/apidom-ns-openapi-3-0-1.0.0-beta.39.tgz", + "integrity": "sha512-lvNlUtCmyHH8+52qOhgXXdzy4HEYA+t7xnFNvDb6dtP+epXCexux3uRs8+xEYBHo/WqUGzjdwd0qKFRgyP7Lrw==", "license": "Apache-2.0", "dependencies": { "@babel/runtime-corejs3": "^7.26.10", - "@swagger-api/apidom-core": "^1.0.0-beta.38", - "@swagger-api/apidom-error": "^1.0.0-beta.38", - "@swagger-api/apidom-ns-json-schema-draft-4": "^1.0.0-beta.38", + "@swagger-api/apidom-core": "^1.0.0-beta.39", + "@swagger-api/apidom-error": "^1.0.0-beta.39", + "@swagger-api/apidom-ns-json-schema-draft-4": "^1.0.0-beta.39", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0", @@ -1097,17 +1097,17 @@ } }, "node_modules/@swagger-api/apidom-ns-openapi-3-1": { - "version": "1.0.0-beta.38", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-openapi-3-1/-/apidom-ns-openapi-3-1-1.0.0-beta.38.tgz", - "integrity": "sha512-nVwFkxGWJXBOvSiOfyStdaTdRQvMyL3LyICBbUCrnt+lGJ6o9qStbHDoiJgywWqQdM/j+8roHtxYejlqx/uueQ==", + "version": "1.0.0-beta.39", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-openapi-3-1/-/apidom-ns-openapi-3-1-1.0.0-beta.39.tgz", + "integrity": "sha512-sXMJxTGL2F36Uyv9iqvPwvzsD5NJM/dJ52tUuiJP8h4RqXwjrOC86hqf1/Xk/rxgpZShhW4PNEqifvPq/Mto3w==", "license": "Apache-2.0", "dependencies": { "@babel/runtime-corejs3": "^7.26.10", - "@swagger-api/apidom-ast": "^1.0.0-beta.38", - "@swagger-api/apidom-core": "^1.0.0-beta.38", - "@swagger-api/apidom-json-pointer": "^1.0.0-beta.38", - "@swagger-api/apidom-ns-json-schema-2020-12": "^1.0.0-beta.38", - "@swagger-api/apidom-ns-openapi-3-0": "^1.0.0-beta.38", + "@swagger-api/apidom-ast": "^1.0.0-beta.39", + "@swagger-api/apidom-core": "^1.0.0-beta.39", + "@swagger-api/apidom-json-pointer": "^1.0.0-beta.39", + "@swagger-api/apidom-ns-json-schema-2020-12": "^1.0.0-beta.39", + "@swagger-api/apidom-ns-openapi-3-0": "^1.0.0-beta.39", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0", @@ -1115,112 +1115,112 @@ } }, "node_modules/@swagger-api/apidom-parser-adapter-api-design-systems-json": { - "version": "1.0.0-beta.38", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-api-design-systems-json/-/apidom-parser-adapter-api-design-systems-json-1.0.0-beta.38.tgz", - "integrity": "sha512-B4sRtmdarivTNGYOPvM74ZtSRhRksr1tQrWY3XRKDQXp05rQr6CrbZaVQIu37aIWSP9TzxQDwM+QJn8OlYG4ow==", + "version": "1.0.0-beta.39", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-api-design-systems-json/-/apidom-parser-adapter-api-design-systems-json-1.0.0-beta.39.tgz", + "integrity": "sha512-jrPxZMvE6I2X8FUx4ri7VTMy2wTNOLLz+qXSx9sSXWULImqwdscvEwSVug8zdBQYMy8HXwt0wHpxlGLXBEmL8Q==", "license": "Apache-2.0", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.26.10", - "@swagger-api/apidom-core": "^1.0.0-beta.38", - "@swagger-api/apidom-ns-api-design-systems": "^1.0.0-beta.38", - "@swagger-api/apidom-parser-adapter-json": "^1.0.0-beta.38", + "@swagger-api/apidom-core": "^1.0.0-beta.39", + "@swagger-api/apidom-ns-api-design-systems": "^1.0.0-beta.39", + "@swagger-api/apidom-parser-adapter-json": "^1.0.0-beta.39", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0" } }, "node_modules/@swagger-api/apidom-parser-adapter-api-design-systems-yaml": { - "version": "1.0.0-beta.38", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-api-design-systems-yaml/-/apidom-parser-adapter-api-design-systems-yaml-1.0.0-beta.38.tgz", - "integrity": "sha512-EIe/AQ5D57tFQpC0lND1JjPRk+CSuSCvE/PBtZ/rEN9PUBrmD0nrOIPg55Mzu6AwnKTby+mW5XrYRVyqLEWkfA==", + "version": "1.0.0-beta.39", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-api-design-systems-yaml/-/apidom-parser-adapter-api-design-systems-yaml-1.0.0-beta.39.tgz", + "integrity": "sha512-JKyRYc4cBajPkIpO0YTJnxI+p8ubXfA+/1L8Fpq5kDPAI5Wh744iZ/scVHTgpgY8g+GbPqIoWB0ilQbEdlF5Sg==", "license": "Apache-2.0", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.26.10", - "@swagger-api/apidom-core": "^1.0.0-beta.38", - "@swagger-api/apidom-ns-api-design-systems": "^1.0.0-beta.38", - "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.0.0-beta.38", + "@swagger-api/apidom-core": "^1.0.0-beta.39", + "@swagger-api/apidom-ns-api-design-systems": "^1.0.0-beta.39", + "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.0.0-beta.39", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0" } }, "node_modules/@swagger-api/apidom-parser-adapter-arazzo-json-1": { - "version": "1.0.0-beta.38", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-arazzo-json-1/-/apidom-parser-adapter-arazzo-json-1-1.0.0-beta.38.tgz", - "integrity": "sha512-9IIYRInVOlCbVf40aUKO3zRyxdYNoFmu2JyUhrHeRb9oJCWdRv+xBrfG61aGRelPzAA/Ail9GBFYnCFgjzyRLg==", + "version": "1.0.0-beta.39", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-arazzo-json-1/-/apidom-parser-adapter-arazzo-json-1-1.0.0-beta.39.tgz", + "integrity": "sha512-qlQuj4jsEPpLRH4wpkMjbR3Id3qb4n/oerv4cKCi1TYJJphC7DG7QRS90tYjaAF7n2YA8HxUcEIu2+Y5QZKyMw==", "license": "Apache-2.0", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.26.10", - "@swagger-api/apidom-core": "^1.0.0-beta.38", - "@swagger-api/apidom-ns-arazzo-1": "^1.0.0-beta.38", - "@swagger-api/apidom-parser-adapter-json": "^1.0.0-beta.38", + "@swagger-api/apidom-core": "^1.0.0-beta.39", + "@swagger-api/apidom-ns-arazzo-1": "^1.0.0-beta.39", + "@swagger-api/apidom-parser-adapter-json": "^1.0.0-beta.39", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0" } }, "node_modules/@swagger-api/apidom-parser-adapter-arazzo-yaml-1": { - "version": "1.0.0-beta.38", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-arazzo-yaml-1/-/apidom-parser-adapter-arazzo-yaml-1-1.0.0-beta.38.tgz", - "integrity": "sha512-HVBTEkLluBM2eMl2QnxrUm5caIfWMzPfXkxfHPPlL/PA4Qzxts3IDs/6GtKxEoGfeYy1kFcsdkoku9oeF+27Xg==", + "version": "1.0.0-beta.39", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-arazzo-yaml-1/-/apidom-parser-adapter-arazzo-yaml-1-1.0.0-beta.39.tgz", + "integrity": "sha512-MUChnj6dJZRGDtIIVItIojzDNBEdan8KkuV+3U1l8bBA4eJQIq7yzHYk7fq6bl4Yd17HG0HT+1xckbUnj5Ay4A==", "license": "Apache-2.0", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.26.10", - "@swagger-api/apidom-core": "^1.0.0-beta.38", - "@swagger-api/apidom-ns-arazzo-1": "^1.0.0-beta.38", - "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.0.0-beta.38", + "@swagger-api/apidom-core": "^1.0.0-beta.39", + "@swagger-api/apidom-ns-arazzo-1": "^1.0.0-beta.39", + "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.0.0-beta.39", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0" } }, "node_modules/@swagger-api/apidom-parser-adapter-asyncapi-json-2": { - "version": "1.0.0-beta.38", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-asyncapi-json-2/-/apidom-parser-adapter-asyncapi-json-2-1.0.0-beta.38.tgz", - "integrity": "sha512-VXX2xLwMSMSRsDNtdx85evfh2JbuDw1+LjqqVHRUFt0zwA/CowqzPJ/zgURKnSSJ3JKmr+20mpYE9hSC5iTa3Q==", + "version": "1.0.0-beta.39", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-asyncapi-json-2/-/apidom-parser-adapter-asyncapi-json-2-1.0.0-beta.39.tgz", + "integrity": "sha512-G+xIeYGetnCM3ylsWSwSyqCntpT6gt2Bv3f6hu/IonZxxCy2HqUl9JS41XF/cJHCoBchJU3G+bjOZXN22W3Xzw==", "license": "Apache-2.0", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.26.10", - "@swagger-api/apidom-core": "^1.0.0-beta.38", - "@swagger-api/apidom-ns-asyncapi-2": "^1.0.0-beta.38", - "@swagger-api/apidom-parser-adapter-json": "^1.0.0-beta.38", + "@swagger-api/apidom-core": "^1.0.0-beta.39", + "@swagger-api/apidom-ns-asyncapi-2": "^1.0.0-beta.39", + "@swagger-api/apidom-parser-adapter-json": "^1.0.0-beta.39", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0" } }, "node_modules/@swagger-api/apidom-parser-adapter-asyncapi-yaml-2": { - "version": "1.0.0-beta.38", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-asyncapi-yaml-2/-/apidom-parser-adapter-asyncapi-yaml-2-1.0.0-beta.38.tgz", - "integrity": "sha512-+K15mDRtyGH4nMWHKZJtjG9IWR0Zm2eYedvm3eS9dhLYlPX9MDC8rYyf6+GPx3KfzgOen7SpEJv9QM66HZWepw==", + "version": "1.0.0-beta.39", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-asyncapi-yaml-2/-/apidom-parser-adapter-asyncapi-yaml-2-1.0.0-beta.39.tgz", + "integrity": "sha512-VPwlMRwtMQtPmEv6JXNefBBjAK/IxPsq9XWP/7kJZQ6CDp6ljHrMJDPAHZNundSL09xu7Wbz6KVGcpruUPiWmA==", "license": "Apache-2.0", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.26.10", - "@swagger-api/apidom-core": "^1.0.0-beta.38", - "@swagger-api/apidom-ns-asyncapi-2": "^1.0.0-beta.38", - "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.0.0-beta.38", + "@swagger-api/apidom-core": "^1.0.0-beta.39", + "@swagger-api/apidom-ns-asyncapi-2": "^1.0.0-beta.39", + "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.0.0-beta.39", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0" } }, "node_modules/@swagger-api/apidom-parser-adapter-json": { - "version": "1.0.0-beta.38", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-json/-/apidom-parser-adapter-json-1.0.0-beta.38.tgz", - "integrity": "sha512-S3EmtMyX8YBAwH7uQovsPiBm1jDjCp3qVbri3QGbhL6e7O4rNxd27TA2KGqEDs1e3QEH72SkKjsxHQG/XeFGLQ==", + "version": "1.0.0-beta.39", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-json/-/apidom-parser-adapter-json-1.0.0-beta.39.tgz", + "integrity": "sha512-Rg2SgI06CDTdm3qs3A5pNvhonVxa2jOcwypxyhKngelIHaTuOPgaFA6qyCIvX0oIhwTcKcvV+5tPlGIR3vshpA==", "license": "Apache-2.0", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.26.10", - "@swagger-api/apidom-ast": "^1.0.0-beta.38", - "@swagger-api/apidom-core": "^1.0.0-beta.38", - "@swagger-api/apidom-error": "^1.0.0-beta.38", + "@swagger-api/apidom-ast": "^1.0.0-beta.39", + "@swagger-api/apidom-core": "^1.0.0-beta.39", + "@swagger-api/apidom-error": "^1.0.0-beta.39", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0", @@ -1252,112 +1252,112 @@ } }, "node_modules/@swagger-api/apidom-parser-adapter-openapi-json-2": { - "version": "1.0.0-beta.38", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-json-2/-/apidom-parser-adapter-openapi-json-2-1.0.0-beta.38.tgz", - "integrity": "sha512-QqOw0/oNeHEU57bpViIaMTWibeBwjYTAVOy+advY+UvqceUriUoHH33D8yeEvwLZUKECbCxgmiPECNbbbRuADg==", + "version": "1.0.0-beta.39", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-json-2/-/apidom-parser-adapter-openapi-json-2-1.0.0-beta.39.tgz", + "integrity": "sha512-DYB3jGcSnTu1ykbAKkMo550QW0BjnHlGxi1NaBbVYzdMfPYbBSQnDB3zYAwgakpoQx89OztFSlrNQ+3P8wuuSw==", "license": "Apache-2.0", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.26.10", - "@swagger-api/apidom-core": "^1.0.0-beta.38", - "@swagger-api/apidom-ns-openapi-2": "^1.0.0-beta.38", - "@swagger-api/apidom-parser-adapter-json": "^1.0.0-beta.38", + "@swagger-api/apidom-core": "^1.0.0-beta.39", + "@swagger-api/apidom-ns-openapi-2": "^1.0.0-beta.39", + "@swagger-api/apidom-parser-adapter-json": "^1.0.0-beta.39", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0" } }, "node_modules/@swagger-api/apidom-parser-adapter-openapi-json-3-0": { - "version": "1.0.0-beta.38", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-json-3-0/-/apidom-parser-adapter-openapi-json-3-0-1.0.0-beta.38.tgz", - "integrity": "sha512-HQEW3cTZ9Wl5VQcqCvWiI5quolNdK997xhhpI72Y4+ZGkxdrntCVal2PB0Hnd2CYn6zIYn0Ijif5fZK49eL7ww==", + "version": "1.0.0-beta.39", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-json-3-0/-/apidom-parser-adapter-openapi-json-3-0-1.0.0-beta.39.tgz", + "integrity": "sha512-4ueWFNc3N4YZb7fTwsgrhWzdCo3TnZ7HgK5fPW3m0+Hm2wko2WYIUCIxU33Ef4DB+0Hd8y4Abjv8Mz0CCxRaeg==", "license": "Apache-2.0", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.26.10", - "@swagger-api/apidom-core": "^1.0.0-beta.38", - "@swagger-api/apidom-ns-openapi-3-0": "^1.0.0-beta.38", - "@swagger-api/apidom-parser-adapter-json": "^1.0.0-beta.38", + "@swagger-api/apidom-core": "^1.0.0-beta.39", + "@swagger-api/apidom-ns-openapi-3-0": "^1.0.0-beta.39", + "@swagger-api/apidom-parser-adapter-json": "^1.0.0-beta.39", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0" } }, "node_modules/@swagger-api/apidom-parser-adapter-openapi-json-3-1": { - "version": "1.0.0-beta.38", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-json-3-1/-/apidom-parser-adapter-openapi-json-3-1-1.0.0-beta.38.tgz", - "integrity": "sha512-HgIXoMd/T7XbVwO4R1Ty64/5fD8nVSipAZ3pKZHoRTZ86jXC4Bh5NU8wXNWVr0cco5w3gtzNAVwNOFmK6ljEpA==", + "version": "1.0.0-beta.39", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-json-3-1/-/apidom-parser-adapter-openapi-json-3-1-1.0.0-beta.39.tgz", + "integrity": "sha512-8K/9J1CnQAwVqN+pvP9PH607WKA7WimNmZiyczgfnOgq93PUozNavrK97lwUUOQcZUmQra8pG2XrOrZZwd/M5w==", "license": "Apache-2.0", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.26.10", - "@swagger-api/apidom-core": "^1.0.0-beta.38", - "@swagger-api/apidom-ns-openapi-3-1": "^1.0.0-beta.38", - "@swagger-api/apidom-parser-adapter-json": "^1.0.0-beta.38", + "@swagger-api/apidom-core": "^1.0.0-beta.39", + "@swagger-api/apidom-ns-openapi-3-1": "^1.0.0-beta.39", + "@swagger-api/apidom-parser-adapter-json": "^1.0.0-beta.39", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0" } }, "node_modules/@swagger-api/apidom-parser-adapter-openapi-yaml-2": { - "version": "1.0.0-beta.38", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-yaml-2/-/apidom-parser-adapter-openapi-yaml-2-1.0.0-beta.38.tgz", - "integrity": "sha512-OlVn9MyXR3q5W8siwnI4iVDmf7KXm3klgR1YDZIC8Dpwt2jAh9Hd0sJo3axLijf2PnFA1rvtQNlgsLAmK2J8CQ==", + "version": "1.0.0-beta.39", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-yaml-2/-/apidom-parser-adapter-openapi-yaml-2-1.0.0-beta.39.tgz", + "integrity": "sha512-EfzVZrYTnwNGXUXIOrZkigQxdze+VdXxJWp55t3CWTy0CA7w9eM+PDpzHu7iqJgXqTOixMGy02Gzyv6N6sDj8A==", "license": "Apache-2.0", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.26.10", - "@swagger-api/apidom-core": "^1.0.0-beta.38", - "@swagger-api/apidom-ns-openapi-2": "^1.0.0-beta.38", - "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.0.0-beta.38", + "@swagger-api/apidom-core": "^1.0.0-beta.39", + "@swagger-api/apidom-ns-openapi-2": "^1.0.0-beta.39", + "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.0.0-beta.39", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0" } }, "node_modules/@swagger-api/apidom-parser-adapter-openapi-yaml-3-0": { - "version": "1.0.0-beta.38", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-yaml-3-0/-/apidom-parser-adapter-openapi-yaml-3-0-1.0.0-beta.38.tgz", - "integrity": "sha512-/fF47bW0j679vdhkwukvSv8SweHjkbWMGV3o5wA4oP8COyWpNegMUhs6KXjcCuDSseHi+1nzeKKODeI9+um47g==", + "version": "1.0.0-beta.39", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-yaml-3-0/-/apidom-parser-adapter-openapi-yaml-3-0-1.0.0-beta.39.tgz", + "integrity": "sha512-ElHueuGdwB35VeZaJnmhZE3ILGE8F74ThJqgTbY+F2JcNo4O8cBkoCq9syw1pJ+l2JoAUErmxaTOR+zNA/wK+g==", "license": "Apache-2.0", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.26.10", - "@swagger-api/apidom-core": "^1.0.0-beta.38", - "@swagger-api/apidom-ns-openapi-3-0": "^1.0.0-beta.38", - "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.0.0-beta.38", + "@swagger-api/apidom-core": "^1.0.0-beta.39", + "@swagger-api/apidom-ns-openapi-3-0": "^1.0.0-beta.39", + "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.0.0-beta.39", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0" } }, "node_modules/@swagger-api/apidom-parser-adapter-openapi-yaml-3-1": { - "version": "1.0.0-beta.38", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-yaml-3-1/-/apidom-parser-adapter-openapi-yaml-3-1-1.0.0-beta.38.tgz", - "integrity": "sha512-6vCl8ESRaYo/KB1FihgmEU9bxlpZcfeEx19PZH2a0MMt3t+RnE0yTVVYjrwuPd9cqMpnqOjDcFwQAwpmB3TAeA==", + "version": "1.0.0-beta.39", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-yaml-3-1/-/apidom-parser-adapter-openapi-yaml-3-1-1.0.0-beta.39.tgz", + "integrity": "sha512-lNSXp+vGcsA/d/3ukXJeovAnO5oxcTJ5OvFBL84grJvK1C6E2v0AOfsMlUEipIRNhIHq3zYKpUnhFJyE13VqXA==", "license": "Apache-2.0", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.26.10", - "@swagger-api/apidom-core": "^1.0.0-beta.38", - "@swagger-api/apidom-ns-openapi-3-1": "^1.0.0-beta.38", - "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.0.0-beta.38", + "@swagger-api/apidom-core": "^1.0.0-beta.39", + "@swagger-api/apidom-ns-openapi-3-1": "^1.0.0-beta.39", + "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.0.0-beta.39", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0" } }, "node_modules/@swagger-api/apidom-parser-adapter-yaml-1-2": { - "version": "1.0.0-beta.38", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-yaml-1-2/-/apidom-parser-adapter-yaml-1-2-1.0.0-beta.38.tgz", - "integrity": "sha512-ZycCtLALSob7ZiviVZ2pp/HBaDFV0WxcjTUzGPpKqqlhZnMEhNbX0veTUCQkhXjF7cCcUDhU+FTVmi+FQOfg3Q==", + "version": "1.0.0-beta.39", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-yaml-1-2/-/apidom-parser-adapter-yaml-1-2-1.0.0-beta.39.tgz", + "integrity": "sha512-30Lhgkg2ZrHY7tQ5h9umjWWhy0Fqcoi28SXJ9vtdj1cLSnFvclaLe5ZGbXP3wdW4sXZO0As3+msL9tMwrUJ/7w==", "license": "Apache-2.0", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.26.10", - "@swagger-api/apidom-ast": "^1.0.0-beta.38", - "@swagger-api/apidom-core": "^1.0.0-beta.38", - "@swagger-api/apidom-error": "^1.0.0-beta.38", + "@swagger-api/apidom-ast": "^1.0.0-beta.39", + "@swagger-api/apidom-core": "^1.0.0-beta.39", + "@swagger-api/apidom-error": "^1.0.0-beta.39", "@tree-sitter-grammars/tree-sitter-yaml": "=0.7.0", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", @@ -1409,16 +1409,16 @@ } }, "node_modules/@swagger-api/apidom-reference": { - "version": "1.0.0-beta.38", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-reference/-/apidom-reference-1.0.0-beta.38.tgz", - "integrity": "sha512-8T3mtcP4C23NRMlElErI8ZOnEkZptaO3o1/LN1ipUo92QQU5od0rdtLr2GLhDs5Zl+SjW3YNKwQHU5SdJQum/A==", + "version": "1.0.0-beta.39", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-reference/-/apidom-reference-1.0.0-beta.39.tgz", + "integrity": "sha512-PrV2/3Z6XGJPj4fv1JazY1dKjlnAg/BN22UQdUOzA5/A0TkfbImt8uVQuVzQSL2P8RA6G9TDsdpOalj80N47rw==", "license": "Apache-2.0", "dependencies": { "@babel/runtime-corejs3": "^7.26.10", - "@swagger-api/apidom-core": "^1.0.0-beta.38", - "@swagger-api/apidom-error": "^1.0.0-beta.38", + "@swagger-api/apidom-core": "^1.0.0-beta.39", + "@swagger-api/apidom-error": "^1.0.0-beta.39", "@types/ramda": "~0.30.0", - "axios": "^1.8.2", + "axios": "^1.9.0", "minimatch": "^7.4.3", "process": "^0.11.10", "ramda": "~0.30.0", @@ -1887,9 +1887,9 @@ } }, "node_modules/dompurify": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.5.tgz", - "integrity": "sha512-mLPd29uoRe9HpvwP2TxClGQBzGXeEC/we/q+bFlmPPmj2p2Ugl3r6ATu/UU1v77DXNcehiBg9zsr1dREyA/dJQ==", + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.6.tgz", + "integrity": "sha512-/2GogDQlohXPZe6D6NOgQvXLPSYBqIWMnZ8zzOhn09REE4eyAzb+Hed3jhoM9OkuaJ8P6ZGTTVWQKAi8ieIzfQ==", "license": "(MPL-2.0 OR Apache-2.0)", "optionalDependencies": { "@types/trusted-types": "^2.0.7" @@ -3269,18 +3269,18 @@ } }, "node_modules/swagger-client": { - "version": "3.35.1", - "resolved": "https://registry.npmjs.org/swagger-client/-/swagger-client-3.35.1.tgz", - "integrity": "sha512-FEMFQGPu/Vt3UA2rrIvR00PT6SfnFCXLb+E4tGI0BSwVkwwu3bZ/c78QBXo/H/PtEvPJhQwBfF7af80jgjc7Bg==", + "version": "3.35.3", + "resolved": "https://registry.npmjs.org/swagger-client/-/swagger-client-3.35.3.tgz", + "integrity": "sha512-4bO+dhBbasP485Ak67o46cWNVUnV0/92ypb2997bhvxTO2M+IuQZM1ilkN/7nSaiGuxDKJhkuL54I35PVI3AAw==", "license": "Apache-2.0", "dependencies": { "@babel/runtime-corejs3": "^7.22.15", "@scarf/scarf": "=1.4.0", - "@swagger-api/apidom-core": ">=1.0.0-beta.37 <1.0.0-rc.0", - "@swagger-api/apidom-error": ">=1.0.0-beta.37 <1.0.0-rc.0", - "@swagger-api/apidom-json-pointer": ">=1.0.0-beta.37 <1.0.0-rc.0", - "@swagger-api/apidom-ns-openapi-3-1": ">=1.0.0-beta.37 <1.0.0-rc.0", - "@swagger-api/apidom-reference": ">=1.0.0-beta.37 <1.0.0-rc.0", + "@swagger-api/apidom-core": ">=1.0.0-beta.39 <1.0.0-rc.0", + "@swagger-api/apidom-error": ">=1.0.0-beta.39 <1.0.0-rc.0", + "@swagger-api/apidom-json-pointer": ">=1.0.0-beta.39 <1.0.0-rc.0", + "@swagger-api/apidom-ns-openapi-3-1": ">=1.0.0-beta.39 <1.0.0-rc.0", + "@swagger-api/apidom-reference": ">=1.0.0-beta.39 <1.0.0-rc.0", "@swaggerexpert/cookie": "^2.0.2", "deepmerge": "~4.3.0", "fast-json-patch": "^3.0.0-1", From 5240b1b33e288e64d385e37470653863aa3aeed6 Mon Sep 17 00:00:00 2001 From: Ralph Slooten Date: Sun, 25 May 2025 10:12:05 +1200 Subject: [PATCH 8/8] Release v1.25.1 --- CHANGELOG.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b6d9469..ee82606 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,20 @@ Notable changes to Mailpit will be documented in this file. +## [v1.25.1] + +### Chore +- Switch from unnecessary float64 to uint64 API values for App Information, message & attachment sizes +- Extend latest version cache expiration from 5 to 15 minutes +- Lighten outline-secondary buttons in dark mode +- Add note to swagger docs about API date formats +- Update Go dependencies +- Update node dependencies + +### Fix +- Update bootstrap5-tags to fix text pasting in message release modal ([#498](https://github.com/axllent/mailpit/issues/498)) + + ## [v1.25.0] ### Feature