Compare commits

...

6 Commits

Author SHA1 Message Date
Armando Ruocco
b23e1c2cba
Merge 6a55a361a3 into 3958ee4805 2026-09-02 13:35:13 +08:00
renovate[bot]
3958ee4805
chore(deps): lock file maintenance (#1089)
Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-09-01 09:46:28 +02:00
renovate[bot]
e7905b9da9
chore(deps): update dependency serialize-javascript to v7.1.1 (#1040)
Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-09-01 09:31:43 +02:00
Marco Nenciarini
cd71e7d5fd
docs(web): use active doc version for install manifest link (#1074)
The install snippet always linked to the manifest of the latest released
version, regardless of which versioned docs page it was rendered on.
Viewing the 0.13.0 installation page therefore pointed at the 0.14.0
manifest.

Build the manifest URL from the active doc version directly: each
versioned page links its own release tag, and the unreleased "current"
docs link the manifest built off `main` instead of a (nonexistent)
release tag.

---------

Signed-off-by: Marco Nenciarini <marco.nenciarini@enterprisedb.com>
Signed-off-by: Danish <danish.khan@enterprisedb.com>
Co-authored-by: Danish <danish.khan@enterprisedb.com>
2026-08-31 11:14:07 +02:00
Marco Nenciarini
6a55a361a3 test: replace sleep-based test with deterministic channel verification
The cleanup routine test used time.Sleep() without actually verifying
the goroutine stopped. Added a done channel to provide deterministic
verification of goroutine termination.

Signed-off-by: Marco Nenciarini <marco.nenciarini@enterprisedb.com>
2025-12-23 17:06:00 +01:00
Armando Ruocco
62b579101f fix: prevent memory leak by periodically cleaning up expired cache entries
Signed-off-by: Armando Ruocco <armando.ruocco@enterprisedb.com>
2025-12-23 17:06:00 +01:00
9 changed files with 361 additions and 159 deletions

View File

@ -36,6 +36,9 @@ import (
// DefaultTTLSeconds is the default TTL in seconds of cache entries // DefaultTTLSeconds is the default TTL in seconds of cache entries
const DefaultTTLSeconds = 10 const DefaultTTLSeconds = 10
// DefaultCleanupIntervalSeconds is the default interval in seconds for cache cleanup
const DefaultCleanupIntervalSeconds = 30
type cachedEntry struct { type cachedEntry struct {
entry client.Object entry client.Object
fetchUnixTime int64 fetchUnixTime int64
@ -49,18 +52,30 @@ func (e *cachedEntry) isExpired() bool {
// ExtendedClient is an extended client that is capable of caching multiple secrets without relying on informers // ExtendedClient is an extended client that is capable of caching multiple secrets without relying on informers
type ExtendedClient struct { type ExtendedClient struct {
client.Client client.Client
cachedObjects []cachedEntry cachedObjects []cachedEntry
mux *sync.Mutex mux *sync.Mutex
cleanupInterval time.Duration
cleanupDone chan struct{} // Signals when cleanup routine exits
} }
// NewExtendedClient returns an extended client capable of caching secrets on the 'Get' operation // NewExtendedClient returns an extended client capable of caching secrets on the 'Get' operation.
// It starts a background goroutine that periodically cleans up expired cache entries.
// The cleanup routine will stop when the provided context is cancelled.
func NewExtendedClient( func NewExtendedClient(
ctx context.Context,
baseClient client.Client, baseClient client.Client,
) client.Client { ) client.Client {
return &ExtendedClient{ ec := &ExtendedClient{
Client: baseClient, Client: baseClient,
mux: &sync.Mutex{}, mux: &sync.Mutex{},
cleanupInterval: DefaultCleanupIntervalSeconds * time.Second,
cleanupDone: make(chan struct{}),
} }
// Start the background cleanup routine
go ec.startCleanupRoutine(ctx)
return ec
} }
func (e *ExtendedClient) isObjectCached(obj client.Object) bool { func (e *ExtendedClient) isObjectCached(obj client.Object) bool {
@ -208,3 +223,55 @@ func (e *ExtendedClient) Patch(
return e.Client.Patch(ctx, obj, patch, opts...) return e.Client.Patch(ctx, obj, patch, opts...)
} }
// startCleanupRoutine periodically removes expired entries from the cache.
// It runs until the context is cancelled.
func (e *ExtendedClient) startCleanupRoutine(ctx context.Context) {
defer close(e.cleanupDone)
contextLogger := log.FromContext(ctx).WithName("extended_client_cleanup")
ticker := time.NewTicker(e.cleanupInterval)
defer ticker.Stop()
for {
select {
case <-ctx.Done():
contextLogger.Debug("stopping cache cleanup routine")
return
case <-ticker.C:
// Check context before cleanup to avoid unnecessary work during shutdown
if ctx.Err() != nil {
return
}
e.cleanupExpiredEntries(ctx)
}
}
}
// cleanupExpiredEntries removes all expired entries from the cache.
func (e *ExtendedClient) cleanupExpiredEntries(ctx context.Context) {
contextLogger := log.FromContext(ctx).WithName("extended_client_cleanup")
e.mux.Lock()
defer e.mux.Unlock()
initialCount := len(e.cachedObjects)
if initialCount == 0 {
return
}
// Create a new slice with only non-expired entries
validEntries := make([]cachedEntry, 0, initialCount)
for _, entry := range e.cachedObjects {
if !entry.isExpired() {
validEntries = append(validEntries, entry)
}
}
removedCount := initialCount - len(validEntries)
if removedCount > 0 {
e.cachedObjects = validEntries
contextLogger.Debug("cleaned up expired cache entries",
"removedCount", removedCount,
"remainingCount", len(validEntries))
}
}

View File

@ -20,6 +20,7 @@ SPDX-License-Identifier: Apache-2.0
package client package client
import ( import (
"context"
"time" "time"
corev1 "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1"
@ -59,6 +60,7 @@ var _ = Describe("ExtendedClient Get", func() {
extendedClient *ExtendedClient extendedClient *ExtendedClient
secretInClient *corev1.Secret secretInClient *corev1.Secret
objectStore *barmancloudv1.ObjectStore objectStore *barmancloudv1.ObjectStore
cancelCtx context.CancelFunc
) )
BeforeEach(func() { BeforeEach(func() {
@ -79,7 +81,14 @@ var _ = Describe("ExtendedClient Get", func() {
baseClient := fake.NewClientBuilder(). baseClient := fake.NewClientBuilder().
WithScheme(scheme). WithScheme(scheme).
WithObjects(secretInClient, objectStore).Build() WithObjects(secretInClient, objectStore).Build()
extendedClient = NewExtendedClient(baseClient).(*ExtendedClient) ctx, cancel := context.WithCancel(context.Background())
cancelCtx = cancel
extendedClient = NewExtendedClient(ctx, baseClient).(*ExtendedClient)
})
AfterEach(func() {
// Cancel the context to stop the cleanup routine
cancelCtx()
}) })
It("returns secret from cache if not expired", func(ctx SpecContext) { It("returns secret from cache if not expired", func(ctx SpecContext) {
@ -164,3 +173,141 @@ var _ = Describe("ExtendedClient Get", func() {
Expect(objectStore.GetResourceVersion()).To(Equal("from cache")) Expect(objectStore.GetResourceVersion()).To(Equal("from cache"))
}) })
}) })
var _ = Describe("ExtendedClient Cache Cleanup", func() {
var (
extendedClient *ExtendedClient
cancelCtx context.CancelFunc
)
BeforeEach(func() {
baseClient := fake.NewClientBuilder().
WithScheme(scheme).
Build()
ctx, cancel := context.WithCancel(context.Background())
cancelCtx = cancel
extendedClient = NewExtendedClient(ctx, baseClient).(*ExtendedClient)
})
AfterEach(func() {
cancelCtx()
})
It("cleans up expired entries", func(ctx SpecContext) {
// Add some expired entries
expiredSecret1 := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Namespace: "default",
Name: "expired-secret-1",
},
}
expiredSecret2 := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Namespace: "default",
Name: "expired-secret-2",
},
}
validSecret := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Namespace: "default",
Name: "valid-secret",
},
}
// Add expired entries (2 minutes ago)
addToCache(extendedClient, expiredSecret1, time.Now().Add(-2*time.Minute).Unix())
addToCache(extendedClient, expiredSecret2, time.Now().Add(-2*time.Minute).Unix())
// Add valid entry (just now)
addToCache(extendedClient, validSecret, time.Now().Unix())
Expect(extendedClient.cachedObjects).To(HaveLen(3))
// Trigger cleanup
extendedClient.cleanupExpiredEntries(ctx)
// Only the valid entry should remain
Expect(extendedClient.cachedObjects).To(HaveLen(1))
Expect(extendedClient.cachedObjects[0].entry.GetName()).To(Equal("valid-secret"))
})
It("does nothing when all entries are valid", func(ctx SpecContext) {
validSecret1 := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Namespace: "default",
Name: "valid-secret-1",
},
}
validSecret2 := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Namespace: "default",
Name: "valid-secret-2",
},
}
addToCache(extendedClient, validSecret1, time.Now().Unix())
addToCache(extendedClient, validSecret2, time.Now().Unix())
Expect(extendedClient.cachedObjects).To(HaveLen(2))
// Trigger cleanup
extendedClient.cleanupExpiredEntries(ctx)
// Both entries should remain
Expect(extendedClient.cachedObjects).To(HaveLen(2))
})
It("does nothing when cache is empty", func(ctx SpecContext) {
Expect(extendedClient.cachedObjects).To(BeEmpty())
// Trigger cleanup
extendedClient.cleanupExpiredEntries(ctx)
Expect(extendedClient.cachedObjects).To(BeEmpty())
})
It("removes all entries when all are expired", func(ctx SpecContext) {
expiredSecret1 := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Namespace: "default",
Name: "expired-secret-1",
},
}
expiredSecret2 := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Namespace: "default",
Name: "expired-secret-2",
},
}
addToCache(extendedClient, expiredSecret1, time.Now().Add(-2*time.Minute).Unix())
addToCache(extendedClient, expiredSecret2, time.Now().Add(-2*time.Minute).Unix())
Expect(extendedClient.cachedObjects).To(HaveLen(2))
// Trigger cleanup
extendedClient.cleanupExpiredEntries(ctx)
Expect(extendedClient.cachedObjects).To(BeEmpty())
})
It("stops cleanup routine when context is cancelled", func() {
// Create a new client with a short cleanup interval for testing
baseClient := fake.NewClientBuilder().
WithScheme(scheme).
Build()
ctx, cancel := context.WithCancel(context.Background())
ec := NewExtendedClient(ctx, baseClient).(*ExtendedClient)
ec.cleanupInterval = 10 * time.Millisecond
// Cancel the context immediately
cancel()
// Verify the cleanup routine actually stops by waiting for the done channel
select {
case <-ec.cleanupDone:
// Success: cleanup routine exited as expected
case <-time.After(1 * time.Second):
Fail("cleanup routine did not stop within timeout")
}
})
})

View File

@ -80,7 +80,7 @@ func Start(ctx context.Context) error {
return err return err
} }
customCacheClient := extendedclient.NewExtendedClient(mgr.GetClient()) customCacheClient := extendedclient.NewExtendedClient(ctx, mgr.GetClient())
if err := mgr.Add(&CNPGI{ if err := mgr.Add(&CNPGI{
Client: customCacheClient, Client: customCacheClient,

View File

@ -54,10 +54,9 @@ Both checks are required before proceeding with the installation.
## Installing the Barman Cloud Plugin ## Installing the Barman Cloud Plugin
import { InstallationSnippet } from '@site/src/components/Installation'; import { InstallationSnippet, ManifestVersion } from '@site/src/components/Installation';
Install the plugin using `kubectl` by applying the manifest for the latest Install the plugin using `kubectl` by applying the manifest for <ManifestVersion />:
release:
<InstallationSnippet /> <InstallationSnippet />
@ -100,10 +99,6 @@ This confirms that the plugin is deployed and ready to use.
## Testing the latest development snapshot ## Testing the latest development snapshot
You can also test the latest development snapshot of the plugin with the import { DevSnapshotSection } from '@site/src/components/Installation';
following command:
```sh <DevSnapshotSection />
kubectl apply -f \
https://raw.githubusercontent.com/cloudnative-pg/plugin-barman-cloud/refs/heads/main/manifest.yaml
```

View File

@ -1,16 +1,55 @@
import {ReactElement} from 'react'; import {ReactElement} from 'react';
import CodeBlock from '@theme/CodeBlock'; import CodeBlock from '@theme/CodeBlock';
import {useCurrentVersion} from '@site/src/hooks/versions'; import {useActiveVersion} from '@docusaurus/plugin-content-docs/client';
// InstallationSnippet is the kubectl incantation to install the lastest // DEV_MANIFEST_URL is the URL of the manifest.yaml on the main branch of the plugin repo.
// available version of the Barman Cloud Plugin. const DEV_MANIFEST_URL =
'https://raw.githubusercontent.com/cloudnative-pg/plugin-barman-cloud/refs/heads/main/manifest.yaml';
// InstallationSnippet is the kubectl incantation to install the Barman
// Cloud Plugin: the manifest matching the doc version being viewed, or
// (on the unreleased "current" docs) the latest manifest on main.
export function InstallationSnippet(): ReactElement<null> { export function InstallationSnippet(): ReactElement<null> {
const latest = useCurrentVersion('latestReleased'); const activeVersion = useActiveVersion('default');
const url = activeVersion && activeVersion.name !== 'current'
? `https://github.com/cloudnative-pg/plugin-barman-cloud/releases/download/v${activeVersion.name}/manifest.yaml`
: DEV_MANIFEST_URL;
return ( return (
<CodeBlock language="sh"> <CodeBlock language="sh">
{`kubectl apply -f \\ {`kubectl apply -f \\
https://github.com/cloudnative-pg/plugin-barman-cloud/releases/download/v${latest}/manifest.yaml`} ${url}`}
</CodeBlock> </CodeBlock>
); );
} }
// ManifestVersion names the manifest the snippet below installs: the
// release tag for a versioned docs page, or the main branch on Dev docs.
export function ManifestVersion(): ReactElement<null> {
const activeVersion = useActiveVersion('default');
return activeVersion && activeVersion.name !== 'current'
? <code>v{activeVersion.name}</code>
: <>the latest development snapshot from the <code>main</code> branch</>;
}
// DevSnapshotSection offers the main-branch manifest as an alternative;
// on the Dev docs the main install already is that manifest, so hide it.
export function DevSnapshotSection(): ReactElement {
const activeVersion = useActiveVersion('default');
if (!activeVersion || activeVersion.name === 'current') {
return (
<p>The <a href="#installing-the-barman-cloud-plugin">install
command above</a> already applies the latest development
snapshot from the <code>main</code> branch.</p>
);
}
return (
<>
<p>You can also test the latest development snapshot of the plugin
with the following command:</p>
<CodeBlock language="sh">
{`kubectl apply -f \\
${DEV_MANIFEST_URL}`}
</CodeBlock>
</>
);
}

View File

@ -1,36 +0,0 @@
import {useActiveVersion, useLatestVersion, useVersions} from '@docusaurus/plugin-content-docs/client';
export function useCurrentVersion(fallback: 'latest' | 'latestReleased' = 'latest'): string {
switch (fallback) {
case 'latestReleased':
return useLatestReleasedVersion();
case 'latest': {
const version = useActiveVersion('default');
return version?.name ?? useLatestVersion('default')?.name;
}
default:
// The following line ensures that if `fallback` is not 'latest' or 'latestReleased',
// an error is thrown. This can be useful for catching unexpected states.
throw new Error(`Unhandled fallback type: ${fallback}`);
}
}
export function useLatestReleasedVersion(): string {
const allVersions = useVersions('default');
// Filter out "current" to only consider versioned docs
const versionedDocs = allVersions.filter(version => version.name !== 'current');
// Handle the case where no versioned documents are found
if (versionedDocs.length === 0) {
return "unknown_version";
}
const sortedVersions = versionedDocs.sort((a, b) => {
return b.name.localeCompare(a.name, undefined, { numeric: true, sensitivity: 'base' });
});
// The latest version is the first in the sorted list since versionedDocs was not empty,
return sortedVersions[0].name;
}

View File

@ -54,10 +54,9 @@ Both checks are required before proceeding with the installation.
## Installing the Barman Cloud Plugin ## Installing the Barman Cloud Plugin
import { InstallationSnippet } from '@site/src/components/Installation'; import { InstallationSnippet, ManifestVersion } from '@site/src/components/Installation';
Install the plugin using `kubectl` by applying the manifest for the latest Install the plugin using `kubectl` by applying the manifest for <ManifestVersion />:
release:
<InstallationSnippet /> <InstallationSnippet />
@ -100,10 +99,6 @@ This confirms that the plugin is deployed and ready to use.
## Testing the latest development snapshot ## Testing the latest development snapshot
You can also test the latest development snapshot of the plugin with the import { DevSnapshotSection } from '@site/src/components/Installation';
following command:
```sh <DevSnapshotSection />
kubectl apply -f \
https://raw.githubusercontent.com/cloudnative-pg/plugin-barman-cloud/refs/heads/main/manifest.yaml
```

View File

@ -54,10 +54,9 @@ Both checks are required before proceeding with the installation.
## Installing the Barman Cloud Plugin ## Installing the Barman Cloud Plugin
import { InstallationSnippet } from '@site/src/components/Installation'; import { InstallationSnippet, ManifestVersion } from '@site/src/components/Installation';
Install the plugin using `kubectl` by applying the manifest for the latest Install the plugin using `kubectl` by applying the manifest for <ManifestVersion />:
release:
<InstallationSnippet /> <InstallationSnippet />
@ -100,10 +99,6 @@ This confirms that the plugin is deployed and ready to use.
## Testing the latest development snapshot ## Testing the latest development snapshot
You can also test the latest development snapshot of the plugin with the import { DevSnapshotSection } from '@site/src/components/Installation';
following command:
```sh <DevSnapshotSection />
kubectl apply -f \
https://raw.githubusercontent.com/cloudnative-pg/plugin-barman-cloud/refs/heads/main/manifest.yaml
```

View File

@ -2099,9 +2099,9 @@
"@jridgewell/trace-mapping" "^0.3.25" "@jridgewell/trace-mapping" "^0.3.25"
"@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.5.0": "@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.5.0":
version "1.5.5" version "1.6.0"
resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz#6912b00d2c631c0d15ce1a7ab57cd657f2a8f8ba" resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.6.0.tgz#f4c663e862f06dc98ca4d453862c46902789a18d"
integrity sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og== integrity sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==
"@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25", "@jridgewell/trace-mapping@^0.3.28", "@jridgewell/trace-mapping@^0.3.31": "@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25", "@jridgewell/trace-mapping@^0.3.28", "@jridgewell/trace-mapping@^0.3.31":
version "0.3.31" version "0.3.31"
@ -2141,75 +2141,75 @@
resolved "https://registry.yarnpkg.com/@jsonjoy.com/codegen/-/codegen-1.0.0.tgz#5c23f796c47675f166d23b948cdb889184b93207" resolved "https://registry.yarnpkg.com/@jsonjoy.com/codegen/-/codegen-1.0.0.tgz#5c23f796c47675f166d23b948cdb889184b93207"
integrity sha512-E8Oy+08cmCf0EK/NMxpaJZmOxPqM+6iSe2S4nlSBrPZOORoDJILxtbSUEDKQyTamm/BVAhIGllOBNU79/dwf0g== integrity sha512-E8Oy+08cmCf0EK/NMxpaJZmOxPqM+6iSe2S4nlSBrPZOORoDJILxtbSUEDKQyTamm/BVAhIGllOBNU79/dwf0g==
"@jsonjoy.com/fs-core@4.68.1": "@jsonjoy.com/fs-core@4.68.2":
version "4.68.1" version "4.68.2"
resolved "https://registry.yarnpkg.com/@jsonjoy.com/fs-core/-/fs-core-4.68.1.tgz#15fed282af2a8efbd1a335a83ae1bd3507fa0237" resolved "https://registry.yarnpkg.com/@jsonjoy.com/fs-core/-/fs-core-4.68.2.tgz#ea3e3e3e07e0d808844ba7ee908dd47ad121eddf"
integrity sha512-V5oZ4Gt9WJKyQef0n9cAd0N9qjSkIBm3E4MYsgNIWBk5aINCDPKxMPo1i29rBxqiT4Ixf1epklqV9VJMKIxwlw== integrity sha512-PoBeUNEbjyLKKwCap2z8LkkqdhdfttS4rTHCALVuP65BdF+sAoyBqHo1m+uGTRBiQWv3H7MGfr8f7lY4pDwanw==
dependencies: dependencies:
"@jsonjoy.com/fs-node-builtins" "4.68.1" "@jsonjoy.com/fs-node-builtins" "4.68.2"
"@jsonjoy.com/fs-node-utils" "4.68.1" "@jsonjoy.com/fs-node-utils" "4.68.2"
thingies "^2.5.0" thingies "^2.5.0"
"@jsonjoy.com/fs-fsa@4.68.1": "@jsonjoy.com/fs-fsa@4.68.2":
version "4.68.1" version "4.68.2"
resolved "https://registry.yarnpkg.com/@jsonjoy.com/fs-fsa/-/fs-fsa-4.68.1.tgz#009ebc90396622d37df984691fbe8bad51fdedea" resolved "https://registry.yarnpkg.com/@jsonjoy.com/fs-fsa/-/fs-fsa-4.68.2.tgz#01d59e3bedb3cfe4b32334abbb1004a75b481a76"
integrity sha512-HCG72UioncuO7Gw09XNVG+S85e3cq2hrUC/mexBrsWsa3mI7eePkkqWie3uVYbtsb64OR9YGQs5SqaufDRYBcg== integrity sha512-h6eGXlLGGMyPfNliDQrbuHKTB9Z29ksCLjreAmdBqrDOBdfrTrHssi+b9WLfrF+J2KzAbIt9OMjJu6AEpTnYkg==
dependencies: dependencies:
"@jsonjoy.com/fs-core" "4.68.1" "@jsonjoy.com/fs-core" "4.68.2"
"@jsonjoy.com/fs-node-builtins" "4.68.1" "@jsonjoy.com/fs-node-builtins" "4.68.2"
"@jsonjoy.com/fs-node-utils" "4.68.1" "@jsonjoy.com/fs-node-utils" "4.68.2"
thingies "^2.5.0" thingies "^2.5.0"
"@jsonjoy.com/fs-node-builtins@4.68.1": "@jsonjoy.com/fs-node-builtins@4.68.2":
version "4.68.1" version "4.68.2"
resolved "https://registry.yarnpkg.com/@jsonjoy.com/fs-node-builtins/-/fs-node-builtins-4.68.1.tgz#3c4ee9877e12d76eab8611663bea127d0e261fc5" resolved "https://registry.yarnpkg.com/@jsonjoy.com/fs-node-builtins/-/fs-node-builtins-4.68.2.tgz#ef82d558a6894b54537857ba153daa38a5326a05"
integrity sha512-HK1BTksysokNZxNspqDH0yPaqN9YgR/AYIlYiIaU2Ys4BOk5CdybI7r6BgiZuiiPiV8n4sK/kZdice7Znpy2Kw== integrity sha512-V8WzQsW2YIrH3RxBGY6HZisxn+dDUltHgksVRuCdPEOXEkAfXuhL/01eHFrabNu84Dn13XuLqvcQUKOYVKAUOA==
"@jsonjoy.com/fs-node-to-fsa@4.68.1": "@jsonjoy.com/fs-node-to-fsa@4.68.2":
version "4.68.1" version "4.68.2"
resolved "https://registry.yarnpkg.com/@jsonjoy.com/fs-node-to-fsa/-/fs-node-to-fsa-4.68.1.tgz#d0dab7f007f9e01dcd1e62d2e27ec0fdd0126554" resolved "https://registry.yarnpkg.com/@jsonjoy.com/fs-node-to-fsa/-/fs-node-to-fsa-4.68.2.tgz#faf01a277752868d90681f6dcb86d3e01f05a296"
integrity sha512-lpKmU4X9e/oh8GIuAI7EXaS5QiLNM3KD15CkdhfS6PYmrGvoJqKQcyEfnLgnnaGslh/PFUMYSIZBCf2ejJGw8g== integrity sha512-4O1K4w5G4oJIpKpoa3WSLG83AsQYVnGv+aUSBGOvIUph9Axm6bB1mPlvldkNg2tBx/4dkiTlZnqNrK5SQ21Wtg==
dependencies: dependencies:
"@jsonjoy.com/fs-fsa" "4.68.1" "@jsonjoy.com/fs-fsa" "4.68.2"
"@jsonjoy.com/fs-node-builtins" "4.68.1" "@jsonjoy.com/fs-node-builtins" "4.68.2"
"@jsonjoy.com/fs-node-utils" "4.68.1" "@jsonjoy.com/fs-node-utils" "4.68.2"
"@jsonjoy.com/fs-node-utils@4.68.1": "@jsonjoy.com/fs-node-utils@4.68.2":
version "4.68.1" version "4.68.2"
resolved "https://registry.yarnpkg.com/@jsonjoy.com/fs-node-utils/-/fs-node-utils-4.68.1.tgz#25fa70c1c11986eef75c1e6c52caea9fe2e69778" resolved "https://registry.yarnpkg.com/@jsonjoy.com/fs-node-utils/-/fs-node-utils-4.68.2.tgz#78311a84df4e4edc51f8e41fc042d3eed21cb0d4"
integrity sha512-/GxfW1DWm9SCdkfbvqevLO/P5duobQfmKkHXxdMIDbcZMQeAgooAstIfZhkXpATzq9QbCQsnoWFM/dGHdZfndw== integrity sha512-CxFwyG9fJr7dAKAd1uanNRNrRMtDDqbYJA8do53+M4LY7SxcBEEmMjC1zi9MOsBlVLHTXvA7OP9+n639UqtIcw==
dependencies: dependencies:
"@jsonjoy.com/fs-node-builtins" "4.68.1" "@jsonjoy.com/fs-node-builtins" "4.68.2"
glob-to-regex.js "^1.0.1" glob-to-regex.js "^1.0.1"
"@jsonjoy.com/fs-node@4.68.1": "@jsonjoy.com/fs-node@4.68.2":
version "4.68.1" version "4.68.2"
resolved "https://registry.yarnpkg.com/@jsonjoy.com/fs-node/-/fs-node-4.68.1.tgz#0ca716e6c3ef5ed8887fbd4b4557094f99293d19" resolved "https://registry.yarnpkg.com/@jsonjoy.com/fs-node/-/fs-node-4.68.2.tgz#166b641f7c810e12cbf92c483e9c7084123ed669"
integrity sha512-R5D9mWtqdURzcOWj1vdXr3APCwX0xchtFT+kmW7fXLNDifWdDrnh26jSID8pdnUfFBxTyfHtFtTL/NWKzIH7kQ== integrity sha512-Kpj519Qk4OXG4+mZ8vTf9BEflliJrPueIDEVcbx8tAOufMJJ8IxR0WwdbcEvJol2KQog3PJjtALXVclorE+xbQ==
dependencies: dependencies:
"@jsonjoy.com/fs-core" "4.68.1" "@jsonjoy.com/fs-core" "4.68.2"
"@jsonjoy.com/fs-node-builtins" "4.68.1" "@jsonjoy.com/fs-node-builtins" "4.68.2"
"@jsonjoy.com/fs-node-utils" "4.68.1" "@jsonjoy.com/fs-node-utils" "4.68.2"
"@jsonjoy.com/fs-print" "4.68.1" "@jsonjoy.com/fs-print" "4.68.2"
"@jsonjoy.com/fs-snapshot" "4.68.1" "@jsonjoy.com/fs-snapshot" "4.68.2"
glob-to-regex.js "^1.0.0" glob-to-regex.js "^1.0.0"
thingies "^2.5.0" thingies "^2.5.0"
"@jsonjoy.com/fs-print@4.68.1": "@jsonjoy.com/fs-print@4.68.2":
version "4.68.1" version "4.68.2"
resolved "https://registry.yarnpkg.com/@jsonjoy.com/fs-print/-/fs-print-4.68.1.tgz#bd830f90764155fb131320624248d33e720d6130" resolved "https://registry.yarnpkg.com/@jsonjoy.com/fs-print/-/fs-print-4.68.2.tgz#1562c2481393359644e2840c25a5082274378f39"
integrity sha512-oGeZOGPYKK9v1CgeVeEDsLomH1lCnslSpqUN5GmPzrmAVGQlsmsdcXNA2O4lV8Y4xkuSuynx2ITBkUHJVaTbow== integrity sha512-cBABQmZJXig6bahwNka3+yPNGUF1GeMWbR76ZM1N2ajgCd+S+twZigCoe9+0ueZmkhM9xd2a7688Gy/ch7T+2w==
dependencies: dependencies:
"@jsonjoy.com/fs-node-utils" "4.68.1" "@jsonjoy.com/fs-node-utils" "4.68.2"
tree-dump "^1.1.0" tree-dump "^1.1.0"
"@jsonjoy.com/fs-snapshot@4.68.1": "@jsonjoy.com/fs-snapshot@4.68.2":
version "4.68.1" version "4.68.2"
resolved "https://registry.yarnpkg.com/@jsonjoy.com/fs-snapshot/-/fs-snapshot-4.68.1.tgz#672d82cb65dad18c3a1fcf7d22254d037e6a794a" resolved "https://registry.yarnpkg.com/@jsonjoy.com/fs-snapshot/-/fs-snapshot-4.68.2.tgz#6f1b2e5aa6827a1075f82162055ca8bedee0fe58"
integrity sha512-XZfP0FDZN32bbc4t2bZN2qRrYHg5AktJnzk22HRoKGK4BprrbNRH2k5ceSNS/kupKYcofCs+O841+xaAbjnxwQ== integrity sha512-Aix7+NM38LzvewM0T3PICSgFdF5BVCtVgsjNsrlDPGc9hiMgJzReTDDl2/elgl0A9USMl3QP27x5WwxZSOtrfw==
dependencies: dependencies:
"@jsonjoy.com/buffers" "^17.65.0" "@jsonjoy.com/buffers" "^17.65.0"
"@jsonjoy.com/fs-node-utils" "4.68.1" "@jsonjoy.com/fs-node-utils" "4.68.2"
"@jsonjoy.com/json-pack" "^17.65.0" "@jsonjoy.com/json-pack" "^17.65.0"
"@jsonjoy.com/util" "^17.65.0" "@jsonjoy.com/util" "^17.65.0"
@ -3564,9 +3564,9 @@ balanced-match@^1.0.0:
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
baseline-browser-mapping@^2.11.12: baseline-browser-mapping@^2.11.12:
version "2.11.19" version "2.11.20"
resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.11.19.tgz#4711abac48b88ccb56b5817e86f1b3a9a0764276" resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.11.20.tgz#26078c7a4b08299656ea7ddceaebec955dc44303"
integrity sha512-Grytf1xOxOEMTGRwx6rLGKkTabd4vMg3VrKdj/7joCmV0qgh4QwMMO6xh34YEXQqirAuUdgQGa5orJQQ+69RBw== integrity sha512-H0ulySigv6icDJ1F7SjtdCD6PrhTpdYCmP0CactWy1+ekh0AFd0o1Wn5T8b+hnTmdBx19u9yhL6wvCylXMY7zw==
batch@0.6.1: batch@0.6.1:
version "0.6.1" version "0.6.1"
@ -4241,9 +4241,9 @@ css-what@^6.0.1, css-what@^6.1.0:
integrity sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA== integrity sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==
cssdb@^8.6.0: cssdb@^8.6.0:
version "8.10.0" version "8.11.0"
resolved "https://registry.yarnpkg.com/cssdb/-/cssdb-8.10.0.tgz#fdb9cc7af72c81839265811ad8ca4e0a4db919c1" resolved "https://registry.yarnpkg.com/cssdb/-/cssdb-8.11.0.tgz#e03c9cdc9c5e99d8cddf64a917bfc427b20c143a"
integrity sha512-+JWEEjjoqkPY7iGHps3SaCT2w67Zpaj9zHvhCJ2iPBavKHwgtOOD2YEbZSCU8VO2uVGpKdYjVz+j6bhkNSjZ0g== integrity sha512-VzY/8kcK5M8oCVr/cwh24J8XVlCOITpmzCizKBC28o7Z1s23MMojXoJ3q7a+TQQoMKvxC3YlG0Z9yU10kJF1uQ==
cssesc@^3.0.0: cssesc@^3.0.0:
version "3.0.0" version "3.0.0"
@ -4568,9 +4568,9 @@ ee-first@1.1.1:
integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==
electron-to-chromium@^1.5.402: electron-to-chromium@^1.5.402:
version "1.5.415" version "1.5.418"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.415.tgz#edd7356bfb4752a12c8293f8e38a00778b13bbb4" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.418.tgz#40ccbf6d572447663041611e05924b53bc9a0331"
integrity sha512-958V+Kbhtgz+SxXeEVKBjrlKRBIDAYvUJfwhjxMZ5S6ut9jAl7l9ZKBkBrvjyjZE36PabLUo2L8kEeV5O4vgJg== integrity sha512-UzS26r3AEbG5wSoGVpJKqwHIU9zwQN7LHdVIThDrJpS0I5KdlXFMEb8543fhc9dVnIIAST6ar8rhwa00AL5MlA==
emoji-regex@^8.0.0: emoji-regex@^8.0.0:
version "8.0.0" version "8.0.0"
@ -4897,9 +4897,9 @@ fast-uri@^3.0.1:
integrity sha512-7Ical1vFEMr0onbVzEDIreM22I4khW+fzyQPwvAFWBp1iwdshSZRsL4jjRvPG9JP1uiqMHRto+YU6R2/CzDz5Q== integrity sha512-7Ical1vFEMr0onbVzEDIreM22I4khW+fzyQPwvAFWBp1iwdshSZRsL4jjRvPG9JP1uiqMHRto+YU6R2/CzDz5Q==
fastq@^1.6.0: fastq@^1.6.0:
version "1.20.1" version "1.20.3"
resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.20.1.tgz#ca750a10dc925bc8b18839fd203e3ef4b3ced675" resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.20.3.tgz#7ab8731e647b56abcfeee997dae333ca3ee1d04d"
integrity sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw== integrity sha512-XKv5nnLs6nLF71NgiKJLIZFLkPyIEuOselLG7ujZnGrRfQK8HpvY+WqKhAJUAdLomwVHErVS4LfxFlPq0/FTAw==
dependencies: dependencies:
reusify "^1.0.4" reusify "^1.0.4"
@ -6281,18 +6281,18 @@ media-typer@0.3.0:
integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==
memfs@^4.43.1: memfs@^4.43.1:
version "4.68.1" version "4.68.2"
resolved "https://registry.yarnpkg.com/memfs/-/memfs-4.68.1.tgz#e42fa69c873305a9cd0b28a8d230b96efacd8b5d" resolved "https://registry.yarnpkg.com/memfs/-/memfs-4.68.2.tgz#26aeb07f3774ccf79bf9d79483ea3241e1383254"
integrity sha512-OD+IDRUvIxu3QHL+nFm9gdyugInD27FDJ+sl4B5QgomPHXMlbw+GP918P8VNKu2FkNlVeqBkpzkwROpamVifRw== integrity sha512-Un1ElEBoIdPI9kg0sm3LebVEuEViodfIvlaG8Z1MFXa7ZnR9vWuPKUo3dt/vuWY2ivc05l76B5QOjdgCzAzmGw==
dependencies: dependencies:
"@jsonjoy.com/fs-core" "4.68.1" "@jsonjoy.com/fs-core" "4.68.2"
"@jsonjoy.com/fs-fsa" "4.68.1" "@jsonjoy.com/fs-fsa" "4.68.2"
"@jsonjoy.com/fs-node" "4.68.1" "@jsonjoy.com/fs-node" "4.68.2"
"@jsonjoy.com/fs-node-builtins" "4.68.1" "@jsonjoy.com/fs-node-builtins" "4.68.2"
"@jsonjoy.com/fs-node-to-fsa" "4.68.1" "@jsonjoy.com/fs-node-to-fsa" "4.68.2"
"@jsonjoy.com/fs-node-utils" "4.68.1" "@jsonjoy.com/fs-node-utils" "4.68.2"
"@jsonjoy.com/fs-print" "4.68.1" "@jsonjoy.com/fs-print" "4.68.2"
"@jsonjoy.com/fs-snapshot" "4.68.1" "@jsonjoy.com/fs-snapshot" "4.68.2"
"@jsonjoy.com/json-pack" "^1.11.0" "@jsonjoy.com/json-pack" "^1.11.0"
"@jsonjoy.com/util" "^1.9.0" "@jsonjoy.com/util" "^1.9.0"
glob-to-regex.js "^1.0.1" glob-to-regex.js "^1.0.1"
@ -8446,9 +8446,9 @@ send@~0.19.0, send@~0.19.1:
statuses "~2.0.2" statuses "~2.0.2"
serialize-javascript@>=7.0.5, serialize-javascript@^6.0.0, serialize-javascript@^6.0.1: serialize-javascript@>=7.0.5, serialize-javascript@^6.0.0, serialize-javascript@^6.0.1:
version "7.1.0" version "7.1.1"
resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-7.1.0.tgz#9e462c5c6dec5dbc8b55d90c52a4ad6aff985b9f" resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-7.1.1.tgz#c3b0a7ac13df6cf2fcda71cbb142ba9392a710b9"
integrity sha512-RNEqWOyhhUQYN9V1GfHwu9AR/g+NTciH6Z5u3/no6X3/w+04J2lVDL+svFQVXgXrEGBMG2puMVN3gq2SNGuTGw== integrity sha512-k3CMsaIvvdSwm8oLB4MXSl0wH2/cwlH7xGcnRd2DaeRmBkbzYmyT8j0tsX60DwD1eRwHTpNpH8ljKu9oUT1MeQ==
serve-handler@^6.1.7: serve-handler@^6.1.7:
version "6.1.7" version "6.1.7"
@ -9117,9 +9117,9 @@ unpipe@~1.0.0:
integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==
update-browserslist-db@^1.3.0: update-browserslist-db@^1.3.0:
version "1.3.1" version "1.3.2"
resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.3.1.tgz#a71c28dd22f505481dbc4689087b18d933e90afd" resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.3.2.tgz#9d99fbff56c50bb11ba5fd35cece5916da595836"
integrity sha512-ZZ61DsRsOnakl74HAmp3oSN4aXUmEWXf+i/yv0h7tIBfICc3VdrFErQKUUKPgu3AMsTUMbcongALEN4l6GSUrQ== integrity sha512-UQ+MSxlhRm1bzjhU+DcuXfjFO1FzNtqhK5+9Yvlp90ItDLk5vT932A0rFu619nf7RVS+Y/VeaUW1jaRDqZ8VJw==
dependencies: dependencies:
escalade "^3.2.0" escalade "^3.2.0"
picocolors "^1.1.1" picocolors "^1.1.1"
@ -9326,9 +9326,9 @@ webpack-sources@^3.5.1:
integrity sha512-jyuiGJdtvY434z5bUZrjz67v76/ePNvFZTp9Mdz29IlH4+GPsgyGjiv0fKI+M7BdkU6ADjulUcKAd3tUK3WlEw== integrity sha512-jyuiGJdtvY434z5bUZrjz67v76/ePNvFZTp9Mdz29IlH4+GPsgyGjiv0fKI+M7BdkU6ADjulUcKAd3tUK3WlEw==
webpack@^5.88.1, webpack@^5.95.0: webpack@^5.88.1, webpack@^5.95.0:
version "5.110.0" version "5.110.2"
resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.110.0.tgz#504e6195f3a729ed3904b24961e43f0f51e1b79b" resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.110.2.tgz#ef23a0e62fe5e1ba71b033e3505b7f005d8d5c6e"
integrity sha512-vzGjrgzXNYRs0MBVkdF288cJt0RIJMxlZy+3pLFo6KIeZI57sBGCgjBp+yNQWf5g9c1us34rjivM1sfNLijQYg== integrity sha512-TciLrfM7zgEjqGdY851HkirDsSPQgTFsWQpl9oHqMAMYsHhEC0bKjscvjpnz+pzx10hLC8qISApGrsnrCP4UtQ==
dependencies: dependencies:
"@types/estree" "^1.0.8" "@types/estree" "^1.0.8"
"@types/json-schema" "^7.0.15" "@types/json-schema" "^7.0.15"