groupware: omit "position" when "anchor" is specified in queries

* the "position" attribute is always set to 0 when using an anchor for
   pagination, but it does not accurately reflect the position and thus
   we decided to remove the attribute from the resulting object for
   clarity

 * omit "canCalculateChanges" attribute when its value is "true", which
   is going to be the case in 100% of calls against Stalwart
This commit is contained in:
Pascal Bleser
2026-04-28 11:10:37 +02:00
parent b63b0b3f28
commit 91e2705bb1
15 changed files with 373 additions and 268 deletions

View File

@@ -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),
}

View File

@@ -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,
}
}

View File

@@ -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),
}

View File

@@ -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),
}

View File

@@ -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)
}
{

View File

@@ -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{

View File

@@ -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"`

View File

@@ -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,
}
}

View File

@@ -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

View File

@@ -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(`<link rel="icon" href="data:image/png;base64,${favicon}">`);
process.stdout.write($.html() + "\n");
} catch (e) {
console.error(`Error occurred while post-processing HTML: ${e.message}`);
process.exit(1);
}
}
run();

View File

@@ -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(`<link rel="icon" href="data:image/png;base64,${favicon}">`)
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")
}
}
});

View File

@@ -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"
}
}

View File

@@ -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

View File

@@ -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)
})

View File

@@ -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: {}