Archilyzer · Source

archilyzer

Archilyzer
git clone https://archilyzer.pages.dev/source/archilyzer.git
Log | Files | Refs | README | LICENSE

commit 7767905706d8891812758e43c46441072d95b8be
parent c11cdfd3e51add5d181eec14995b22ae589003ae
Author: I Mean I'm Just Saying <imeanimjustsaying@kiwifarms.st>
Date:   Mon,  6 Jul 2026 21:43:42 -0400

Upload oversize archives to R2 via S3 multipart, not wrangler

`wrangler r2 object put` caps a single upload at 300 MiB, so oversize
archives (e.g. a 480 MB live-chat zip) failed to upload and the served
manifest pointed at a missing object. Switch runArchiveUploadIntoLog to
R2's S3 API using the AWS SDK's multipart uploader (@aws-sdk/lib-storage),
which streams any size. Archives stay .zip (application/zip); Cache-Control
unchanged.

Credentials come from the env (R2_ACCESS_KEY_ID, R2_SECRET_ACCESS_KEY,
CLOUDFLARE_ACCOUNT_ID → S3 endpoint), not the settings JSON. If a bucket is
configured with staged files but creds are missing, the upload fails closed
(non-zero, before the Pages deploy) so a site never links to a missing file.
wrangler still handles the Pages deploy. DEPLOY_CLOUDFLARE.md documents the
new S3 credential step.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

Diffstat:
MDEPLOY_CLOUDFLARE.md | 38+++++++++++++++++++++++++++++++-------
Meditor/CHANGELOG.md | 2+-
Meditor/app/deploy/buildDeployCore.ts | 103+++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------
Meditor/package.json | 2++
Mpnpm-lock.yaml | 380+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mpnpm-workspace.yaml | 16++++++++++++++++
6 files changed, 505 insertions(+), 36 deletions(-)

diff --git a/DEPLOY_CLOUDFLARE.md b/DEPLOY_CLOUDFLARE.md @@ -36,9 +36,15 @@ Oversize archives are staged during compose into `export/.r2-staging/<siteId>/ar **Build & deploy** actions to `<bucket>/<siteId>/archives/<file>.zip` **before** the Pages deploy runs, so the manifest URLs resolve immediately. -> **Note:** only the **editor's** deploy actions upload to R2 (that's where the host -> `wrangler` credentials live). A raw `pnpm run build` / `pnpm deploy` from the -> `export` package only *stages* the files — it does not upload them. +> **Note:** only the **editor's** deploy actions upload to R2 (that's where the R2 +> credentials live). A raw `pnpm run build` / `pnpm deploy` from the `export` +> package only *stages* the files — it does not upload them. + +Uploads go through R2's **S3 API** (via the AWS SDK's multipart uploader), not +`wrangler r2 object put` — wrangler caps a single upload at **300 MiB**, and real +live-chat archives are larger (multipart has no such limit). That's why archive +uploads need S3 credentials (step 3) in addition to the wrangler auth your Pages +deploy already uses. --- @@ -76,11 +82,29 @@ ways to expose it; the first needs **no domain purchase** and is the recommended throttles `r2.dev` and gives you **no** cache / rate-limit control of your own. Fine for a smoke test; use the Worker for a real instance. -### 3. Authenticate `wrangler` +### 3. Authenticate — two credentials + +**a) `wrangler` (for the Pages deploy).** The `wrangler pages deploy` step reuses +whatever auth you already use. If it works today, nothing to do. Otherwise run +`wrangler login`, or set `CLOUDFLARE_API_TOKEN`. + +**b) R2 S3 API keys (for the archive uploads).** Archive objects are uploaded over +R2's S3-compatible API, which needs an Access Key ID + Secret. In the dashboard: +**R2 → Manage R2 API Tokens → Create API token**, permission **Object Read & Write**, +scoped to your bucket. Then set three environment variables where the editor runs: + +```sh +export R2_ACCESS_KEY_ID=<access key id> +export R2_SECRET_ACCESS_KEY=<secret access key> +export CLOUDFLARE_ACCOUNT_ID=<your account id> # used to build the S3 endpoint +``` -Uploads run as `wrangler r2 object put … --remote` from the host, reusing whatever -auth your Pages deploy already uses. If `wrangler pages deploy` works today, this will -too. Otherwise run `wrangler login`, or set `CLOUDFLARE_API_TOKEN` with R2 write scope. +The account id is on the R2 overview page; the S3 endpoint is derived as +`https://<CLOUDFLARE_ACCOUNT_ID>.r2.cloudflarestorage.com`. Keep these in the +environment (a shell profile, a systemd unit, a `.env` the editor loads) — **not** in +the settings JSON, which isn't a place for secrets. If a deploy has oversize archives +to upload but these are unset, it fails *before* the Pages deploy (so the site never +links to a missing file) with a message pointing back here. ### 4. Point the editor at the bucket diff --git a/editor/CHANGELOG.md b/editor/CHANGELOG.md @@ -5,7 +5,7 @@ - **Search results scroll smoothly again on large result sets.** The results list windows one card per matching video (only the on-screen cards are mounted), but each visible card and every one of its hit rows was re-rendering on *every* scroll frame — and each hit row re-ran its `<mark>` highlighting, so a single video with hundreds of hits meant hundreds of redundant highlight passes per frame while scrolling. The result cards and individual hit rows are now memoized so an unchanged card/row is skipped during scroll, and opening the modal on a hit only re-renders the two rows whose highlight state actually changes. No visible/behavioral change — same DOM, same results, just far less work per frame. See `common/components/TranscriptSearch.tsx` (`ResultCard`/`HitRow` memoization, `openWithMode` stabilized via `useCallback`). - **The monitor widget gains a needs-work channel list, more interaction buttons, and an in-place settings gear.** Three additions, all driveable from the widget builder. **(1) A "Needs work" list** (URL flag `act=1`) — a compact, per-channel worklist of videos to download (`↓ N`) or transcribe (`✎ N`), reusing the same `loadActionableSummary` that powers the `/actionable` page via a new `/api/widget/actionable` route; it polls on a 15s floor (the backlog changes on job completions, not seconds) and caps at 6 channels with a `+N more` line. **(2) More interactions** behind the existing `controls=1` switch: each needs-work row gains the same per-channel **Download missing** / **Transcribe pending** buttons as the actionable page (reusing `InlineActionButton`), and the controls row adds **Retry all failed** alongside Pause/Resume + Drain. **(3) An in-place settings gear** (on by default; URL flag `gear=0` to hide, or a **Show settings gear** builder checkbox) — clicking it opens the builder's own form *inside the widget window*, so a pinned widget can be reconfigured live without opening the builder page; edits apply immediately and mirror into the address bar via `history.replaceState`, so a reload preserves them and the link stays copyable. The builder form is extracted into a shared `WidgetConfigForm` used by both the builder and the overlay, and the widget's poller now fetches immediately on (re)subscribe instead of after one interval, so newly-enabled sections render at once. Existing links render unchanged (the two new flags default to their old behavior; the gear is the one new default-visible affordance and is read-only — it mutates no server state). See `editor/app/widget/lib/config.ts`, the new `editor/app/widget/components/WidgetConfigForm.tsx` and `editor/app/api/widget/actionable/route.ts`, `editor/app/widget/components/{MonitorWidget,WidgetControls}.tsx`, `editor/app/widget/builder/components/WidgetBuilder.tsx`, and `editor/e2e/widget.spec.ts`. - **Every site build now bundles downloadable per-channel transcript & live-chat archive zips.** The archive builders (per-channel `<slug>.zip` / `<slug>.live_chat.zip`) previously only ran as standalone actions that wrote to a non-served directory; now `compose-site` generates them for the site's own channels straight into the served `public/archives/` and writes a `manifest.json` (sizes + counts) that the site's new **Downloads** page reads. **`zip` is now the default archive format** everywhere (was `tar.gz`), and the Build page's format help text tracks the selected format. Generation is **on by default with three opt-out levels**: a global **Generate archive zips on build** toggle in Settings, a per-site **Generate archive zips** toggle (plus an optional **Archive size cap (MB)**) on the site's page, and a per-build **Skip archive zips** checkbox on the Build and Build & Deploy controls (`BUILD_ARCHIVES=0`). See `common/bin/compose-site.ts` (`composeArchives`), `common/controller/archive{Transcripts,LiveChat}.ts` (new `outDir` option), `common/lib/archiveOptions.ts` (default + manifest types), `common/lib/{site,settings}.ts` (opt-out flags), and `editor/app/{deploy/buildDeployCore.ts,build/buildAction.ts,deploy/components/Build{Export,Deploy}Button.tsx,sites/components/SiteForm.tsx,settings/components/SettingsForm.tsx}`. -- **Oversize archives now overflow to Cloudflare R2 instead of being dropped.** A single file over 25 MB breaks a Cloudflare Pages deploy, so a channel zip over the cap (default 25 MB; `0` = no cap) used to be removed from what's served and flagged `oversize`. Now, when **Archive overflow storage** is configured in Settings (an R2 **bucket** + its **public URL**), `compose-site` stages each oversize archive to `export/.r2-staging/<siteId>/` and records its future public URL in the manifest; the deploy step then uploads it via `wrangler r2 object put <bucket>/<siteId>/archives/<file>` (reusing the host's wrangler auth) **before** the Pages deploy, so the Downloads page links straight to R2. With no bucket configured the old drop-and-flag behavior is unchanged (uploads run only in the editor's Deploy / Build & deploy actions, not a raw `pnpm deploy`). The **combined "whole site" archives were removed** — they duplicated the per-channel content and were always the first to blow the cap. Each R2 upload also now sets `Cache-Control: public, max-age=3600` so a Cloudflare custom domain caches downloads at the edge — the main defense against download-abuse cost (R2 egress is free; only origin reads are billable, and cached hits skip the origin). New **[DEPLOY_CLOUDFLARE.md](../DEPLOY_CLOUDFLARE.md)** documents the full R2 setup plus the Cloudflare custom-domain / caching / rate-limiting / bot config for instance operators. See `common/lib/settings.ts` (`archiveStorage`), `common/bin/compose-site.ts` (staging + manifest `url`), `common/lib/archiveOptions.ts` (`ArchiveManifestEntry.url`), and `editor/app/deploy/buildDeployCore.ts` (`runArchiveUploadIntoLog`, `ARCHIVE_CACHE_CONTROL`) / `deploy/deployAction.ts` / `build/buildAction.ts`. +- **Oversize archives now overflow to Cloudflare R2 instead of being dropped.** A single file over 25 MB breaks a Cloudflare Pages deploy, so a channel zip over the cap (default 25 MB; `0` = no cap) used to be removed from what's served and flagged `oversize`. Now, when **Archive overflow storage** is configured in Settings (an R2 **bucket** + its **public URL**), `compose-site` stages each oversize archive to `export/.r2-staging/<siteId>/` and records its future public URL in the manifest; the deploy step then uploads it to `<bucket>/<siteId>/archives/<file>` **before** the Pages deploy, so the Downloads page links straight to R2. Uploads go over R2's **S3 API** using the AWS SDK's multipart uploader (`@aws-sdk/lib-storage`) — `wrangler r2 object put` caps a single upload at 300 MiB and real live-chat archives are larger, whereas multipart streams any size. This needs R2 **S3 credentials** in the environment (`R2_ACCESS_KEY_ID`, `R2_SECRET_ACCESS_KEY`, `CLOUDFLARE_ACCOUNT_ID`); if they're missing when there's something to upload, the deploy fails before the Pages step (so the site never links to a missing file). With no bucket configured the old drop-and-flag behavior is unchanged (uploads run only in the editor's Deploy / Build & deploy actions, not a raw `pnpm deploy`). The **combined "whole site" archives were removed** — they duplicated the per-channel content and were always the first to blow the cap. Each R2 upload also now sets `Cache-Control: public, max-age=3600` so a Cloudflare custom domain caches downloads at the edge — the main defense against download-abuse cost (R2 egress is free; only origin reads are billable, and cached hits skip the origin). New **[DEPLOY_CLOUDFLARE.md](../DEPLOY_CLOUDFLARE.md)** documents the full R2 setup plus the Cloudflare custom-domain / caching / rate-limiting / bot config for instance operators. See `common/lib/settings.ts` (`archiveStorage`), `common/bin/compose-site.ts` (staging + manifest `url`), `common/lib/archiveOptions.ts` (`ArchiveManifestEntry.url`), and `editor/app/deploy/buildDeployCore.ts` (`runArchiveUploadIntoLog`, `ARCHIVE_CACHE_CONTROL`) / `deploy/deployAction.ts` / `build/buildAction.ts`. - **Archive downloads can now be served securely without owning a domain (`r2-proxy/` Worker).** Serving oversize R2 archives with cost/abuse protection previously implied a Cloudflare **custom domain** (for CDN caching + rate-limiting rules). New self-contained Cloudflare Worker at `r2-proxy/` serves the bucket on a free `*.workers.dev` subdomain instead — the same domain-free model as Pages' `*.pages.dev`, addressing the privacy/expense of registering a domain. It's a pure passthrough (request path `<siteId>/archives/<file>.zip` → bucket key), so **one Worker serves every site** — deploy it once, not per site. It adds edge caching (Cache API, honoring the object's `Cache-Control`), native per-IP rate limiting (free binding), path allow-listing (`*/archives/*.zip` only), and `Range`/resumable-download support. Point the editor's **Archive overflow public URL** at the `workers.dev` URL and nothing else changes (uploads/manifest are identical). `DEPLOY_CLOUDFLARE.md` now documents both paths (Worker vs custom domain), with the Worker as the recommended no-domain option. See `r2-proxy/{src/index.ts,wrangler.toml,package.json,README.md}` and `editor/app/settings/components/SettingsForm.tsx` (public-URL hint). - **The Duplicates page is now a per-site toggle and hides itself when empty.** Each site's editor page gains a **Show the Duplicates page** checkbox (on by default). `compose-site` writes the site-filtered `duplicates.json` only when the toggle is on *and* there's at least one in-scope cluster, and the export Header keys its Duplicates nav link off a new `hasDuplicates()` — so the link and page disappear both when a site opts out and when it simply has no detected duplicates. See `common/lib/site.ts` (`duplicates` flag), `common/bin/compose-site.ts` (gated write), `export/app/lib/duplicates.ts` (new), `export/app/components/Header.tsx`, and `editor/app/sites/{components/SiteForm.tsx,actions.ts}`. - **You can now change a channel's slug (its id) — deliberately, from the Danger zone.** A channel's slug *is* its on-disk directory name (`transcripts/channels/<slug>/`), so it used to be fixed at creation ("Slug is fixed once a channel is created"). A new **Rename** form in the channel's Danger zone lifts that: enter a new slug and **type the current slug to confirm** (same friction as delete), and the rename is blocked while the channel has running/queued jobs (the in-memory registry keys by slug). Because the slug is a directory name, the rename does a **full migration** of every slug-keyed store so nothing silently breaks: it moves the channel dir (config, data, playlist, snapshot, shards, failed lists) **and** the saved-video store dir — rewriting each `saved-video.json` pointer's absolute `dir` so persisted source videos still resolve — then retargets every site.json membership, the sync scheduler's per-channel backoff state, and any job bookmarks. The two filesystem moves run first and roll back on failure; the metadata updates that follow are atomic and best-effort (surfaced as warnings). Renaming **changes the channel's public URL** (the old one 404s), which the form warns about. The slug grammar is also now validated on create. See `common/controller/renameChannel.ts`, `common/controller/channels.ts` (`isValidChannelSlug`), `common/lib/savedVideo-server.ts` (`rewriteSavedVideoDir`), `common/jobs/bookmarks.ts` (`renameChannelInBookmarks`), `editor/app/channels/{actions.ts,components/RenameChannelForm.tsx,[slug]/page.tsx}`, and `editor/e2e/channel-rename.spec.ts`. diff --git a/editor/app/deploy/buildDeployCore.ts b/editor/app/deploy/buildDeployCore.ts @@ -6,6 +6,10 @@ import path from "node:path"; import { readdir } from "node:fs/promises"; +import { createReadStream } from "node:fs"; +import { stat } from "node:fs/promises"; +import { S3Client } from "@aws-sdk/client-s3"; +import { Upload } from "@aws-sdk/lib-storage"; import { runChildIntoLog } from "yt-dlp-transcript-common/jobs/runChild"; import type { Paths } from "yt-dlp-transcript-common/lib/paths"; import { getSettings } from "yt-dlp-transcript-common/lib/settings"; @@ -93,12 +97,23 @@ function archiveStagingDir(siteId: string, paths: Paths): string { // going stale; raise it if your archives rarely change. const ARCHIVE_CACHE_CONTROL = "public, max-age=3600"; +// MIME type stored on each uploaded archive. Archives are `.zip` bundles. +const ARCHIVE_CONTENT_TYPE = "application/zip"; + // Upload this site's staged oversize archives to the configured R2 bucket, so the -// remote URLs the served manifest points at actually resolve. Reuses the host's -// wrangler auth (process.env), same as the Pages deploy. No-op (returns 0) when -// overflow storage isn't configured or nothing was staged. Keys match what -// composeArchives wrote into the manifest: `<siteId>/archives/<file>`. Must run -// BEFORE the Pages deploy so the manifest never points at a missing object. +// remote URLs the served manifest points at actually resolve. Uploads go through +// R2's S3 API with the AWS SDK's multipart uploader (`@aws-sdk/lib-storage`) — +// `wrangler r2 object put` caps single-file uploads at 300 MiB, which real +// live-chat archives blow past, whereas multipart streams any size. Keys match +// what composeArchives wrote into the manifest: `<siteId>/archives/<file>`. Must +// run BEFORE the Pages deploy so the manifest never points at a missing object. +// +// No-op (returns 0) when overflow storage isn't configured or nothing was staged. +// Credentials come from the host env (NOT the settings JSON — secrets don't +// belong there): R2_ACCESS_KEY_ID, R2_SECRET_ACCESS_KEY, and CLOUDFLARE_ACCOUNT_ID +// (for the S3 endpoint). If a bucket is configured and files are staged but the +// credentials are missing, we fail (return non-zero) so the deploy aborts rather +// than shipping a manifest that points at un-uploaded objects. export async function runArchiveUploadIntoLog( onLog: (line: string) => void, signal: AbortSignal, @@ -118,32 +133,64 @@ export async function runArchiveUploadIntoLog( } if (files.length === 0) return 0; + const accessKeyId = process.env.R2_ACCESS_KEY_ID?.trim(); + const secretAccessKey = process.env.R2_SECRET_ACCESS_KEY?.trim(); + const accountId = process.env.CLOUDFLARE_ACCOUNT_ID?.trim(); + if (!accessKeyId || !secretAccessKey || !accountId) { + onLog( + `[archives] ${files.length} oversize archive(s) need uploading to R2 bucket ` + + `"${bucket}", but R2 S3 credentials are missing. Set R2_ACCESS_KEY_ID, ` + + `R2_SECRET_ACCESS_KEY, and CLOUDFLARE_ACCOUNT_ID in the environment — see ` + + `DEPLOY_CLOUDFLARE.md. Aborting before deploy so the site never links to ` + + `missing files.\n`, + ); + return 1; + } + + const client = new S3Client({ + region: "auto", + endpoint: `https://${accountId}.r2.cloudflarestorage.com`, + credentials: { accessKeyId, secretAccessKey }, + }); + onLog( - `[archives] uploading ${files.length} oversize archive(s) to R2 bucket "${bucket}"…\n`, + `[archives] uploading ${files.length} oversize archive(s) to R2 bucket "${bucket}" via the S3 API…\n`, ); - for (const file of files) { - const key = `${site.siteId}/archives/${file}`; - const code = await runChildIntoLog(onLog, signal, { - command: "pnpm", - args: [ - "dlx", - "wrangler", - "r2", - "object", - "put", - `${bucket}/${key}`, - `--file=${path.join(stagingDir, file)}`, - "--content-type=application/zip", - `--cache-control=${ARCHIVE_CACHE_CONTROL}`, - "--remote", - ], - cwd: paths.exportDir, - env: { ...process.env, NODE_ENV: "production" }, - }); - if (code !== 0) { - onLog(`[archives] R2 upload failed for ${key} (exit ${code}).\n`); - return code; + try { + for (const file of files) { + if (signal.aborted) return 1; + const key = `${site.siteId}/archives/${file}`; + const filePath = path.join(stagingDir, file); + const { size } = await stat(filePath); + onLog(`[archives] ${key} (${(size / 1e6).toFixed(1)} MB)…\n`); + const upload = new Upload({ + client, + params: { + Bucket: bucket, + Key: key, + Body: createReadStream(filePath), + ContentType: ARCHIVE_CONTENT_TYPE, + CacheControl: ARCHIVE_CACHE_CONTROL, + }, + }); + const onAbort = () => { + upload.abort().catch(() => {}); + }; + signal.addEventListener("abort", onAbort, { once: true }); + try { + await upload.done(); + } finally { + signal.removeEventListener("abort", onAbort); + } + onLog(`[archives] ${key} done.\n`); } + } catch (err) { + onLog( + `[archives] R2 upload failed: ${err instanceof Error ? err.message : String(err)}\n`, + ); + return 1; + } finally { + client.destroy(); } onLog("[archives] R2 upload complete.\n"); return 0; diff --git a/editor/package.json b/editor/package.json @@ -14,6 +14,8 @@ "e2e:ui": "playwright test --ui" }, "dependencies": { + "@aws-sdk/client-s3": "^3.1080.0", + "@aws-sdk/lib-storage": "^3.1080.0", "@sindresorhus/slugify": "^3.0.0", "lucide-react": "^1.16.0", "markdown-to-jsx": "^7.7.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml @@ -111,6 +111,12 @@ importers: editor: dependencies: + '@aws-sdk/client-s3': + specifier: ^3.1080.0 + version: 3.1080.0 + '@aws-sdk/lib-storage': + specifier: ^3.1080.0 + version: 3.1080.0(@aws-sdk/client-s3@3.1080.0) '@sindresorhus/slugify': specifier: ^3.0.0 version: 3.0.0 @@ -283,6 +289,84 @@ packages: resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} engines: {node: '>=10'} + '@aws-sdk/checksums@3.1000.13': + resolution: {integrity: sha512-USI1N1d+NbCcfjeiYLKIl94PSYykl5IIjj4X3WqdL33Ln5qktA6sjXYct0o/gG2Cte7cuzbXKkDBkzUA4VPHrg==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/client-s3@3.1080.0': + resolution: {integrity: sha512-erKuxbwhYLKs0ZviBeTDvXxC0E4AtugHXLbt5kFk8u9/rQMglh/QJNK5f9KuLjlMrbFSJgkBmjNSY5O03YoK4A==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/core@3.974.28': + resolution: {integrity: sha512-4/1DtLwgLqzIg2uFzkFaFjMQHhhhwHIZN4PfziIVqXYX7koO78omuchQlLHyzQBw80l255dtmTA/J4W5yhb7zw==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-env@3.972.54': + resolution: {integrity: sha512-F4WQCG8GULIt+XrMHsqUM9dZc0eTwZM3HUWByOjIKOwBqJSzUxX8CFAtbgMvWfCua52FS1oi5FXarH3+khFq8A==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-http@3.972.56': + resolution: {integrity: sha512-PiwHgEK2srdfi/lFveyQ+3w/qikyh6MKvuZAdlMC+dwQi4K5iVBr32oh7cugnYw+jA8iGtnQMhCGvLm/mqplmw==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-ini@3.972.61': + resolution: {integrity: sha512-9CZWMjhBlgfKlqJk40R7kvMOLEIoOr3HJ1J/ELjAH9H5LzR4bCxLujPVM/1PKAEjzSZKZCxWOalm7JUGZbhQqw==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-login@3.972.60': + resolution: {integrity: sha512-Ak6OOrCbXvACyxLFIP1mcS+JTLS9ZpW1ZqyBtqu6axvdpsbG1gVNhUlAfQq8TK/gar/h2w35LrzlQU0PcUzJpw==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-node@3.972.63': + resolution: {integrity: sha512-YmgWtTPZDStyT74ApSHpApD3r7W9znsc+WEZjW0vceom+NAxRx9/F3TyukOKix8kJkPaa49aIREQJdpGeLDiEw==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-process@3.972.54': + resolution: {integrity: sha512-UNmUjtTnp3wH3YTZcctN7yK17S2AdaJpiNIdIf0l70hHOdGuDfdMxk62P5rt64GwGm6qkFOYG0js/cU6cdZDdg==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-sso@3.972.60': + resolution: {integrity: sha512-zH8SvJkTRw1Kb7GARjGPjzkQPfL3jDi/OxK32I5SQq7bgwgFHJZaoDEwkEvFlfNfpByM6n4Rs20Y1mLyOdb6ag==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-web-identity@3.972.60': + resolution: {integrity: sha512-q2rJSQ/AMjemUS18OtQqczqSo2R6VjOCLmLVmLVcdrP5/AKoj632lGCrMUWQ6EgnaLMEHbq0UO4mWh/u6gjPhA==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/lib-storage@3.1080.0': + resolution: {integrity: sha512-Vhe1T+Of8qWRypS8sEsC24931jMUd0Q2MNhtzApZB18Re/JnRYo5NaqlMSktzvyQ3SUljHTQ/R5Bv2Cz0bRfGg==} + engines: {node: '>=20.0.0'} + peerDependencies: + '@aws-sdk/client-s3': ^3.1080.0 + + '@aws-sdk/middleware-sdk-s3@3.972.59': + resolution: {integrity: sha512-KCf/UjbnzV3QIXR1C2MeE9eRUG8EUXUf0V4y65hf2bKWQXzol5f3I8wOhE6OBdEYohn8zHfnC/cyy5+s7/HwLw==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/nested-clients@3.997.28': + resolution: {integrity: sha512-1oG/mM3jmE2M3kad2zWJS6IKIY8hjRV4l5kAgg+xTQdLMTtehhcSucL/y4WqQpcHmQwi6+gRK8E46GYl1NBW9Q==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/signature-v4-multi-region@3.996.38': + resolution: {integrity: sha512-C379Sk+MiFZCfWZphKlMyLHKxV22OjoGM5KJjj5IJNJcOCWL4IGIpnEGzv1FQiRwhYXfq55SJMfxlqPE08JJ9g==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/token-providers@3.1080.0': + resolution: {integrity: sha512-8PufAQvncWXvdZUvODbuyXa8l3aszefEzwSMBUcgheNbZOmJMcNn388Ebt/piVrUHyxKN1MlxnR2OonzTyZaGw==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/types@3.973.15': + resolution: {integrity: sha512-IULn8uBV/SMtmOIANsm4WHXIOtVPBWfOWs3WGL0j/sI+KhaYehvOw0ET+9urnn8MBpiijuU/0JOpuwKOE451PQ==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/xml-builder@3.972.33': + resolution: {integrity: sha512-ezbwz9WpuLctm6o7P2t2naDhVVPI5jFGrVefVybhcKGjU57VIyT46pQVO0RI2RYkUdhdj2Z9uSIlAzGZE9NW9A==} + engines: {node: '>=20.0.0'} + + '@aws/lambda-invoke-store@0.3.0': + resolution: {integrity: sha512-sl4Bm6yiMNYrZKkqqDFWN0UfnWhlS8ivKxrYl+6t0gCLrqr8y3B2IqZZbFRkfaVVp7C/baApyh71P+LeE1A2sQ==} + engines: {node: '>=18.0.0'} + '@babel/code-frame@7.29.0': resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==} engines: {node: '>=6.9.0'} @@ -1619,6 +1703,30 @@ packages: resolution: {integrity: sha512-gVaaGtKYMYAMmI8buULVH3A2TXVJ98QiwGwI7ddrWGuGidGC2uRt4FHs22+8iROJ0QTzju9CuMjlVsrvpqsdhA==} engines: {node: '>=20'} + '@smithy/core@3.29.1': + resolution: {integrity: sha512-qoiY4nrk5OCu1+eIR1VB8l5DmON/oKiqrd5zZFAhXJXjJlLWQusKEW/SkBDAtGDcPaz86m9kfcE1lngU0GlM6A==} + engines: {node: '>=18.0.0'} + + '@smithy/credential-provider-imds@4.4.6': + resolution: {integrity: sha512-B2WQ/PV/H6Jeg3lrIq6bKUfa6Hy01mtK7CGs6lhjzHA6k4aagldH6T6eEjnzKl4HI0cJnAsxfJ19pgb5PV+CVQ==} + engines: {node: '>=18.0.0'} + + '@smithy/fetch-http-handler@5.6.3': + resolution: {integrity: sha512-CwCc/7SMTj45y97MUnDTbTaxvtAsiNNRm81z3abROIuMbMsC2Iy5EKfkkVdsKrz8WExQAAMx1EJapq+9j4fFTQ==} + engines: {node: '>=18.0.0'} + + '@smithy/node-http-handler@4.9.3': + resolution: {integrity: sha512-qZTa4gQFUo8RM02rk6q5UVTDLNrQ1oS20LsepBzqq1QBVc/EHJ03OOUADcqMZiXHArW+Y7+OGY0BpdTwZRq/Yg==} + engines: {node: '>=18.0.0'} + + '@smithy/signature-v4@5.6.2': + resolution: {integrity: sha512-QgHflghMoPxCJ9axiCVh8KZfbC9fuP6vkXXyK//E3cq7nLaSSyyLj0GAoqVWezYeDQmXIZhmlRvLE16jsqDK6g==} + engines: {node: '>=18.0.0'} + + '@smithy/types@4.15.1': + resolution: {integrity: sha512-x3L0XSACF6UYzKpa9biqiRMgvH5+wnFFew9Tm/grFYqgaupPwx/+ojDPpPJM8dZON3S9tjz5U+PQYsCBd1Mw5Q==} + engines: {node: '>=18.0.0'} + '@swc/helpers@0.5.15': resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} @@ -2062,11 +2170,17 @@ packages: resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} engines: {node: 18 || 20 || >=22} + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + baseline-browser-mapping@2.10.23: resolution: {integrity: sha512-xwVXGqevyKPsiuQdLj+dZMVjidjJV508TBqexND5HrF89cGdCYCJFB3qhcxRHSeMctdCfbR1jrxBajhDy7o29g==} engines: {node: '>=6.0.0'} hasBin: true + bowser@2.14.1: + resolution: {integrity: sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg==} + boxen@7.0.0: resolution: {integrity: sha512-j//dBVuyacJbvW+tvZ9HuH03fZ46QcaKvvhZickZqtB271DxJ7SNRSNxrV/dZX0085m7hISRZWbzWlJvx/rHSg==} engines: {node: '>=14.16'} @@ -2087,6 +2201,9 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true + buffer@5.6.0: + resolution: {integrity: sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==} + bytes@3.0.0: resolution: {integrity: sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==} engines: {node: '>= 0.8'} @@ -2498,6 +2615,10 @@ packages: eventemitter3@4.0.7: resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} + events@3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} + execa@5.1.1: resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} engines: {node: '>=10'} @@ -2698,6 +2819,9 @@ packages: resolution: {integrity: sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==} engines: {node: '>=18.18.0'} + ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + ignore@5.3.2: resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} @@ -2714,6 +2838,9 @@ packages: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} engines: {node: '>=0.8.19'} + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + ini@1.3.8: resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} @@ -3390,6 +3517,10 @@ packages: resolution: {integrity: sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==} engines: {node: '>=0.10.0'} + readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + recharts-scale@0.4.5: resolution: {integrity: sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w==} @@ -3538,6 +3669,9 @@ packages: resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} engines: {node: '>= 0.4'} + stream-browserify@3.0.0: + resolution: {integrity: sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==} + string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} @@ -3569,6 +3703,9 @@ packages: resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} engines: {node: '>= 0.4'} + string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + strip-ansi@6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} @@ -3745,6 +3882,9 @@ packages: '@types/react': optional: true + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + vary@1.1.2: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} @@ -3816,6 +3956,181 @@ snapshots: '@alloc/quick-lru@5.2.0': {} + '@aws-sdk/checksums@3.1000.13': + dependencies: + '@aws-sdk/core': 3.974.28 + '@aws-sdk/types': 3.973.15 + '@smithy/core': 3.29.1 + '@smithy/types': 4.15.1 + tslib: 2.8.1 + + '@aws-sdk/client-s3@3.1080.0': + dependencies: + '@aws-sdk/checksums': 3.1000.13 + '@aws-sdk/core': 3.974.28 + '@aws-sdk/credential-provider-node': 3.972.63 + '@aws-sdk/middleware-sdk-s3': 3.972.59 + '@aws-sdk/signature-v4-multi-region': 3.996.38 + '@aws-sdk/types': 3.973.15 + '@smithy/core': 3.29.1 + '@smithy/fetch-http-handler': 5.6.3 + '@smithy/node-http-handler': 4.9.3 + '@smithy/types': 4.15.1 + tslib: 2.8.1 + + '@aws-sdk/core@3.974.28': + dependencies: + '@aws-sdk/types': 3.973.15 + '@aws-sdk/xml-builder': 3.972.33 + '@aws/lambda-invoke-store': 0.3.0 + '@smithy/core': 3.29.1 + '@smithy/signature-v4': 5.6.2 + '@smithy/types': 4.15.1 + bowser: 2.14.1 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-env@3.972.54': + dependencies: + '@aws-sdk/core': 3.974.28 + '@aws-sdk/types': 3.973.15 + '@smithy/core': 3.29.1 + '@smithy/types': 4.15.1 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-http@3.972.56': + dependencies: + '@aws-sdk/core': 3.974.28 + '@aws-sdk/types': 3.973.15 + '@smithy/core': 3.29.1 + '@smithy/fetch-http-handler': 5.6.3 + '@smithy/node-http-handler': 4.9.3 + '@smithy/types': 4.15.1 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-ini@3.972.61': + dependencies: + '@aws-sdk/core': 3.974.28 + '@aws-sdk/credential-provider-env': 3.972.54 + '@aws-sdk/credential-provider-http': 3.972.56 + '@aws-sdk/credential-provider-login': 3.972.60 + '@aws-sdk/credential-provider-process': 3.972.54 + '@aws-sdk/credential-provider-sso': 3.972.60 + '@aws-sdk/credential-provider-web-identity': 3.972.60 + '@aws-sdk/nested-clients': 3.997.28 + '@aws-sdk/types': 3.973.15 + '@smithy/core': 3.29.1 + '@smithy/credential-provider-imds': 4.4.6 + '@smithy/types': 4.15.1 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-login@3.972.60': + dependencies: + '@aws-sdk/core': 3.974.28 + '@aws-sdk/nested-clients': 3.997.28 + '@aws-sdk/types': 3.973.15 + '@smithy/core': 3.29.1 + '@smithy/types': 4.15.1 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-node@3.972.63': + dependencies: + '@aws-sdk/credential-provider-env': 3.972.54 + '@aws-sdk/credential-provider-http': 3.972.56 + '@aws-sdk/credential-provider-ini': 3.972.61 + '@aws-sdk/credential-provider-process': 3.972.54 + '@aws-sdk/credential-provider-sso': 3.972.60 + '@aws-sdk/credential-provider-web-identity': 3.972.60 + '@aws-sdk/types': 3.973.15 + '@smithy/core': 3.29.1 + '@smithy/credential-provider-imds': 4.4.6 + '@smithy/types': 4.15.1 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-process@3.972.54': + dependencies: + '@aws-sdk/core': 3.974.28 + '@aws-sdk/types': 3.973.15 + '@smithy/core': 3.29.1 + '@smithy/types': 4.15.1 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-sso@3.972.60': + dependencies: + '@aws-sdk/core': 3.974.28 + '@aws-sdk/nested-clients': 3.997.28 + '@aws-sdk/token-providers': 3.1080.0 + '@aws-sdk/types': 3.973.15 + '@smithy/core': 3.29.1 + '@smithy/types': 4.15.1 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-web-identity@3.972.60': + dependencies: + '@aws-sdk/core': 3.974.28 + '@aws-sdk/nested-clients': 3.997.28 + '@aws-sdk/types': 3.973.15 + '@smithy/core': 3.29.1 + '@smithy/types': 4.15.1 + tslib: 2.8.1 + + '@aws-sdk/lib-storage@3.1080.0(@aws-sdk/client-s3@3.1080.0)': + dependencies: + '@aws-sdk/client-s3': 3.1080.0 + '@smithy/core': 3.29.1 + '@smithy/types': 4.15.1 + buffer: 5.6.0 + events: 3.3.0 + stream-browserify: 3.0.0 + tslib: 2.8.1 + + '@aws-sdk/middleware-sdk-s3@3.972.59': + dependencies: + '@aws-sdk/core': 3.974.28 + '@aws-sdk/signature-v4-multi-region': 3.996.38 + '@aws-sdk/types': 3.973.15 + '@smithy/core': 3.29.1 + '@smithy/types': 4.15.1 + tslib: 2.8.1 + + '@aws-sdk/nested-clients@3.997.28': + dependencies: + '@aws-sdk/core': 3.974.28 + '@aws-sdk/signature-v4-multi-region': 3.996.38 + '@aws-sdk/types': 3.973.15 + '@smithy/core': 3.29.1 + '@smithy/fetch-http-handler': 5.6.3 + '@smithy/node-http-handler': 4.9.3 + '@smithy/types': 4.15.1 + tslib: 2.8.1 + + '@aws-sdk/signature-v4-multi-region@3.996.38': + dependencies: + '@aws-sdk/types': 3.973.15 + '@smithy/signature-v4': 5.6.2 + '@smithy/types': 4.15.1 + tslib: 2.8.1 + + '@aws-sdk/token-providers@3.1080.0': + dependencies: + '@aws-sdk/core': 3.974.28 + '@aws-sdk/nested-clients': 3.997.28 + '@aws-sdk/types': 3.973.15 + '@smithy/core': 3.29.1 + '@smithy/types': 4.15.1 + tslib: 2.8.1 + + '@aws-sdk/types@3.973.15': + dependencies: + '@smithy/types': 4.15.1 + tslib: 2.8.1 + + '@aws-sdk/xml-builder@3.972.33': + dependencies: + '@smithy/types': 4.15.1 + tslib: 2.8.1 + + '@aws/lambda-invoke-store@0.3.0': {} + '@babel/code-frame@7.29.0': dependencies: '@babel/helper-validator-identifier': 7.28.5 @@ -5060,6 +5375,39 @@ snapshots: '@sindresorhus/transliterate@2.3.1': {} + '@smithy/core@3.29.1': + dependencies: + '@smithy/types': 4.15.1 + tslib: 2.8.1 + + '@smithy/credential-provider-imds@4.4.6': + dependencies: + '@smithy/core': 3.29.1 + '@smithy/types': 4.15.1 + tslib: 2.8.1 + + '@smithy/fetch-http-handler@5.6.3': + dependencies: + '@smithy/core': 3.29.1 + '@smithy/types': 4.15.1 + tslib: 2.8.1 + + '@smithy/node-http-handler@4.9.3': + dependencies: + '@smithy/core': 3.29.1 + '@smithy/types': 4.15.1 + tslib: 2.8.1 + + '@smithy/signature-v4@5.6.2': + dependencies: + '@smithy/core': 3.29.1 + '@smithy/types': 4.15.1 + tslib: 2.8.1 + + '@smithy/types@4.15.1': + dependencies: + tslib: 2.8.1 + '@swc/helpers@0.5.15': dependencies: tslib: 2.8.1 @@ -5485,8 +5833,12 @@ snapshots: balanced-match@4.0.4: {} + base64-js@1.5.1: {} + baseline-browser-mapping@2.10.23: {} + bowser@2.14.1: {} + boxen@7.0.0: dependencies: ansi-align: 3.0.1 @@ -5519,6 +5871,11 @@ snapshots: node-releases: 2.0.38 update-browserslist-db: 1.2.3(browserslist@4.28.2) + buffer@5.6.0: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + bytes@3.0.0: {} bytes@3.1.2: {} @@ -6133,6 +6490,8 @@ snapshots: eventemitter3@4.0.7: {} + events@3.3.0: {} + execa@5.1.1: dependencies: cross-spawn: 7.0.6 @@ -6337,6 +6696,8 @@ snapshots: human-signals@8.0.1: {} + ieee754@1.2.1: {} + ignore@5.3.2: {} ignore@7.0.5: {} @@ -6348,6 +6709,8 @@ snapshots: imurmurhash@0.1.4: {} + inherits@2.0.4: {} + ini@1.3.8: {} internal-slot@1.1.0: @@ -7036,6 +7399,12 @@ snapshots: react@19.2.4: {} + readable-stream@3.6.2: + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + recharts-scale@0.4.5: dependencies: decimal.js-light: 2.5.1 @@ -7262,6 +7631,11 @@ snapshots: es-errors: 1.3.0 internal-slot: 1.1.0 + stream-browserify@3.0.0: + dependencies: + inherits: 2.0.4 + readable-stream: 3.6.2 + string-width@4.2.3: dependencies: emoji-regex: 8.0.0 @@ -7324,6 +7698,10 @@ snapshots: define-properties: 1.2.1 es-object-atoms: 1.1.1 + string_decoder@1.3.0: + dependencies: + safe-buffer: 5.2.1 + strip-ansi@6.0.1: dependencies: ansi-regex: 5.0.1 @@ -7513,6 +7891,8 @@ snapshots: optionalDependencies: '@types/react': 19.2.14 + util-deprecate@1.0.2: {} + vary@1.1.2: {} victory-vendor@36.9.2: diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml @@ -14,6 +14,22 @@ allowBuilds: ignoredBuiltDependencies: - sharp - unrs-resolver +minimumReleaseAgeExclude: + - '@aws-sdk/checksums@3.1000.13' + - '@aws-sdk/client-s3@3.1080.0' + - '@aws-sdk/core@3.974.28' + - '@aws-sdk/credential-provider-env@3.972.54' + - '@aws-sdk/credential-provider-http@3.972.56' + - '@aws-sdk/credential-provider-ini@3.972.61' + - '@aws-sdk/credential-provider-login@3.972.60' + - '@aws-sdk/credential-provider-node@3.972.63' + - '@aws-sdk/credential-provider-process@3.972.54' + - '@aws-sdk/credential-provider-sso@3.972.60' + - '@aws-sdk/credential-provider-web-identity@3.972.60' + - '@aws-sdk/lib-storage@3.1080.0' + - '@aws-sdk/middleware-sdk-s3@3.972.59' + - '@aws-sdk/nested-clients@3.997.28' + - '@aws-sdk/token-providers@3.1080.0' onlyBuiltDependencies: - cypress - esbuild