diff --git a/pkg/jmap/api_contact.go b/pkg/jmap/api_contact.go index 1185e24ef1..cfbb165b9f 100644 --- a/pkg/jmap/api_contact.go +++ b/pkg/jmap/api_contact.go @@ -66,13 +66,16 @@ type ContactCardSearchResults SearchResultsTemplate[ContactCard] var _ SearchResults[ContactCard] = &ContactCardSearchResults{} -func (r *ContactCardSearchResults) GetResults() []ContactCard { return r.Results } -func (r *ContactCardSearchResults) GetCanCalculateChanges() bool { return r.CanCalculateChanges } -func (r *ContactCardSearchResults) GetPosition() uint { return r.Position } -func (r *ContactCardSearchResults) GetLimit() *uint { return r.Limit } -func (r *ContactCardSearchResults) GetTotal() *uint { return r.Total } -func (r *ContactCardSearchResults) RemoveResults() { r.Results = nil } -func (r *ContactCardSearchResults) SetLimit(limit *uint) { r.Limit = limit } +func (r *ContactCardSearchResults) GetResults() []ContactCard { return r.Results } +func (r *ContactCardSearchResults) GetCanCalculateChanges() ChangeCalculation { + return r.CanCalculateChanges +} +func (r *ContactCardSearchResults) GetPosition() *uint { return r.Position } +func (r *ContactCardSearchResults) GetLimit() *uint { return r.Limit } +func (r *ContactCardSearchResults) GetTotal() *uint { return r.Total } +func (r *ContactCardSearchResults) RemoveResults() { r.Results = nil } +func (r *ContactCardSearchResults) SetLimit(limit *uint) { r.Limit = limit } +func (r *ContactCardSearchResults) SetPosition(position *uint) { r.Position = position } func (j *Client) QueryContactCards(accountIds []string, //NOSONAR filter ContactCardFilterElement, sortBy []ContactCardComparator, @@ -89,8 +92,8 @@ func (j *Client) QueryContactCards(accountIds []string, //NOSONAR func(query ContactCardQueryResponse, get ContactCardGetResponse) *ContactCardSearchResults { return &ContactCardSearchResults{ Results: get.List, - CanCalculateChanges: query.CanCalculateChanges, - Position: query.Position, + CanCalculateChanges: ChangeCalculation(query.CanCalculateChanges), + Position: ptrIf(query.Position, anchor == ""), Total: valueIf(query.Total, calculateTotal), Limit: ptrIf(query.Limit, limit != nil), } diff --git a/pkg/jmap/api_email.go b/pkg/jmap/api_email.go index c4678178ef..a8552df8f5 100644 --- a/pkg/jmap/api_email.go +++ b/pkg/jmap/api_email.go @@ -115,13 +115,14 @@ type EmailSearchResults SearchResultsTemplate[Email] var _ SearchResults[Email] = &EmailSearchResults{} -func (r *EmailSearchResults) GetResults() []Email { return r.Results } -func (r *EmailSearchResults) GetCanCalculateChanges() bool { return r.CanCalculateChanges } -func (r *EmailSearchResults) GetPosition() uint { return r.Position } -func (r *EmailSearchResults) GetLimit() *uint { return r.Limit } -func (r *EmailSearchResults) GetTotal() *uint { return r.Total } -func (r *EmailSearchResults) RemoveResults() { r.Results = nil } -func (r *EmailSearchResults) SetLimit(limit *uint) { r.Limit = limit } +func (r *EmailSearchResults) GetResults() []Email { return r.Results } +func (r *EmailSearchResults) GetCanCalculateChanges() ChangeCalculation { return r.CanCalculateChanges } +func (r *EmailSearchResults) GetPosition() *uint { return r.Position } +func (r *EmailSearchResults) GetLimit() *uint { return r.Limit } +func (r *EmailSearchResults) GetTotal() *uint { return r.Total } +func (r *EmailSearchResults) RemoveResults() { r.Results = nil } +func (r *EmailSearchResults) SetLimit(limit *uint) { r.Limit = limit } +func (r *EmailSearchResults) SetPosition(position *uint) { r.Position = position } // Retrieve all the Emails in a given Mailbox by its id. func (j *Client) GetAllEmailsInMailbox(accountId string, mailboxId string, //NOSONAR @@ -204,8 +205,8 @@ func (j *Client) GetAllEmailsInMailbox(accountId string, mailboxId string, //NOS return &EmailSearchResults{ Results: getResponse.List, - CanCalculateChanges: queryResponse.CanCalculateChanges, - Position: queryResponse.Position, + CanCalculateChanges: ChangeCalculation(queryResponse.CanCalculateChanges), + Position: ptrIf(queryResponse.Position, anchor == ""), Limit: ptrIf(queryResponse.Limit, limit != nil), Total: uintPtr(queryResponse.Total), }, queryResponse.QueryState, nil @@ -308,7 +309,7 @@ type SearchSnippetWithMeta struct { type EmailSnippetSearchResults SearchResultsTemplate[SearchSnippetWithMeta] func (j *Client) QueryEmailSnippets(accountIds []string, //NOSONAR - filter EmailFilterElement, position int, limit *uint, + filter EmailFilterElement, position int, anchor string, anchorOffset *int, limit *uint, ctx Context) (map[string]EmailSnippetSearchResults, SessionState, State, Language, Error) { logger := j.loggerParams("QueryEmailSnippets", ctx, func(z zerolog.Context) zerolog.Context { l := z.Int(logPosition, position) @@ -329,6 +330,8 @@ func (j *Client) QueryEmailSnippets(accountIds []string, //NOSONAR CollapseThreads: true, CalculateTotal: true, Position: position, + Anchor: anchor, + AnchorOffset: anchorOffset, Limit: limit, } @@ -411,10 +414,10 @@ func (j *Client) QueryEmailSnippets(accountIds []string, //NOSONAR results[accountId] = EmailSnippetSearchResults{ Results: snippets, - CanCalculateChanges: queryResponse.CanCalculateChanges, + CanCalculateChanges: ChangeCalculation(queryResponse.CanCalculateChanges), Total: uintPtr(queryResponse.Total), Limit: ptrIf(queryResponse.Limit, limit != nil), - Position: queryResponse.Position, + Position: ptrIf(queryResponse.Position, anchor == ""), } } return results, squashState(states), nil @@ -509,13 +512,13 @@ type EmailWithSnippets struct { type EmailQueryWithSnippetsResult struct { Results []EmailWithSnippets `json:"results"` Total uint `json:"total"` - Position uint `json:"position"` - Limit uint `json:"limit,omitzero"` + Position *uint `json:"position,omitempty"` + Limit uint `json:"limit"` QueryState State `json:"queryState"` } func (j *Client) QueryEmailsWithSnippets(accountIds []string, //NOSONAR - filter EmailFilterElement, position int, limit *uint, collapseThreads bool, calculateTotal bool, fetchBodies bool, maxBodyValueBytes uint, + filter EmailFilterElement, position int, anchor string, anchorOffset *int, limit *uint, collapseThreads bool, calculateTotal bool, fetchBodies bool, maxBodyValueBytes uint, ctx Context) (map[string]EmailQueryWithSnippetsResult, SessionState, State, Language, Error) { logger := j.loggerParams("QueryEmailsWithSnippets", ctx, func(z zerolog.Context) zerolog.Context { return z.Bool(logFetchBodies, fetchBodies) @@ -532,6 +535,8 @@ func (j *Client) QueryEmailsWithSnippets(accountIds []string, //NOSONAR CollapseThreads: collapseThreads, CalculateTotal: calculateTotal, Position: position, + Anchor: anchor, + AnchorOffset: anchorOffset, Limit: limit, } @@ -611,7 +616,7 @@ func (j *Client) QueryEmailsWithSnippets(accountIds []string, //NOSONAR Results: results, Total: queryResponse.Total, Limit: queryResponse.Limit, - Position: queryResponse.Position, + Position: ptrIf(queryResponse.Position, anchor == ""), QueryState: queryResponse.QueryState, } } @@ -1003,7 +1008,7 @@ type EmailsSummary struct { Emails []Email `json:"emails"` Total uint `json:"total"` Limit uint `json:"limit"` - Position uint `json:"position"` + Position *uint `json:"position,omitempty"` State State `json:"state"` } @@ -1027,7 +1032,7 @@ var EmailSummaryProperties = []string{ } func (j *Client) QueryEmailSummaries(accountIds []string, //NOSONAR - filter EmailFilterElement, limit *uint, withThreads bool, calculateTotal bool, + filter EmailFilterElement, position int, anchor string, anchorOffset *int, limit *uint, withThreads bool, calculateTotal bool, ctx Context) (map[string]EmailsSummary, SessionState, State, Language, Error) { logger := j.logger("QueryEmailSummaries", ctx) ctx = ctx.WithLogger(logger) @@ -1046,6 +1051,9 @@ func (j *Client) QueryEmailSummaries(accountIds []string, //NOSONAR Filter: filter, Sort: []EmailComparator{{Property: EmailPropertyReceivedAt, IsAscending: false}}, CalculateTotal: calculateTotal, + Position: position, + Anchor: anchor, + AnchorOffset: anchorOffset, Limit: limit, } invocations[i*factor+0] = invocation(get, mcid(accountId, "0")) @@ -1105,7 +1113,7 @@ func (j *Client) QueryEmailSummaries(accountIds []string, //NOSONAR Emails: response.List, Total: queryResponse.Total, Limit: queryResponse.Limit, - Position: queryResponse.Position, + Position: ptrIf(queryResponse.Position, anchor == ""), State: response.State, } } diff --git a/pkg/jmap/api_event.go b/pkg/jmap/api_event.go index 9fbb8450d4..6bffeb9c1b 100644 --- a/pkg/jmap/api_event.go +++ b/pkg/jmap/api_event.go @@ -6,13 +6,16 @@ type CalendarEventSearchResults SearchResultsTemplate[CalendarEvent] var _ SearchResults[CalendarEvent] = &CalendarEventSearchResults{} -func (r *CalendarEventSearchResults) GetResults() []CalendarEvent { return r.Results } -func (r *CalendarEventSearchResults) GetCanCalculateChanges() bool { return r.CanCalculateChanges } -func (r *CalendarEventSearchResults) GetPosition() uint { return r.Position } -func (r *CalendarEventSearchResults) GetLimit() *uint { return r.Limit } -func (r *CalendarEventSearchResults) GetTotal() *uint { return r.Total } -func (r *CalendarEventSearchResults) RemoveResults() { r.Results = nil } -func (r *CalendarEventSearchResults) SetLimit(limit *uint) { r.Limit = limit } +func (r *CalendarEventSearchResults) GetResults() []CalendarEvent { return r.Results } +func (r *CalendarEventSearchResults) GetCanCalculateChanges() ChangeCalculation { + return r.CanCalculateChanges +} +func (r *CalendarEventSearchResults) GetPosition() *uint { return r.Position } +func (r *CalendarEventSearchResults) GetLimit() *uint { return r.Limit } +func (r *CalendarEventSearchResults) GetTotal() *uint { return r.Total } +func (r *CalendarEventSearchResults) RemoveResults() { r.Results = nil } +func (r *CalendarEventSearchResults) SetLimit(limit *uint) { r.Limit = limit } +func (r *CalendarEventSearchResults) SetPosition(position *uint) { r.Position = position } func (j *Client) GetCalendarEvents(accountId string, eventIds []string, ctx Context) (CalendarEventGetResponse, SessionState, State, Language, Error) { return get(j, "GetCalendarEvents", CalendarEventType, @@ -41,8 +44,8 @@ func (j *Client) QueryCalendarEvents(accountIds []string, //NOSONAR func(query CalendarEventQueryResponse, get CalendarEventGetResponse) *CalendarEventSearchResults { return &CalendarEventSearchResults{ Results: get.List, - CanCalculateChanges: query.CanCalculateChanges, - Position: query.Position, + CanCalculateChanges: ChangeCalculation(query.CanCalculateChanges), + Position: ptrIf(query.Position, anchor == ""), Total: valueIf(query.Total, calculateTotal), Limit: ptrIf(query.Limit, limit != nil), } diff --git a/pkg/jmap/api_principal.go b/pkg/jmap/api_principal.go index c8d48b37d6..e0641e9adc 100644 --- a/pkg/jmap/api_principal.go +++ b/pkg/jmap/api_principal.go @@ -18,13 +18,16 @@ type PrincipalSearchResults SearchResultsTemplate[Principal] var _ SearchResults[Principal] = &PrincipalSearchResults{} -func (r *PrincipalSearchResults) GetResults() []Principal { return r.Results } -func (r *PrincipalSearchResults) GetCanCalculateChanges() bool { return r.CanCalculateChanges } -func (r *PrincipalSearchResults) GetPosition() uint { return r.Position } -func (r *PrincipalSearchResults) GetLimit() *uint { return r.Limit } -func (r *PrincipalSearchResults) GetTotal() *uint { return r.Total } -func (r *PrincipalSearchResults) RemoveResults() { r.Results = nil } -func (r *PrincipalSearchResults) SetLimit(limit *uint) { r.Limit = limit } +func (r *PrincipalSearchResults) GetResults() []Principal { return r.Results } +func (r *PrincipalSearchResults) GetCanCalculateChanges() ChangeCalculation { + return r.CanCalculateChanges +} +func (r *PrincipalSearchResults) GetPosition() *uint { return r.Position } +func (r *PrincipalSearchResults) GetLimit() *uint { return r.Limit } +func (r *PrincipalSearchResults) GetTotal() *uint { return r.Total } +func (r *PrincipalSearchResults) RemoveResults() { r.Results = nil } +func (r *PrincipalSearchResults) SetLimit(limit *uint) { r.Limit = limit } +func (r *PrincipalSearchResults) SetPosition(position *uint) { r.Position = position } func (j *Client) QueryPrincipals(accountId string, //NOSONAR filter PrincipalFilterElement, sortBy []PrincipalComparator, @@ -41,8 +44,8 @@ func (j *Client) QueryPrincipals(accountId string, //NOSONAR func(query PrincipalQueryResponse, get PrincipalGetResponse) *PrincipalSearchResults { return &PrincipalSearchResults{ Results: get.List, - CanCalculateChanges: query.CanCalculateChanges, - Position: query.Position, + CanCalculateChanges: ChangeCalculation(query.CanCalculateChanges), + Position: ptrIf(query.Position, anchor == ""), Total: ptrIf(query.Total, calculateTotal), Limit: ptrIf(query.Limit, limit != nil), } diff --git a/pkg/jmap/integration_addressbook_test.go b/pkg/jmap/integration_addressbook_test.go index 447d676a72..18bd0c296f 100644 --- a/pkg/jmap/integration_addressbook_test.go +++ b/pkg/jmap/integration_addressbook_test.go @@ -108,10 +108,11 @@ func TestContacts(t *testing.T) { results := contactsByAccount[accountId] require.Len(results.Results, int(count)) require.Nil(results.Limit) - require.Equal(uint(0), results.Position) + require.NotNil(results.Position) + require.Equal(uint(0), *results.Position) require.NotNil(results.Total) require.Equal(count, *results.Total) - require.Equal(true, results.CanCalculateChanges) + require.Equal(ChangeCalculation(true), results.CanCalculateChanges) for _, actual := range results.Results { expected, ok := expectedContactCardsById[actual.Id] @@ -158,8 +159,9 @@ func TestContacts(t *testing.T) { require.Equal(len(results.Results), int(page)) require.NotNil(results.Limit) require.Equal(limit, *results.Limit) - require.Equal(uint(position), results.Position) - require.Equal(true, results.CanCalculateChanges) + require.NotNil(results.Position) + require.Equal(uint(position), *results.Position) + require.Equal(ChangeCalculation(true), results.CanCalculateChanges) require.NotNil(results.Total) require.Equal(count, *results.Total) remainder -= uint(len(results.Results)) @@ -185,17 +187,9 @@ func TestContacts(t *testing.T) { require.NotZero(l) require.NotNil(results.Limit) require.Equal(uint(chunkSize), *results.Limit) - //require.Equal(uint(i*chunkSize), results.Position) - require.Equal(true, results.CanCalculateChanges) + require.Equal(ChangeCalculation(true), results.CanCalculateChanges) require.NotNil(results.Total) require.Equal(count, *results.Total) - - fmt.Printf("\x1b[34;1m===[%d]========================================\x1b[0m\n", i) - fmt.Printf("pos: %d\n", results.Position) - fmt.Printf("chunk : %s\n", strings.Join(structs.Map(chunk, func(c ContactCard) string { return c.Id }), " | ")) - fmt.Printf("results: %s\n", strings.Join(structs.Map(results.Results, func(c ContactCard) string { return c.Id }), " | ")) - fmt.Printf("============================================\n") - for i := range l { require.Equal(chunk[i].Id, results.Results[i].Id) } @@ -203,7 +197,6 @@ func TestContacts(t *testing.T) { offset = 1 i++ } - require.True(false) } { diff --git a/pkg/jmap/integration_calendar_test.go b/pkg/jmap/integration_calendar_test.go index cc2fa51c4a..1f4e0e0434 100644 --- a/pkg/jmap/integration_calendar_test.go +++ b/pkg/jmap/integration_calendar_test.go @@ -92,17 +92,20 @@ func TestEvents(t *testing.T) { ss := EmptySessionState os := EmptyState + var results *CalendarEventSearchResults { resultsByAccount, sessionState, state, _, err := s.client.QueryCalendarEvents([]string{accountId}, filter, sortBy, 0, "", nil, nil, true, ctx) require.NoError(err) require.Len(resultsByAccount, 1) require.Contains(resultsByAccount, accountId) - results := resultsByAccount[accountId] + results = resultsByAccount[accountId] + require.NotNil(results) require.Len(results.Results, int(count)) - require.Equal(uint(0), results.Limit) - require.Equal(uint(0), results.Position) - require.Equal(true, results.CanCalculateChanges) + require.Nil(results.Limit) + require.NotNil(results.Position) + require.Equal(uint(0), *results.Position) + require.Equal(ChangeCalculation(true), results.CanCalculateChanges) require.NotNil(results.Total) require.Equal(count, *results.Total) @@ -130,9 +133,11 @@ func TestEvents(t *testing.T) { require.Contains(m, accountId) results := m[accountId] require.Equal(len(results.Results), int(page)) - require.Equal(limit, results.Limit) - require.Equal(uint(position), results.Position) - require.Equal(true, results.CanCalculateChanges) + require.NotNil(results.Limit) + require.Equal(limit, *results.Limit) + require.NotNil(results.Position) + require.Equal(uint(position), *results.Position) + require.Equal(ChangeCalculation(true), results.CanCalculateChanges) require.NotNil(results.Total) require.Equal(count, *results.Total) remainder -= uint(len(results.Results)) @@ -141,6 +146,35 @@ func TestEvents(t *testing.T) { } } + { + chunkSize := 3 + anchor := results.Results[0].Id + offset := 0 + i := 0 + for chunk := range slices.Chunk(results.Results, chunkSize) { + m, sessionState, _, _, err := s.client.QueryCalendarEvents([]string{accountId}, filter, sortBy, 0, anchor, &offset, uintPtr(chunkSize), true, ctx) + require.Equal(ss, sessionState) + require.NoError(err) + require.Len(m, 1) + require.Contains(m, accountId) + results := m[accountId] + l := len(results.Results) + require.LessOrEqual(l, chunkSize) + require.NotZero(l) + require.NotNil(results.Limit) + require.Equal(uint(chunkSize), *results.Limit) + require.Equal(ChangeCalculation(true), results.CanCalculateChanges) + require.NotNil(results.Total) + require.Equal(count, *results.Total) + for i := range l { + require.Equal(chunk[i].Id, results.Results[i].Id) + } + anchor = chunk[len(chunk)-1].Id + offset = 1 + i++ + } + } + for _, event := range expectedEventsById { change := CalendarEventChange{ EventChange: jscalendar.EventChange{ diff --git a/pkg/jmap/model.go b/pkg/jmap/model.go index e1e00995aa..8191fd8c8c 100644 --- a/pkg/jmap/model.go +++ b/pkg/jmap/model.go @@ -1422,6 +1422,16 @@ type Changes[T Foo] interface { GetDestroyed() []string } +// using a custom type for the "canCalculateChanges" attribute in order to customize its rendering: +// as it's going to be "true" in 99% if not 100% of cases with Stalwart, we only want to render this +// attribute if its value is "false" + +type ChangeCalculation bool + +func (cc *ChangeCalculation) IsZero() bool { + return *cc == true +} + type SearchResultsTemplate[T Foo] struct { // The list of objects that resulted from the query. Results []T `json:"results,omitempty"` @@ -1430,10 +1440,10 @@ type SearchResultsTemplate[T Foo] struct { // // Note, this does not guarantee that the queryChanges call will succeed, as it may only be possible for a limited time // afterwards due to server internal implementation details. - CanCalculateChanges bool `json:"canCalculateChanges"` + CanCalculateChanges ChangeCalculation `json:"canCalculateChanges,omitzero"` // The pagination position that was requested using the `position` query parameter. - Position uint `json:"position"` + Position *uint `json:"position,omitempty"` // The maximum amount of results to return, as requested using the `limit` query parameter. Limit *uint `json:"limit,omitempty"` @@ -1444,12 +1454,13 @@ type SearchResultsTemplate[T Foo] struct { type SearchResults[T Foo] interface { GetResults() []T - GetCanCalculateChanges() bool - GetPosition() uint + GetCanCalculateChanges() ChangeCalculation + GetPosition() *uint GetTotal() *uint GetLimit() *uint RemoveResults() SetLimit(*uint) + SetPosition(*uint) } type FilterOperatorTerm string @@ -3175,7 +3186,7 @@ type EmailQueryResponse struct { // // Note, this does not guarantee that the Email/queryChanges call will succeed, as it may only be possible for a limited time // afterwards due to server internal implementation details. - CanCalculateChanges bool `json:"canCalculateChanges"` + CanCalculateChanges ChangeCalculation `json:"canCalculateChanges,omitzero"` // The zero-based index of the first result in the ids array within the complete list of query results. Position uint `json:"position"` @@ -3400,7 +3411,7 @@ type MailboxQueryResponse struct { // // Note, this does not guarantee that the Mailbox/queryChanges call will succeed, as it may only be possible for // a limited time afterwards due to server internal implementation details. - CanCalculateChanges bool `json:"canCalculateChanges"` + CanCalculateChanges ChangeCalculation `json:"canCalculateChanges,omitzero"` // The zero-based index of the first result in the ids array within the complete list of query results. Position int `json:"position"` @@ -7127,7 +7138,7 @@ type ContactCardQueryResponse struct { // // Note, this does not guarantee that the ContactCard/queryChanges call will succeed, as it may only be possible for a limited time // afterwards due to server internal implementation details. - CanCalculateChanges bool `json:"canCalculateChanges"` + CanCalculateChanges ChangeCalculation `json:"canCalculateChanges,omitzero"` // The zero-based index of the first result in the ids array within the complete list of query results. Position uint `json:"position"` @@ -7857,7 +7868,7 @@ type CalendarEventQueryResponse struct { // // Note, this does not guarantee that the CalendarEvent/queryChanges call will succeed, as it may only be possible for a limited time // afterwards due to server internal implementation details. - CanCalculateChanges bool `json:"canCalculateChanges"` + CanCalculateChanges ChangeCalculation `json:"canCalculateChanges,omitzero"` // The zero-based index of the first result in the ids array within the complete list of query results. Position uint `json:"position"` @@ -8333,7 +8344,7 @@ type PrincipalQueryResponse struct { // // Note, this does not guarantee that the Principal/queryChanges call will succeed, as it may only be possible for // a limited time afterwards due to server internal implementation details. - CanCalculateChanges bool `json:"canCalculateChanges"` + CanCalculateChanges ChangeCalculation `json:"canCalculateChanges,omitzero"` // The zero-based index of the first result in the ids array within the complete list of query results. Position uint `json:"position"` diff --git a/pkg/jmap/model_examples.go b/pkg/jmap/model_examples.go index 5601caa7d7..c9a886d43f 100644 --- a/pkg/jmap/model_examples.go +++ b/pkg/jmap/model_examples.go @@ -816,7 +816,7 @@ func (e Exemplar) Emails() EmailSearchResults { Results: []Email{e.Email()}, Total: uintPtr(132), Limit: uintPtr(1), - Position: 5, + Position: uintPtr(5), CanCalculateChanges: true, } } diff --git a/services/groupware/Makefile b/services/groupware/Makefile index bd8066817d..f83ffaf1b6 100644 --- a/services/groupware/Makefile +++ b/services/groupware/Makefile @@ -32,7 +32,7 @@ serve-apidoc: swagger.yml tsnode api.html: swagger.yml favicon.png tsnode pnpm exec redocly build-docs --output=$@.template --title="OpenCloud Groupware API" --theme.openapi.hideHostname=false --theme.openapi.hideTryItPanel=false --theme.openapi.pathInMiddlePanel=true $< - NODE_OPTIONS='--no-warnings --loader ts-node/esm' pnpm exec ts-node ./apidoc-postprocess-html.ts favicon.png < $@.template > $@ + NODE_OPTIONS='--no-warnings' pnpm exec node ./apidoc-postprocess-html.js favicon.png < $@.template > $@ rm $@.template .PHONY: apidoc-static @@ -48,3 +48,7 @@ examples: .PHONY: gosec gosec: cd ../../ && gosec ./pkg/jmap/... ./pkg/jscalendar/... ./pkg/jscontact/... ./services/groupware/pkg/... + +.PHONY: update-redocly +update-redocly: + pnpm update @redocly/cli@latest diff --git a/services/groupware/apidoc-postprocess-html.js b/services/groupware/apidoc-postprocess-html.js new file mode 100644 index 0000000000..65e4ebcf3d --- /dev/null +++ b/services/groupware/apidoc-postprocess-html.js @@ -0,0 +1,38 @@ +import * as fs from 'fs' +import * as cheerio from 'cheerio' +import { stdin } from 'process' + +process.on('unhandledRejection', (reason, promise) => { + console.error('Unhandled Rejection at:', promise, 'reason:', reason); + process.exit(1); +}); + +async function run() { + try { + const faviconFile = process.argv[2]; + if (!faviconFile) { + throw new Error("No favicon file provided"); + } + + const favicon = fs.readFileSync(faviconFile).toString('base64'); + + let html = ''; + for await (const chunk of stdin) { + html += chunk; + } + + if (!html) { + throw new Error("No HTML received from stdin"); + } + + const $ = cheerio.load(html); + $('head').append(``); + + process.stdout.write($.html() + "\n"); + } catch (e) { + console.error(`Error occurred while post-processing HTML: ${e.message}`); + process.exit(1); + } +} + +run(); diff --git a/services/groupware/apidoc-postprocess-html.ts b/services/groupware/apidoc-postprocess-html.ts deleted file mode 100644 index 6a10baf00c..0000000000 --- a/services/groupware/apidoc-postprocess-html.ts +++ /dev/null @@ -1,24 +0,0 @@ -import * as fs from 'fs' -import * as cheerio from 'cheerio' - -const faviconFile = process.argv[2] -const favicon = fs.readFileSync(faviconFile).toString('base64') - -let html = '' -process.stdin.on('data', (chunk) => { - html += chunk.toString() -}) -process.stdin.on('end', () => { - try { - const $ = cheerio.load(html) - $('head').append(``) - process.stdout.write($.html()) - process.stdout.write("\n") - } catch (error) { - if (error instanceof Error) { - console.error(`Error occurred while post-processing HTML: ${error.message}`) - } else { - console.error("Unknown error occurred") - } - } -}); diff --git a/services/groupware/package.json b/services/groupware/package.json index 2204122853..4471364077 100644 --- a/services/groupware/package.json +++ b/services/groupware/package.json @@ -1,15 +1,15 @@ { "dependencies": { - "@redocly/cli": "^2.29.1", + "@redocly/cli": "^2.30.1", "@types/js-yaml": "^4.0.9", "cheerio": "^1.2.0", "js-yaml": "^4.1.1", "ts-node": "^10.9.2", - "typescript": "^5.9.3" + "typescript": "^6.0.3" }, "packageManager": "pnpm@10.33.2+sha512.a90faf6feeab71ad6c6e57f94e0fe1a12f5dcc22cd754db40ae9593eb6a3e0b6b12e3540218bb37ae083404b1f2ce6db2a4121e979829b4aff94b99f49da1cf8", "type": "module", "devDependencies": { - "@types/node": "^24.10.15" + "@types/node": "^25.6.0" } } diff --git a/services/groupware/pkg/groupware/api_emails.go b/services/groupware/pkg/groupware/api_emails.go index 5f59f61991..b32f9e4501 100644 --- a/services/groupware/pkg/groupware/api_emails.go +++ b/services/groupware/pkg/groupware/api_emails.go @@ -362,7 +362,7 @@ type SnippetWithoutEmailId struct { type EmailWithSnippetsSearchResults jmap.SearchResultsTemplate[EmailWithSnippets] -func (g *Groupware) buildEmailFilter(req Request) (bool, jmap.EmailFilterElement, bool, int, *uint, *log.Logger, *Error) { //NOSONAR +func (g *Groupware) buildEmailFilter(req Request) (bool, jmap.EmailFilterElement, bool, int, string, *int, *uint, *log.Logger, *Error) { //NOSONAR mailboxId, _ := req.getStringParam(QueryParamMailboxId, "") // the identifier of the Mailbox to which to restrict the search text, _ := req.getStringParam(QueryParamSearchText, "") // text that must be included in the Email, specifically in From, To, Cc, Bcc, Subject and any text/* body part from, _ := req.getStringParam(QueryParamSearchFrom, "") // text that must be included in the From header of the Email @@ -374,11 +374,11 @@ func (g *Groupware) buildEmailFilter(req Request) (bool, jmap.EmailFilterElement messageId, _ := req.getStringParam(QueryParamSearchMessageId, "") // value of the Message-ID header of the Email notInMailboxIds, _, err := req.parseOptStringListParam(QueryParamNotInMailboxId) // a comma-separated list of identifiers of Mailboxes the Email must *not* be in if err != nil { - return false, nil, false, 0, nil, nil, err + return false, nil, false, 0, "", nil, nil, nil, err } keywords, _, err := req.parseOptStringListParam(QueryParamSearchKeyword) // the Email must have all those keywords if err != nil { - return false, nil, false, 0, nil, nil, err + return false, nil, false, 0, "", nil, nil, nil, err } snippets := false @@ -387,17 +387,34 @@ func (g *Groupware) buildEmailFilter(req Request) (bool, jmap.EmailFilterElement position, ok, err := req.parseIntParam(QueryParamPosition, 0) // pagination element position (offset) if err != nil { - return false, nil, snippets, 0, nil, nil, err + return false, nil, snippets, 0, "", nil, nil, nil, err } if ok { l = l.Int(QueryParamPosition, position) } + anchor, ok := req.getStringParam(QueryParamAnchor, "") // pagination element anchor + if ok { + l = l.Str(QueryParamAnchor, log.SafeString(anchor)) + } + + var anchorOffset *int = nil + { + v, ok, err := req.parseIntParam(QueryParamAnchorOffset, 0) // optional offset relative to the anchor + if err != nil { + return false, nil, snippets, 0, "", nil, nil, nil, err + } + if ok { + l = l.Int(QueryParamAnchorOffset, v) + anchorOffset = &v + } + } + var limit *uint = nil { v, ok, err := req.parseUIntParam(QueryParamLimit, g.defaults.emailLimit) // maximum number of results (size of a page) if err != nil { - return false, nil, snippets, 0, nil, nil, err + return false, nil, snippets, 0, "", nil, nil, nil, err } if ok { l = l.Uint(QueryParamLimit, v) @@ -407,7 +424,7 @@ func (g *Groupware) buildEmailFilter(req Request) (bool, jmap.EmailFilterElement before, ok, err := req.parseDateParam(QueryParamSearchBefore) // the Email must have been received before this date-time if err != nil { - return false, nil, snippets, 0, nil, nil, err + return false, nil, snippets, 0, "", nil, nil, nil, err } if ok { l = l.Time(QueryParamSearchBefore, before) @@ -415,7 +432,7 @@ func (g *Groupware) buildEmailFilter(req Request) (bool, jmap.EmailFilterElement after, ok, err := req.parseDateParam(QueryParamSearchAfter) // the Email must have been received after this date-time if err != nil { - return false, nil, snippets, 0, nil, nil, err + return false, nil, snippets, 0, "", nil, nil, nil, err } if ok { l = l.Time(QueryParamSearchAfter, after) @@ -454,7 +471,7 @@ func (g *Groupware) buildEmailFilter(req Request) (bool, jmap.EmailFilterElement minSize, ok, err := req.parseIntParam(QueryParamSearchMinSize, 0) // the minimum size of the Email if err != nil { - return false, nil, snippets, 0, nil, nil, err + return false, nil, snippets, 0, "", nil, nil, nil, err } if ok { l = l.Int(QueryParamSearchMinSize, minSize) @@ -462,7 +479,7 @@ func (g *Groupware) buildEmailFilter(req Request) (bool, jmap.EmailFilterElement maxSize, ok, err := req.parseIntParam(QueryParamSearchMaxSize, 0) // the maximum size of the Email if err != nil { - return false, nil, snippets, 0, nil, nil, err + return false, nil, snippets, 0, "", nil, nil, nil, err } if ok { l = l.Int(QueryParamSearchMaxSize, maxSize) @@ -516,7 +533,7 @@ func (g *Groupware) buildEmailFilter(req Request) (bool, jmap.EmailFilterElement } } - return true, filter, snippets, position, limit, logger, nil + return true, filter, snippets, position, anchor, anchorOffset, limit, logger, nil } func (g *Groupware) GetEmails(w http.ResponseWriter, r *http.Request) { //NOSONAR @@ -538,7 +555,7 @@ func (g *Groupware) GetEmails(w http.ResponseWriter, r *http.Request) { //NOSONA l := req.logger.With().Str(logAccountId, log.SafeString(accountId)) - ok, filter, makesSnippets, position, limit, logger, err := g.buildEmailFilter(req) + ok, filter, makesSnippets, position, anchor, anchorOffset, limit, logger, err := g.buildEmailFilter(req) if !ok { return req.error(accountId, err) } @@ -566,7 +583,7 @@ func (g *Groupware) GetEmails(w http.ResponseWriter, r *http.Request) { //NOSONA jmaplimit = UintPtrOne } - resultsByAccount, sessionState, state, lang, jerr := g.jmap.QueryEmailsWithSnippets(single(accountId), filter, position, jmaplimit, collapseThreads, calculateTotal, fetchBodies, g.config.maxBodyValueBytes, ctx) + resultsByAccount, sessionState, state, lang, jerr := g.jmap.QueryEmailsWithSnippets(single(accountId), filter, position, anchor, anchorOffset, jmaplimit, collapseThreads, calculateTotal, fetchBodies, g.config.maxBodyValueBytes, ctx) if jerr != nil { return req.jmapError(accountId, jerr, sessionState, lang) } @@ -623,7 +640,7 @@ func (g *Groupware) GetEmailsForAllAccounts(w http.ResponseWriter, r *http.Reque g.respond(w, r, func(req Request) Response { allAccountIds := req.AllAccountIds() - ok, filter, makesSnippets, position, limit, logger, err := g.buildEmailFilter(req) + ok, filter, makesSnippets, position, anchor, anchorOffset, limit, logger, err := g.buildEmailFilter(req) if !ok { return req.errorN(allAccountIds, err) } @@ -640,7 +657,7 @@ func (g *Groupware) GetEmailsForAllAccounts(w http.ResponseWriter, r *http.Reque } if makesSnippets { - resultsByAccountId, sessionState, state, lang, jerr := g.jmap.QueryEmailSnippets(allAccountIds, filter, position, jmaplimit, ctx) + resultsByAccountId, sessionState, state, lang, jerr := g.jmap.QueryEmailSnippets(allAccountIds, filter, position, anchor, anchorOffset, jmaplimit, ctx) if jerr != nil { return req.jmapErrorN(allAccountIds, jerr, sessionState, lang) } @@ -687,7 +704,7 @@ func (g *Groupware) GetEmailsForAllAccounts(w http.ResponseWriter, r *http.Reque withThreads := true calculateTotal := true - resultsByAccountId, sessionState, state, lang, jerr := g.jmap.QueryEmailSummaries(allAccountIds, filter, jmaplimit, withThreads, calculateTotal, ctx) + resultsByAccountId, sessionState, state, lang, jerr := g.jmap.QueryEmailSummaries(allAccountIds, filter, position, anchor, anchorOffset, jmaplimit, withThreads, calculateTotal, ctx) if jerr != nil { return req.jmapErrorN(allAccountIds, jerr, sessionState, lang) } @@ -1478,17 +1495,40 @@ func (g *Groupware) GetLatestEmailsSummaryForAllAccounts(w http.ResponseWriter, l = l.Uint(QueryParamLimit, limit) } - position, ok, err := req.parseUIntParam(QueryParamPosition, 0) + position, ok, err := req.parseIntParam(QueryParamPosition, 0) if err != nil { return req.errorN(allAccountIds, err) } - if position > 0 { + if position != 0 { return req.notImplementedN(allAccountIds, EmailResponseObjectType) } if ok { l = l.Uint(QueryParamPosition, limit) } + anchor, ok := req.getStringParam(QueryParamAnchor, "") // pagination element anchor + if anchor != "" { + return req.notImplementedN(allAccountIds, EmailResponseObjectType) + } + if ok { + l = l.Str(QueryParamAnchor, log.SafeString(anchor)) + } + + var anchorOffset *int = nil + { + v, ok, err := req.parseIntParam(QueryParamAnchorOffset, 0) // optional offset relative to the anchor + if err != nil { + return req.errorN(allAccountIds, err) + } + if ok { + return req.notImplementedN(allAccountIds, EmailResponseObjectType) + } + if ok { + l = l.Int(QueryParamAnchorOffset, v) + anchorOffset = &v + } + } + seen, ok, err := req.parseBoolParam(QueryParamSeen, false) if err != nil { return req.errorN(allAccountIds, err) @@ -1522,7 +1562,7 @@ func (g *Groupware) GetLatestEmailsSummaryForAllAccounts(w http.ResponseWriter, calculateTotal := true withThreads := true - emailsSummariesByAccount, sessionState, state, lang, jerr := g.jmap.QueryEmailSummaries(allAccountIds, filter, &limit, withThreads, calculateTotal, ctx) + emailsSummariesByAccount, sessionState, state, lang, jerr := g.jmap.QueryEmailSummaries(allAccountIds, filter, position, anchor, anchorOffset, &limit, withThreads, calculateTotal, ctx) if jerr != nil { return req.jmapErrorN(allAccountIds, jerr, sessionState, lang) } @@ -1551,7 +1591,7 @@ func (g *Groupware) GetLatestEmailsSummaryForAllAccounts(w http.ResponseWriter, body := EmailSummaries{ Results: summaries, Limit: &limit, - Position: position, + Position: UintPtrZero, // TODO position from results } if calculateTotal { body.Total = &total diff --git a/services/groupware/pkg/groupware/templates.go b/services/groupware/pkg/groupware/templates.go index bd3b1905b8..9f7bf435bb 100644 --- a/services/groupware/pkg/groupware/templates.go +++ b/services/groupware/pkg/groupware/templates.go @@ -169,6 +169,9 @@ func getallpaged[T jmap.Foo, CHANGE jmap.Change, CHANGES jmap.Changes[T], FILTER results.RemoveResults() results.SetLimit(UintPtrZero) } + if anchor != "" && results.GetPosition() != nil && *results.GetPosition() == 0 { + results.SetPosition(nil) + } return req.respond(accountId, results, sessionState, o.responseType, state, lang) }) @@ -256,6 +259,9 @@ func query[T jmap.Foo, CHANGE jmap.Change, CHANGES jmap.Changes[T], SEARCHRESULT results.RemoveResults() results.SetLimit(UintPtrZero) } + if anchor != "" && results.GetPosition() != nil && *results.GetPosition() == 0 { + results.SetPosition(nil) + } return req.respond(accountId, results, sessionState, o.responseType, state, lang) }) diff --git a/services/groupware/pnpm-lock.yaml b/services/groupware/pnpm-lock.yaml index ac3e7d0a88..533c3b8ef2 100644 --- a/services/groupware/pnpm-lock.yaml +++ b/services/groupware/pnpm-lock.yaml @@ -9,8 +9,8 @@ importers: .: dependencies: '@redocly/cli': - specifier: ^2.29.1 - version: 2.29.1(@opentelemetry/api@1.9.1)(core-js@3.45.1) + specifier: ^2.30.1 + version: 2.30.1(@opentelemetry/api@1.9.1)(core-js@3.45.1) '@types/js-yaml': specifier: ^4.0.9 version: 4.0.9 @@ -22,14 +22,14 @@ importers: version: 4.1.1 ts-node: specifier: ^10.9.2 - version: 10.9.2(@types/node@24.10.15)(typescript@5.9.3) + version: 10.9.2(@types/node@25.6.0)(typescript@6.0.3) typescript: - specifier: ^5.9.3 - version: 5.9.3 + specifier: ^6.0.3 + version: 6.0.3 devDependencies: '@types/node': - specifier: ^24.10.15 - version: 24.10.15 + specifier: ^25.6.0 + version: 25.6.0 packages: @@ -86,76 +86,76 @@ packages: '@nodable/entities@2.1.0': resolution: {integrity: sha512-nyT7T3nbMyBI/lvr6L5TyWbFJAI9FTgVRakNoBqCD+PmID8DzFrrNdLLtHMwMszOtqZa8PAOV24ZqDnQrhQINA==} - '@opentelemetry/api-logs@0.202.0': - resolution: {integrity: sha512-fTBjMqKCfotFWfLzaKyhjLvyEyq5vDKTTFfBmx21btv3gvy8Lq6N5Dh2OzqeuN4DjtpSvNT1uNVfg08eD2Rfxw==} + '@opentelemetry/api-logs@0.214.0': + resolution: {integrity: sha512-40lSJeqYO8Uz2Yj7u94/SJWE/wONa7rmMKjI1ZcIjgf3MHNHv1OZUCrCETGuaRF62d5pQD1wKIW+L4lmSMTzZA==} engines: {node: '>=8.0.0'} '@opentelemetry/api@1.9.1': resolution: {integrity: sha512-gLyJlPHPZYdAk1JENA9LeHejZe1Ti77/pTeFm/nMXmQH/HFZlcS/O2XJB+L8fkbrNSqhdtlvjBVjxwUYanNH5Q==} engines: {node: '>=8.0.0'} - '@opentelemetry/context-async-hooks@2.0.1': - resolution: {integrity: sha512-XuY23lSI3d4PEqKA+7SLtAgwqIfc6E/E9eAQWLN1vlpC53ybO3o6jW4BsXo1xvz9lYyyWItfQDDLzezER01mCw==} + '@opentelemetry/context-async-hooks@2.6.1': + resolution: {integrity: sha512-XHzhwRNkBpeP8Fs/qjGrAf9r9PRv67wkJQ/7ZPaBQQ68DYlTBBx5MF9LvPx7mhuXcDessKK2b+DcxqwpgkcivQ==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': '>=1.0.0 <1.10.0' - '@opentelemetry/core@2.0.1': - resolution: {integrity: sha512-MaZk9SJIDgo1peKevlbhP6+IwIiNPNmswNL4AF0WaQJLbHXjr9SrZMgS12+iqr9ToV4ZVosCcc0f8Rg67LXjxw==} + '@opentelemetry/core@2.6.1': + resolution: {integrity: sha512-8xHSGWpJP9wBxgBpnqGL0R3PbdWQndL1Qp50qrg71+B28zK5OQmUgcDKLJgzyAAV38t4tOyLMGDD60LneR5W8g==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': '>=1.0.0 <1.10.0' - '@opentelemetry/exporter-trace-otlp-http@0.202.0': - resolution: {integrity: sha512-/hKE8DaFCJuaQqE1IxpgkcjOolUIwgi3TgHElPVKGdGRBSmJMTmN/cr6vWa55pCJIXPyhKvcMrbrya7DZ3VmzA==} + '@opentelemetry/exporter-trace-otlp-http@0.214.0': + resolution: {integrity: sha512-kIN8nTBMgV2hXzV/a20BCFilPZdAIMYYJGSgfMMRm/Xa+07y5hRDS2Vm12A/z8Cdu3Sq++ZvJfElokX2rkgGgw==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/otlp-exporter-base@0.202.0': - resolution: {integrity: sha512-nMEOzel+pUFYuBJg2znGmHJWbmvMbdX5/RhoKNKowguMbURhz0fwik5tUKplLcUtl8wKPL1y9zPnPxeBn65N0Q==} + '@opentelemetry/otlp-exporter-base@0.214.0': + resolution: {integrity: sha512-u1Gdv0/E9wP+apqWf7Wv2npXmgJtxsW2XL0TEv9FZloTZRuMBKmu8cYVXwS4Hm3q/f/3FuCnPTgiwYvIqRSpRg==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/otlp-transformer@0.202.0': - resolution: {integrity: sha512-5XO77QFzs9WkexvJQL9ksxL8oVFb/dfi9NWQSq7Sv0Efr9x3N+nb1iklP1TeVgxqJ7m1xWiC/Uv3wupiQGevMw==} + '@opentelemetry/otlp-transformer@0.214.0': + resolution: {integrity: sha512-DSaYcuBRh6uozfsWN3R8HsN0yDhCuWP7tOFdkUOVaWD1KVJg8m4qiLUsg/tNhTLS9HUYUcwNpwL2eroLtsZZ/w==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/resources@2.0.1': - resolution: {integrity: sha512-dZOB3R6zvBwDKnHDTB4X1xtMArB/d324VsbiPkX/Yu0Q8T2xceRthoIVFhJdvgVM2QhGVUyX9tzwiNxGtoBJUw==} + '@opentelemetry/resources@2.6.1': + resolution: {integrity: sha512-lID/vxSuKWXM55XhAKNoYXu9Cutoq5hFdkbTdI/zDKQktXzcWBVhNsOkiZFTMU9UtEWuGRNe0HUgmsFldIdxVA==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': '>=1.3.0 <1.10.0' - '@opentelemetry/sdk-logs@0.202.0': - resolution: {integrity: sha512-pv8QiQLQzk4X909YKm0lnW4hpuQg4zHwJ4XBd5bZiXcd9urvrJNoNVKnxGHPiDVX/GiLFvr5DMYsDBQbZCypRQ==} + '@opentelemetry/sdk-logs@0.214.0': + resolution: {integrity: sha512-zf6acnScjhsaBUU22zXZ/sLWim1dfhUAbGXdMmHmNG3LfBnQ3DKsOCITb2IZwoUsNNMTogqFKBnlIPPftUgGwA==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': '>=1.4.0 <1.10.0' - '@opentelemetry/sdk-metrics@2.0.1': - resolution: {integrity: sha512-wf8OaJoSnujMAHWR3g+/hGvNcsC16rf9s1So4JlMiFaFHiE4HpIA3oUh+uWZQ7CNuK8gVW/pQSkgoa5HkkOl0g==} + '@opentelemetry/sdk-metrics@2.6.1': + resolution: {integrity: sha512-9t9hJHX15meBy2NmTJxL+NJfXmnausR2xUDvE19XQce0Qi/GBtDGamU8nS1RMbdgDmhgpm3VaOu2+fiS/SfTpQ==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': '>=1.9.0 <1.10.0' - '@opentelemetry/sdk-trace-base@2.0.1': - resolution: {integrity: sha512-xYLlvk/xdScGx1aEqvxLwf6sXQLXCjk3/1SQT9X9AoN5rXRhkdvIFShuNNmtTEPRBqcsMbS4p/gJLNI2wXaDuQ==} + '@opentelemetry/sdk-trace-base@2.6.1': + resolution: {integrity: sha512-r86ut4T1e8vNwB35CqCcKd45yzqH6/6Wzvpk2/cZB8PsPLlZFTvrh8yfOS3CYZYcUmAx4hHTZJ8AO8Dj8nrdhw==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': '>=1.3.0 <1.10.0' - '@opentelemetry/sdk-trace-node@2.0.1': - resolution: {integrity: sha512-UhdbPF19pMpBtCWYP5lHbTogLWx9N0EBxtdagvkn5YtsAnCBZzL7SjktG+ZmupRgifsHMjwUaCCaVmqGfSADmA==} + '@opentelemetry/sdk-trace-node@2.6.1': + resolution: {integrity: sha512-Hh2i4FwHWRFhnO2Q/p6svMxy8MPsNCG0uuzUY3glqm0rwM0nQvbTO1dXSp9OqQoTKXcQzaz9q1f65fsurmOhNw==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': '>=1.0.0 <1.10.0' - '@opentelemetry/semantic-conventions@1.34.0': - resolution: {integrity: sha512-aKcOkyrorBGlajjRdVoJWHTxfxO1vCNHLJVlSDaRHDIdjU+pX8IYQPvPDkYiujKLbRnWU+1TBwEt0QRgSm4SGA==} + '@opentelemetry/semantic-conventions@1.40.0': + resolution: {integrity: sha512-cifvXDhcqMwwTlTK04GBNeIe7yyo28Mfby85QXFe1Yk8nmi36Ab/5UQwptOx84SsoGNRg+EVSjwzfSZMy6pmlw==} engines: {node: '>=14'} '@protobufjs/aspromise@1.1.2': @@ -164,8 +164,8 @@ packages: '@protobufjs/base64@1.1.2': resolution: {integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==} - '@protobufjs/codegen@2.0.4': - resolution: {integrity: sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==} + '@protobufjs/codegen@2.0.5': + resolution: {integrity: sha512-zgXFLzW3Ap33e6d0Wlj4MGIm6Ce8O89n/apUaGNB/jx+hw+ruWEp7EwGUshdLKVRCxZW12fp9r40E1mQrf/34g==} '@protobufjs/eventemitter@1.1.0': resolution: {integrity: sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==} @@ -176,8 +176,8 @@ packages: '@protobufjs/float@1.0.2': resolution: {integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==} - '@protobufjs/inquire@1.1.0': - resolution: {integrity: sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==} + '@protobufjs/inquire@1.1.1': + resolution: {integrity: sha512-mnzgDV26ueAvk7rsbt9L7bE0SuAoqyuys/sMMrmVcN5x9VsxpcG3rqAUSgDyLp0UZlmNfIbQ4fHfCtreVBk8Ew==} '@protobufjs/path@1.1.2': resolution: {integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==} @@ -185,8 +185,8 @@ packages: '@protobufjs/pool@1.1.0': resolution: {integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==} - '@protobufjs/utf8@1.1.0': - resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==} + '@protobufjs/utf8@1.1.1': + resolution: {integrity: sha512-oOAWABowe8EAbMyWKM0tYDKi8Yaox52D+HWZhAIJqQXbqe0xI/GV7FhLWqlEKreMkfDjshR5FKgi3mnle0h6Eg==} '@redocly/ajv@8.11.2': resolution: {integrity: sha512-io1JpnwtIcvojV7QKDUSIuMN/ikdOUd1ReEnUnMKGfDVridQZ31J0MmIuqwuRjWDZfmvr+Q0MqCcfHM2gTivOg==} @@ -197,8 +197,8 @@ packages: '@redocly/cli-otel@0.1.2': resolution: {integrity: sha512-Bg7BoO5t1x3lVK+KhA5aGPmeXpQmdf6WtTYHhelKJCsQ+tRMiJoFAQoKHoBHAoNxXrhlS3K9lKFLHGmtxsFQfA==} - '@redocly/cli@2.29.1': - resolution: {integrity: sha512-n85tU21emkYc1k7IZhOFqIrEQizvQuHzHMOwcMZ503XNhzf9OYLLQ8AEcQl1hjpUGtJWsMeSJbpuEwewgb4T0Q==} + '@redocly/cli@2.30.1': + resolution: {integrity: sha512-n5lRNAuA5Sz+pFn6VKhngUlj3E6bR0NtUF3eWzsuVWc3ffu5TyLhD12xRcASyi+aW7Z1z33/leGwIvKRKeG3xg==} engines: {node: '>=22.12.0 || >=20.19.0 <21.0.0', npm: '>=10'} hasBin: true @@ -208,16 +208,16 @@ packages: '@redocly/config@0.48.1': resolution: {integrity: sha512-vq8GM3e0KiglqkwE5Lb9XayrmZY4dHCs21BsvV92yAZN68f1N9cZUuwY1SwnztPbH06dn9uLzubBl/JNfImqfA==} - '@redocly/openapi-core@1.34.12': - resolution: {integrity: sha512-b32XWsz6enN6K4bx8xWsqUaXTJR/DnYT3lL1CzDYzIYKw243NNlz6fexmr71q/U4HrEcMoJGBvwAfcxOb8ymQw==} + '@redocly/openapi-core@1.34.13': + resolution: {integrity: sha512-4Tm4ysZkexx6ZTX7knqSZTqPlNgIvXc7Ha0pd30I694/GD0KtJE2xrElycfPds0vCLFAqoKyIzBtOF1xrLo8KA==} engines: {node: '>=18.17.0', npm: '>=9.5.0'} - '@redocly/openapi-core@2.29.1': - resolution: {integrity: sha512-T9FeS2+lpXR9V/XHqiJ53uGjoF1Hs80nRA9ACEXpTLF9a4jzzSANO92/f9HKuQvl0bHgyaIbP5OsBgVU3EP1KQ==} + '@redocly/openapi-core@2.30.1': + resolution: {integrity: sha512-ggv0nRy9Y7D1PxsmXE8MWU/x6EOVC/njZw1s7Z5TVt7OzHzLUiB2AroZzsU1dIMl2KRm4n3ygdo2VlNAAovyGQ==} engines: {node: '>=22.12.0 || >=20.19.0 <21.0.0', npm: '>=10'} - '@redocly/respect-core@2.29.1': - resolution: {integrity: sha512-TklpmSho4nSp2ySXWRUJlFQaHoN4BtSTTWabzQPetblAJ6KRVZtgFk6x8eD8KwWUaJj8c7ed4/KAIHOqTdNVxg==} + '@redocly/respect-core@2.30.1': + resolution: {integrity: sha512-b3IiUa+oFcUppfUNcNubyKJ1/Gnt8brlU2+MrF0E+tpFJANMLXejQ0DcNN7t6lq2ZgCyp9DDK76tlJMmOIIcAQ==} engines: {node: '>=22.12.0 || >=20.19.0 <21.0.0', npm: '>=10'} '@tsconfig/node10@1.0.12': @@ -238,8 +238,8 @@ packages: '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - '@types/node@24.10.15': - resolution: {integrity: sha512-BgjLoRuSr0MTI5wA6gMw9Xy0sFudAaUuvrnjgGx9wZ522fYYLA5SYJ+1Y30vTcJEG+DRCyDHx/gzQVfofYzSdg==} + '@types/node@25.6.0': + resolution: {integrity: sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ==} '@types/stylis@4.2.7': resolution: {integrity: sha512-VgDNokpBoKF+wrdvhAAfS55OMQpL6QRglwTwNC3kIgBrzZxA4WsFj+2eLfEA/uMUDzBcEhYmjSbwQakn/i3ajA==} @@ -247,10 +247,6 @@ packages: '@types/trusted-types@2.0.7': resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} - abort-controller@3.0.0: - resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} - engines: {node: '>=6.5'} - acorn-walk@8.3.5: resolution: {integrity: sha512-HEHNfbars9v4pgpW6SO1KSPkfoS0xVOM/9UzkJltjlsHZmJasxg8aXkuZa7SMf8vKGIBhpUsPluQSqhJFCqebw==} engines: {node: '>=0.4.0'} @@ -437,10 +433,6 @@ packages: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} - event-target-shim@5.0.1: - resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} - engines: {node: '>=6'} - eventemitter3@5.0.4: resolution: {integrity: sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==} @@ -456,8 +448,8 @@ packages: fast-xml-builder@1.1.5: resolution: {integrity: sha512-4TJn/8FKLeslLAH3dnohXqE3QSoxkhvaMzepOIZytwJXZO69Bfz0HBdDHzOTOon6G59Zrk6VQ2bEiv1t61rfkA==} - fast-xml-parser@5.7.1: - resolution: {integrity: sha512-8Cc3f8GUGUULg34pBch/KGyPLglS+OFs05deyOlY7fL2MTagYPKrVQNmR1fLF/yJ9PH5ZSTd3YDF6pnmeZU+zA==} + fast-xml-parser@5.7.2: + resolution: {integrity: sha512-P7oW7tLbYnhOLQk/Gv7cZgzgMPP/XN03K02/Jy6Y/NHzyIAIpxuZIM/YqAkfiXFPxA2CTm7NtCijK9EDu09u2w==} hasBin: true foreach@2.0.6: @@ -711,8 +703,8 @@ packages: prop-types@15.8.1: resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} - protobufjs@7.5.5: - resolution: {integrity: sha512-3wY1AxV+VBNW8Yypfd1yQY9pXnqTAN+KwQxL8iYm3/BjKYMNg4i0owhEe26PWDOMaIrzeeF98Lqd5NGz4omiIg==} + protobufjs@7.5.6: + resolution: {integrity: sha512-M71sTMB146U3u0di3yup8iM+zv8yPRNQVr1KK4tyBitl3qFvEGucq/rGDRShD2rsJhtN02RJaJ7j5X5hmy8SJg==} engines: {node: '>=12.0.0'} queue-microtask@1.2.3: @@ -877,8 +869,8 @@ packages: tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} - typescript@5.9.3: - resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} + typescript@6.0.3: + resolution: {integrity: sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==} engines: {node: '>=14.17'} hasBin: true @@ -895,15 +887,15 @@ packages: resolution: {integrity: sha512-yu26mwteFYzBAot7KVMqFGCVpsF6g8wXfJzQUHvu1no3+rRRSFcSV2nKeYvNPLD2J4b08jYBDhHUjeH0ygIl9w==} hasBin: true - undici-types@7.16.0: - resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} + undici-types@7.19.2: + resolution: {integrity: sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg==} undici@6.24.0: resolution: {integrity: sha512-lVLNosgqo5EkGqh5XUDhGfsMSoO8K0BAN0TyJLvwNRSl4xWGZlCVYsAIpa/OpA3TvmnM01GWcoKmc3ZWo5wKKA==} engines: {node: '>=18.17'} - undici@7.22.0: - resolution: {integrity: sha512-RqslV2Us5BrllB+JeiZnK4peryVTndy9Dnqq62S3yYRRTj0tFQCwEniUy2167skdGOy3vqRzEvl1Dm4sV2ReDg==} + undici@7.25.0: + resolution: {integrity: sha512-xXnp4kTyor2Zq+J1FfPI6Eq3ew5h6Vl0F/8d9XU5zZQf1tX9s2Su1/3PiMmUANFULpmksxkClamIZcaUqryHsQ==} engines: {node: '>=20.18.1'} uri-js-replace@1.0.1: @@ -1023,104 +1015,105 @@ snapshots: '@nodable/entities@2.1.0': {} - '@opentelemetry/api-logs@0.202.0': + '@opentelemetry/api-logs@0.214.0': dependencies: '@opentelemetry/api': 1.9.1 '@opentelemetry/api@1.9.1': {} - '@opentelemetry/context-async-hooks@2.0.1(@opentelemetry/api@1.9.1)': + '@opentelemetry/context-async-hooks@2.6.1(@opentelemetry/api@1.9.1)': dependencies: '@opentelemetry/api': 1.9.1 - '@opentelemetry/core@2.0.1(@opentelemetry/api@1.9.1)': + '@opentelemetry/core@2.6.1(@opentelemetry/api@1.9.1)': dependencies: '@opentelemetry/api': 1.9.1 - '@opentelemetry/semantic-conventions': 1.34.0 + '@opentelemetry/semantic-conventions': 1.40.0 - '@opentelemetry/exporter-trace-otlp-http@0.202.0(@opentelemetry/api@1.9.1)': + '@opentelemetry/exporter-trace-otlp-http@0.214.0(@opentelemetry/api@1.9.1)': dependencies: '@opentelemetry/api': 1.9.1 - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.1) - '@opentelemetry/otlp-exporter-base': 0.202.0(@opentelemetry/api@1.9.1) - '@opentelemetry/otlp-transformer': 0.202.0(@opentelemetry/api@1.9.1) - '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.1) - '@opentelemetry/sdk-trace-base': 2.0.1(@opentelemetry/api@1.9.1) + '@opentelemetry/core': 2.6.1(@opentelemetry/api@1.9.1) + '@opentelemetry/otlp-exporter-base': 0.214.0(@opentelemetry/api@1.9.1) + '@opentelemetry/otlp-transformer': 0.214.0(@opentelemetry/api@1.9.1) + '@opentelemetry/resources': 2.6.1(@opentelemetry/api@1.9.1) + '@opentelemetry/sdk-trace-base': 2.6.1(@opentelemetry/api@1.9.1) - '@opentelemetry/otlp-exporter-base@0.202.0(@opentelemetry/api@1.9.1)': + '@opentelemetry/otlp-exporter-base@0.214.0(@opentelemetry/api@1.9.1)': dependencies: '@opentelemetry/api': 1.9.1 - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.1) - '@opentelemetry/otlp-transformer': 0.202.0(@opentelemetry/api@1.9.1) + '@opentelemetry/core': 2.6.1(@opentelemetry/api@1.9.1) + '@opentelemetry/otlp-transformer': 0.214.0(@opentelemetry/api@1.9.1) - '@opentelemetry/otlp-transformer@0.202.0(@opentelemetry/api@1.9.1)': + '@opentelemetry/otlp-transformer@0.214.0(@opentelemetry/api@1.9.1)': dependencies: '@opentelemetry/api': 1.9.1 - '@opentelemetry/api-logs': 0.202.0 - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.1) - '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.1) - '@opentelemetry/sdk-logs': 0.202.0(@opentelemetry/api@1.9.1) - '@opentelemetry/sdk-metrics': 2.0.1(@opentelemetry/api@1.9.1) - '@opentelemetry/sdk-trace-base': 2.0.1(@opentelemetry/api@1.9.1) - protobufjs: 7.5.5 + '@opentelemetry/api-logs': 0.214.0 + '@opentelemetry/core': 2.6.1(@opentelemetry/api@1.9.1) + '@opentelemetry/resources': 2.6.1(@opentelemetry/api@1.9.1) + '@opentelemetry/sdk-logs': 0.214.0(@opentelemetry/api@1.9.1) + '@opentelemetry/sdk-metrics': 2.6.1(@opentelemetry/api@1.9.1) + '@opentelemetry/sdk-trace-base': 2.6.1(@opentelemetry/api@1.9.1) + protobufjs: 7.5.6 - '@opentelemetry/resources@2.0.1(@opentelemetry/api@1.9.1)': + '@opentelemetry/resources@2.6.1(@opentelemetry/api@1.9.1)': dependencies: '@opentelemetry/api': 1.9.1 - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.34.0 + '@opentelemetry/core': 2.6.1(@opentelemetry/api@1.9.1) + '@opentelemetry/semantic-conventions': 1.40.0 - '@opentelemetry/sdk-logs@0.202.0(@opentelemetry/api@1.9.1)': + '@opentelemetry/sdk-logs@0.214.0(@opentelemetry/api@1.9.1)': dependencies: '@opentelemetry/api': 1.9.1 - '@opentelemetry/api-logs': 0.202.0 - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.1) - '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.1) + '@opentelemetry/api-logs': 0.214.0 + '@opentelemetry/core': 2.6.1(@opentelemetry/api@1.9.1) + '@opentelemetry/resources': 2.6.1(@opentelemetry/api@1.9.1) + '@opentelemetry/semantic-conventions': 1.40.0 - '@opentelemetry/sdk-metrics@2.0.1(@opentelemetry/api@1.9.1)': + '@opentelemetry/sdk-metrics@2.6.1(@opentelemetry/api@1.9.1)': dependencies: '@opentelemetry/api': 1.9.1 - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.1) - '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.1) + '@opentelemetry/core': 2.6.1(@opentelemetry/api@1.9.1) + '@opentelemetry/resources': 2.6.1(@opentelemetry/api@1.9.1) - '@opentelemetry/sdk-trace-base@2.0.1(@opentelemetry/api@1.9.1)': + '@opentelemetry/sdk-trace-base@2.6.1(@opentelemetry/api@1.9.1)': dependencies: '@opentelemetry/api': 1.9.1 - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.1) - '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.34.0 + '@opentelemetry/core': 2.6.1(@opentelemetry/api@1.9.1) + '@opentelemetry/resources': 2.6.1(@opentelemetry/api@1.9.1) + '@opentelemetry/semantic-conventions': 1.40.0 - '@opentelemetry/sdk-trace-node@2.0.1(@opentelemetry/api@1.9.1)': + '@opentelemetry/sdk-trace-node@2.6.1(@opentelemetry/api@1.9.1)': dependencies: '@opentelemetry/api': 1.9.1 - '@opentelemetry/context-async-hooks': 2.0.1(@opentelemetry/api@1.9.1) - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.1) - '@opentelemetry/sdk-trace-base': 2.0.1(@opentelemetry/api@1.9.1) + '@opentelemetry/context-async-hooks': 2.6.1(@opentelemetry/api@1.9.1) + '@opentelemetry/core': 2.6.1(@opentelemetry/api@1.9.1) + '@opentelemetry/sdk-trace-base': 2.6.1(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions@1.34.0': {} + '@opentelemetry/semantic-conventions@1.40.0': {} '@protobufjs/aspromise@1.1.2': {} '@protobufjs/base64@1.1.2': {} - '@protobufjs/codegen@2.0.4': {} + '@protobufjs/codegen@2.0.5': {} '@protobufjs/eventemitter@1.1.0': {} '@protobufjs/fetch@1.1.0': dependencies: '@protobufjs/aspromise': 1.1.2 - '@protobufjs/inquire': 1.1.0 + '@protobufjs/inquire': 1.1.1 '@protobufjs/float@1.0.2': {} - '@protobufjs/inquire@1.1.0': {} + '@protobufjs/inquire@1.1.1': {} '@protobufjs/path@1.1.2': {} '@protobufjs/pool@1.1.0': {} - '@protobufjs/utf8@1.1.0': {} + '@protobufjs/utf8@1.1.1': {} '@redocly/ajv@8.11.2': dependencies: @@ -1140,16 +1133,15 @@ snapshots: dependencies: ulid: 2.4.0 - '@redocly/cli@2.29.1(@opentelemetry/api@1.9.1)(core-js@3.45.1)': + '@redocly/cli@2.30.1(@opentelemetry/api@1.9.1)(core-js@3.45.1)': dependencies: - '@opentelemetry/exporter-trace-otlp-http': 0.202.0(@opentelemetry/api@1.9.1) - '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.1) - '@opentelemetry/sdk-trace-node': 2.0.1(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.34.0 + '@opentelemetry/exporter-trace-otlp-http': 0.214.0(@opentelemetry/api@1.9.1) + '@opentelemetry/resources': 2.6.1(@opentelemetry/api@1.9.1) + '@opentelemetry/sdk-trace-node': 2.6.1(@opentelemetry/api@1.9.1) + '@opentelemetry/semantic-conventions': 1.40.0 '@redocly/cli-otel': 0.1.2 - '@redocly/openapi-core': 2.29.1 - '@redocly/respect-core': 2.29.1 - abort-controller: 3.0.0 + '@redocly/openapi-core': 2.30.1 + '@redocly/respect-core': 2.30.1 ajv: '@redocly/ajv@8.18.0' ajv-formats: 3.0.1(@redocly/ajv@8.18.0) colorette: 1.4.0 @@ -1186,7 +1178,7 @@ snapshots: dependencies: json-schema-to-ts: 2.7.2 - '@redocly/openapi-core@1.34.12': + '@redocly/openapi-core@1.34.13': dependencies: '@redocly/ajv': 8.11.2 '@redocly/config': 0.22.0 @@ -1200,7 +1192,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@redocly/openapi-core@2.29.1': + '@redocly/openapi-core@2.30.1': dependencies: '@redocly/ajv': 8.18.0 '@redocly/config': 0.48.1 @@ -1213,12 +1205,12 @@ snapshots: pluralize: 8.0.0 yaml-ast-parser: 0.0.43 - '@redocly/respect-core@2.29.1': + '@redocly/respect-core@2.30.1': dependencies: '@faker-js/faker': 7.6.0 '@noble/hashes': 1.8.0 '@redocly/ajv': 8.18.0 - '@redocly/openapi-core': 2.29.1 + '@redocly/openapi-core': 2.30.1 ajv: '@redocly/ajv@8.18.0' better-ajv-errors: 1.2.0(@redocly/ajv@8.18.0) colorette: 2.0.20 @@ -1240,19 +1232,15 @@ snapshots: '@types/json-schema@7.0.15': {} - '@types/node@24.10.15': + '@types/node@25.6.0': dependencies: - undici-types: 7.16.0 + undici-types: 7.19.2 '@types/stylis@4.2.7': {} '@types/trusted-types@2.0.7': optional: true - abort-controller@3.0.0: - dependencies: - event-target-shim: 5.0.1 - acorn-walk@8.3.5: dependencies: acorn: 8.16.0 @@ -1327,7 +1315,7 @@ snapshots: parse5: 7.3.0 parse5-htmlparser2-tree-adapter: 7.1.0 parse5-parser-stream: 7.1.2 - undici: 7.22.0 + undici: 7.25.0 whatwg-mimetype: 4.0.0 classnames@2.5.1: {} @@ -1425,8 +1413,6 @@ snapshots: escalade@3.2.0: {} - event-target-shim@5.0.1: {} - eventemitter3@5.0.4: {} fast-deep-equal@3.1.3: {} @@ -1439,7 +1425,7 @@ snapshots: dependencies: path-expression-matcher: 1.5.0 - fast-xml-parser@5.7.1: + fast-xml-parser@5.7.2: dependencies: '@nodable/entities': 2.1.0 fast-xml-builder: 1.1.5 @@ -1621,7 +1607,7 @@ snapshots: openapi-sampler@1.7.2: dependencies: '@types/json-schema': 7.0.15 - fast-xml-parser: 5.7.1 + fast-xml-parser: 5.7.2 json-pointer: 0.6.2 outdent@0.8.0: {} @@ -1676,19 +1662,19 @@ snapshots: object-assign: 4.1.1 react-is: 16.13.1 - protobufjs@7.5.5: + protobufjs@7.5.6: dependencies: '@protobufjs/aspromise': 1.1.2 '@protobufjs/base64': 1.1.2 - '@protobufjs/codegen': 2.0.4 + '@protobufjs/codegen': 2.0.5 '@protobufjs/eventemitter': 1.1.0 '@protobufjs/fetch': 1.1.0 '@protobufjs/float': 1.0.2 - '@protobufjs/inquire': 1.1.0 + '@protobufjs/inquire': 1.1.1 '@protobufjs/path': 1.1.2 '@protobufjs/pool': 1.1.0 - '@protobufjs/utf8': 1.1.0 - '@types/node': 24.10.15 + '@protobufjs/utf8': 1.1.1 + '@types/node': 25.6.0 long: 5.3.2 queue-microtask@1.2.3: {} @@ -1720,7 +1706,7 @@ snapshots: redoc@2.5.1(core-js@3.45.1)(mobx@6.15.0)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(styled-components@6.3.9(react-dom@19.2.5(react@19.2.5))(react@19.2.5)): dependencies: - '@redocly/openapi-core': 1.34.12 + '@redocly/openapi-core': 1.34.13 classnames: 2.5.1 core-js: 3.45.1 decko: 1.2.0 @@ -1872,27 +1858,27 @@ snapshots: ts-algebra@1.2.2: {} - ts-node@10.9.2(@types/node@24.10.15)(typescript@5.9.3): + ts-node@10.9.2(@types/node@25.6.0)(typescript@6.0.3): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.12 '@tsconfig/node12': 1.0.11 '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 - '@types/node': 24.10.15 + '@types/node': 25.6.0 acorn: 8.16.0 acorn-walk: 8.3.5 arg: 4.1.3 create-require: 1.1.1 diff: 4.0.4 make-error: 1.3.6 - typescript: 5.9.3 + typescript: 6.0.3 v8-compile-cache-lib: 3.0.1 yn: 3.1.1 tslib@2.8.1: {} - typescript@5.9.3: {} + typescript@6.0.3: {} uglify-js@3.19.3: optional: true @@ -1901,11 +1887,11 @@ snapshots: ulid@3.0.2: {} - undici-types@7.16.0: {} + undici-types@7.19.2: {} undici@6.24.0: {} - undici@7.22.0: {} + undici@7.25.0: {} uri-js-replace@1.0.1: {}