diff --git a/.env.example b/.env.example
index 06f69b9a..71905afa 100644
--- a/.env.example
+++ b/.env.example
@@ -1,6 +1,7 @@
-# BrowserStack credentails
-BROWSER_STACK_USERNAME=
-BROWSER_STACK_ACCESS=
+# Convert Staging SDK Key
+CONVERT_STAGING_SDK_KEY=
+CONVERT_STAGING_SDK_KEY2=
+CONVERT_STAGING_SDK_KEY2_SECRET=
# Logger
LOG_LEVEL=2
diff --git a/.github/workflows/publish-package.yml b/.github/workflows/publish-package.yml
index 9d672687..70c86d96 100644
--- a/.github/workflows/publish-package.yml
+++ b/.github/workflows/publish-package.yml
@@ -88,6 +88,12 @@ jobs:
(cd packages/experience && npm publish --access public)
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
+ - if: ${{ startsWith(env.RELEASE_TAG, 'js-sdk-cloudflare-v') }}
+ run: |
+ yarn cloudflare:build
+ (cd packages/cloudflare && npm publish --access public)
+ env:
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
- if: ${{ startsWith(env.RELEASE_TAG, 'js-sdk-v') }}
run: |
yarn sdk:build
diff --git a/.github/workflows/qa.yml b/.github/workflows/qa.yml
index 63028700..dcb0225e 100644
--- a/.github/workflows/qa.yml
+++ b/.github/workflows/qa.yml
@@ -17,29 +17,37 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
- node: [18]
+ node: [22]
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
- - uses: actions/setup-node@v1
+ - uses: actions/checkout@v4
with:
- # The Node.js version to configure
- node-version: ${{ matrix.node }}
+ fetch-depth: 2
- # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- - uses: actions/checkout@v2
+ - name: Setup Node
+ uses: actions/setup-node@v4
with:
- fetch-depth: 2
- - name: Install needed libraries and packages
+ node-version: ${{ matrix.node }}
+
+ - name: Setup Yarn
+ run: |
+ corepack enable
+ corepack prepare yarn@stable --activate
+
+ - name: Install Playwright browsers
run: |
- wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo apt-key add -
- sudo sh -c 'echo "deb http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list'
- sudo apt-get update
- sudo apt-get install -y google-chrome-stable
+ cd packages/js-sdk
+ npx playwright install --with-deps chromium
- name: Runs the SDK QA checks
+ env:
+ CONVERT_STAGING_SDK_KEY: ${{ secrets.CONVERT_STAGING_SDK_KEY }}
+ CONVERT_STAGING_SDK_KEY2: ${{ secrets.CONVERT_STAGING_SDK_KEY2 }}
+ CONVERT_STAGING_SDK_KEY2_SECRET: ${{ secrets.CONVERT_STAGING_SDK_KEY2_SECRET }}
run: |
- yarn set version berry
yarn
cd packages/js-sdk
yarn lint
- yarn test
+ yarn build
+ yarn test:mocha
+ yarn test:browser
diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml
index 9b76dc63..cb9142e2 100644
--- a/.github/workflows/release-please.yml
+++ b/.github/workflows/release-please.yml
@@ -56,5 +56,6 @@ jobs:
packages/data) yarn data:build && (cd packages/data && npm publish --access public) ;;
packages/experience) yarn experience:build && (cd packages/experience && npm publish --access public) ;;
packages/js-sdk) yarn sdk:build && (cd packages/js-sdk && npm publish --access public) ;;
+ packages/cloudflare) yarn cloudflare:build && (cd packages/cloudflare && npm publish --access public) ;;
*) echo "Unknown path: $REL_PATH" && exit 1 ;;
esac
diff --git a/.gitignore b/.gitignore
index 2ab095da..20e9e4df 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,6 +12,7 @@ lib/
dist/
docs/
coverage/
+test-results/
packages/demo-*
.next
demo/remixjs-server-side/build
diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index 9ff278d1..c5517b45 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -10,5 +10,6 @@
"packages/segments": "2.1.2",
"packages/api": "2.1.4",
"packages/data": "3.3.3",
- "packages/experience": "2.3.2"
+ "packages/experience": "2.3.2",
+ "packages/cloudflare": "1.0.0"
}
diff --git a/demo/cloudflare-workers/README.md b/demo/cloudflare-workers/README.md
new file mode 100644
index 00000000..901aa935
--- /dev/null
+++ b/demo/cloudflare-workers/README.md
@@ -0,0 +1,252 @@
+# Convert SDK — Cloudflare Workers Demo
+
+Run Convert A/B tests at the Cloudflare edge with zero client-side flicker. This demo works out of the box with the Convert staging project (`10035569/10034190`) — the same credentials used by all other SDK demos.
+
+## Routes
+
+| Route | Location | Experiments | Features |
+|-------|----------|-------------|----------|
+| `/` | — | None (home page) | — |
+| `/events` | `events` | `test-experience-ab-fullstack-1` | — |
+| `/statistics` | `statistics` | All matching | `feature-4` |
+| `/pricing` | `pricing` | All matching | `feature-5` |
+
+## How It Works
+
+```
+Visitor → Cloudflare Worker (localhost:8787)
+ ├── Fetch config from Convert CDN (edge-cached, ~1-5ms)
+ ├── Map URL path to location property (e.g. /events → "events")
+ ├── SDK: createContext → runExperience/runExperiences
+ ├── Fetch origin page (localhost:8888)
+ ├── HTMLRewriter: inject experiment results into HTML
+ ├── Set visitor cookie + cache headers
+ └── Respond (total overhead: ~5-8ms)
+
+ └── Background (waitUntil):
+ └── Flush tracking events to Convert
+```
+
+No KV namespace is required. Config is cached using Cloudflare's native `cf.cacheTtl` fetch option (free, all plans). Visitor bucketing is deterministic — the same visitor ID always gets the same variation via a cookie.
+
+## Setup
+
+### 1. Install Dependencies
+
+From the monorepo root:
+
+```bash
+yarn install
+```
+
+If the cloudflare package hasn't been built yet:
+
+```bash
+yarn cloudflare:build
+```
+
+You don't need to publish `@convertcom/js-sdk-cloudflare` to npm — Yarn workspaces symlinks it to the local `packages/cloudflare/` directory, and Wrangler's bundler follows symlinks.
+
+### 2. Start the Origin Server
+
+The demo includes a simple origin server (`origin/`) that serves HTML pages for each route. The Worker proxies to this origin and modifies the response with experiment results.
+
+```bash
+# Terminal 1
+cd demo/cloudflare-workers
+yarn origin
+```
+
+This starts on http://localhost:8888 with pages for `/`, `/events`, `/statistics`, and `/pricing`.
+
+### 3. Start the Worker
+
+```bash
+# Terminal 2
+cd demo/cloudflare-workers
+yarn dev
+```
+
+This starts on http://localhost:8787.
+
+### 4. Open in Browser
+
+Visit http://localhost:8787/ and navigate to the different routes:
+
+- **Events** — Shows the bucketed variation for `test-experience-ab-fullstack-1`
+- **Statistics** — Shows all matching variations + `feature-4` status
+- **Pricing** — Shows all matching variations (both experiences) + `feature-5` status
+
+## Verification
+
+### Config Fetch
+
+Confirm the staging project config is accessible:
+
+```bash
+curl -s "https://cdn-4.convertexperiments.com/api/v1/config/10035569/10034190" | head -c 200
+```
+
+Should return JSON starting with `{"account_id":"10035569"...`.
+
+### Visitor Cookie
+
+```bash
+curl -v http://localhost:8787/events 2>&1 | grep -i set-cookie
+```
+
+Expected: `Set-Cookie: convert_visitor_id=; Path=/; ...`
+
+### Deterministic Bucketing
+
+```bash
+# Get a visitor ID
+VISITOR_ID=$(curl -s -D- http://localhost:8787/events 2>&1 | grep -io 'convert_visitor_id=[^;]*' | cut -d= -f2)
+echo "Visitor: $VISITOR_ID"
+
+# Same cookie → same variation every time
+curl -s -b "convert_visitor_id=$VISITOR_ID" http://localhost:8787/events
+curl -s -b "convert_visitor_id=$VISITOR_ID" http://localhost:8787/events
+```
+
+Both responses should show identical experiment results.
+
+### HTMLRewriter
+
+Compare the origin page vs the Worker-modified page:
+
+```bash
+# Origin (unmodified)
+curl -s http://localhost:8888/events | grep experiment-results
+
+# Worker (modified with bucketing results)
+curl -s http://localhost:8787/events | grep experiment-results
+```
+
+The Worker response should contain variation names/keys instead of the placeholder text.
+
+### Cache Headers
+
+```bash
+curl -s -D- http://localhost:8787/events 2>&1 | grep -iE 'cache-control|vary'
+```
+
+Expected:
+
+```
+Cache-Control: public, max-age=300
+Vary: Cookie
+```
+
+### Tracking Events
+
+Watch the Worker logs while making requests:
+
+```bash
+# Terminal 3
+cd demo/cloudflare-workers
+yarn tail
+```
+
+After visiting a page, you should see the SDK POST tracking data to Convert. In the Convert dashboard, the visitor count for the experience should increment.
+
+### Error Fallback
+
+Temporarily set an invalid SDK key in `wrangler.toml`:
+
+```toml
+CONVERT_SDK_KEY = "invalid/key"
+```
+
+Restart `yarn dev` and visit http://localhost:8787/events — should return the unmodified origin page (graceful degradation via try/catch).
+
+### Bundle Validation
+
+```bash
+cd demo/cloudflare-workers
+npx wrangler deploy --dry-run --outdir /tmp/cf-bundle
+```
+
+Should succeed with bundle size ~296 KiB / ~58 KiB gzipped.
+
+## Checklist
+
+| Test | What to Verify |
+|------|---------------|
+| Config fetch | `curl` to CDN config endpoint returns JSON |
+| Wrangler bundle | `--dry-run` succeeds |
+| Worker starts | `yarn dev` runs without errors |
+| Origin server | `yarn origin` serves pages on port 8888 |
+| New visitor cookie | `Set-Cookie: convert_visitor_id=` in response |
+| Deterministic bucketing | Same cookie → same variation on repeated requests |
+| HTMLRewriter | Experiment results injected into HTML |
+| Cache headers | `Cache-Control: public, max-age=300` + `Vary: Cookie` |
+| Tracking events | Visitor count increments in Convert dashboard |
+| Error fallback | Invalid SDK key → unmodified origin page returned |
+| No KV required | All above works without any KV namespace configured |
+
+## Configuration
+
+The demo is pre-configured in `wrangler.toml`:
+
+```toml
+CONVERT_SDK_KEY = "10035569/10034190" # Staging project
+ORIGIN_URL = "http://localhost:8888" # Local origin server
+```
+
+To use your own project, update these values and adjust the experience/feature keys in `src/index.ts`.
+
+## Iterating on Package Changes
+
+If you modify `packages/cloudflare/src/` files:
+
+```bash
+# Rebuild the package
+yarn cloudflare:build
+
+# Restart the Worker (Ctrl+C, then yarn dev again)
+```
+
+## Production Deployment
+
+**Important:** The default `ORIGIN_URL` is `http://localhost:8888` which only works for local development. Deploying with this value will fail because `localhost` is not reachable from Cloudflare's network (you'll see a Cloudflare "Error 1003: Direct IP access not allowed" page).
+
+For production, update `ORIGIN_URL` in `wrangler.toml` to a publicly accessible origin:
+
+```toml
+ORIGIN_URL = "https://your-site.com"
+```
+
+Then deploy:
+
+```bash
+yarn deploy
+```
+
+## Optional: KV-Backed Persistence
+
+If you need to preserve bucketing across experience config changes or store custom visitor attributes, you can optionally add KV support. See the commented section at the bottom of `src/index.ts` for setup instructions.
+
+## Troubleshooting
+
+**"Cannot find module @convertcom/js-sdk-cloudflare"**
+→ Run `yarn install` at the monorepo root to ensure workspace symlinks exist, then `yarn cloudflare:build`.
+
+**"Convert config fetch failed: 404"**
+→ Verify your SDK key. Test directly: `curl https://cdn-4.convertexperiments.com/api/v1/config/ACCOUNT_ID/PROJECT_ID`
+
+**Experience returns null / string (RuleError)**
+→ The experience key doesn't match, or location/audience rules don't match. Check that the experience is **Active** (not Draft/Paused) in Convert.
+
+**HTMLRewriter changes not visible**
+→ Add `console.log('variation:', variation)` in the Worker and check Wrangler logs to confirm bucketing.
+
+**Tracking events not appearing in dashboard**
+→ Confirm `ctx.waitUntil(context.releaseQueues(...))` is called. Check Wrangler logs for outbound POST requests.
+
+**Page hangs / infinite loop**
+→ All `fetch(request)` calls must go through `fetchOrigin()` which rewrites the URL to `ORIGIN_URL`. Direct `fetch(request)` loops back to the Worker.
+
+## Documentation
+
+Full guide: [Cloudflare Workers Edge Experimentation](https://github.com/convertcom/javascript-sdk/wiki/CloudflareWorkers)
diff --git a/demo/cloudflare-workers/origin/server.js b/demo/cloudflare-workers/origin/server.js
new file mode 100644
index 00000000..89f313cf
--- /dev/null
+++ b/demo/cloudflare-workers/origin/server.js
@@ -0,0 +1,126 @@
+/*!
+ * Simple origin server for the Cloudflare Workers demo.
+ * Generates HTML pages from a shared template that the Worker proxies and modifies.
+ *
+ * Usage: node origin/server.js
+ * Serves on http://localhost:8888
+ */
+
+const http = require('http');
+
+const PORT = 8888;
+
+// Page definitions — only the unique content per route
+const PAGES = {
+ '/': {
+ title: 'Convert Edge Demo',
+ body: `
+
+
Cloudflare Workers Demo
+
This page is served by a simple origin server and proxied through a Cloudflare Worker.
+
The Worker runs Convert A/B tests at the edge and modifies HTML before delivery — zero flicker.
+
+
+
Tip: Visit the
Events,
Statistics,
+ or
Pricing pages to see experiments in action.
+ The home page has no experiments configured.
+
`
+ },
+ '/events': {
+ title: 'Events - Convert Edge Demo',
+ heading: 'Events',
+ description: 'Experience: test-experience-ab-fullstack-1 | Location: events',
+ featureLabel: 'Feature Status'
+ },
+ '/statistics': {
+ title: 'Statistics - Convert Edge Demo',
+ heading: 'Statistics',
+ description: 'Runs all matching experiences | Feature: feature-4 | Location: statistics',
+ featureLabel: 'Feature Status (feature-4)'
+ },
+ '/pricing': {
+ title: 'Pricing - Convert Edge Demo',
+ heading: 'Pricing',
+ description:
+ 'Runs all matching experiences | Feature: feature-5 | Location: pricing
' +
+ 'Experiences on this route: test-experience-ab-fullstack-1 and test-experience-ab-fullstack-4',
+ featureLabel: 'Feature Status (feature-5)'
+ }
+};
+
+// Shared layout template
+function renderPage(page) {
+ const nav = ``;
+
+ // Home page uses custom body; experiment pages use a standard layout
+ const content = page.body || `
+
+
${page.heading}
+
${page.description}
+
+
+
Experiment Results
+
+ No experiment bucketing yet — this content is replaced by the Worker.
+
+
+
+
${page.featureLabel}
+
+ No feature flag evaluated.
+
+
+
+
Variation Caption
+
+ Original caption (not modified)
+
+
`;
+
+ return `
+
+
+
+
+ ${page.title}
+
+
+
+ ${nav}
+ ${content}
+
+`;
+}
+
+const server = http.createServer((req, res) => {
+ const pathname = req.url.split('?')[0];
+ const page = PAGES[pathname];
+
+ if (!page) {
+ res.writeHead(404, {'Content-Type': 'text/html'});
+ res.end('404 Not Found
');
+ return;
+ }
+
+ res.writeHead(200, {'Content-Type': 'text/html; charset=utf-8'});
+ res.end(renderPage(page));
+});
+
+server.listen(PORT, () => {
+ console.log(`Origin server running at http://localhost:${PORT}`);
+ console.log('Pages: /, /events, /statistics, /pricing');
+});
diff --git a/demo/cloudflare-workers/package.json b/demo/cloudflare-workers/package.json
new file mode 100644
index 00000000..f4306cff
--- /dev/null
+++ b/demo/cloudflare-workers/package.json
@@ -0,0 +1,22 @@
+{
+ "name": "@convertcom/js-sdk-demo-cloudflare-workers",
+ "version": "1.0.0",
+ "author": "Convert Insights, Inc",
+ "license": "Apache-2.0",
+ "private": true,
+ "scripts": {
+ "origin": "node origin/server.js",
+ "dev": "wrangler dev",
+ "deploy": "wrangler deploy",
+ "tail": "wrangler tail"
+ },
+ "dependencies": {
+ "@convertcom/js-sdk": "^4.3.4",
+ "@convertcom/js-sdk-cloudflare": "^1.0.0"
+ },
+ "devDependencies": {
+ "@cloudflare/workers-types": "^4.20241205.0",
+ "typescript": "^5.9.3",
+ "wrangler": "^3.99.0"
+ }
+}
diff --git a/demo/cloudflare-workers/src/index.ts b/demo/cloudflare-workers/src/index.ts
new file mode 100644
index 00000000..01047842
--- /dev/null
+++ b/demo/cloudflare-workers/src/index.ts
@@ -0,0 +1,343 @@
+/*!
+ * Convert JS SDK - Cloudflare Workers Demo
+ * Version 1.0.0
+ * Copyright(c) 2020 Convert Insights, Inc
+ * License Apache-2.0
+ *
+ * This Worker demonstrates edge experimentation using the Convert FullStack SDK.
+ * It proxies requests to an origin server and modifies HTML responses based on
+ * A/B test bucketing decisions — all at the Cloudflare edge with zero flicker.
+ *
+ * Routes (matching the staging project's location rules):
+ * / - Home page (no experiments)
+ * /events - Runs experience "test-experience-ab-fullstack-1"
+ * /statistics - Runs all matching experiences + feature "feature-4"
+ * /pricing - Runs all matching experiences + feature "feature-5"
+ */
+
+import ConvertSDK, {BucketedVariation} from '@convertcom/js-sdk';
+import {
+ EdgeConfigCache,
+ getVisitorId,
+ setVisitorIdCookie,
+ generateVisitorId,
+ setCacheHeaders
+} from '@convertcom/js-sdk-cloudflare';
+
+// ---------------------------------------------------------------------------
+// Types
+// ---------------------------------------------------------------------------
+
+interface Env {
+ CONVERT_SDK_KEY: string;
+ // Origin server to proxy to. Set in wrangler.toml [vars].
+ ORIGIN_URL: string;
+ // KV is optional — only needed if you enable the KVDataStore for
+ // persisting visitor bucketing data across experience config changes.
+ // CONVERT_KV: KVNamespace;
+}
+
+// ---------------------------------------------------------------------------
+// Route → Location mapping
+// ---------------------------------------------------------------------------
+// The staging project's locations match on a "location" property, not URL path.
+// This mirrors the pattern used by the Node.js demo.
+
+// Route configuration — maps URL paths to location properties and feature keys.
+// The staging project's locations match on a "location" property, not URL path.
+// This mirrors the pattern used by the Node.js demo. [ConvertSDK]
+const ROUTES: Record = {
+ '/events': {location: 'events', experienceKey: 'test-experience-ab-fullstack-1'},
+ '/statistics': {location: 'statistics', featureKey: 'feature-4'},
+ '/pricing': {location: 'pricing', featureKey: 'feature-5'}
+};
+
+// ---------------------------------------------------------------------------
+// Origin fetch helper
+// ---------------------------------------------------------------------------
+
+/**
+ * Fetch from the origin server instead of the Worker's own URL.
+ * Without this, `fetch(request)` in local dev loops back to the Worker.
+ */
+function fetchOrigin(request: Request, env: Env): Promise {
+ const originUrl = new URL(request.url);
+ const origin = new URL(env.ORIGIN_URL);
+ originUrl.hostname = origin.hostname;
+ originUrl.port = origin.port;
+ originUrl.protocol = origin.protocol;
+ return fetch(new Request(originUrl.toString(), request));
+}
+
+// ---------------------------------------------------------------------------
+// SDK Singleton
+// ---------------------------------------------------------------------------
+
+let sdk: InstanceType | null = null;
+let sdkReadyPromise: Promise> | null = null;
+
+/**
+ * Initialise (or reuse) the SDK singleton.
+ * Uses EdgeConfigCache with Cloudflare's built-in fetch cache — the config
+ * response is cached at the edge for the TTL duration, no KV needed.
+ */
+async function getSDK(env: Env): Promise> {
+ if (sdk) return sdk;
+ if (sdkReadyPromise) return sdkReadyPromise;
+
+ sdkReadyPromise = (async () => {
+ const configCache = new EdgeConfigCache(
+ env.CONVERT_SDK_KEY,
+ 300 // cache TTL in seconds (5 minutes)
+ );
+ const configData = await configCache.getConfig();
+
+ const newSdk = new ConvertSDK({
+ data: configData,
+ // Passing data directly avoids the timer-based refresh (setTimeout)
+ // which is meaningless in a stateless Worker environment.
+ network: {tracking: true}
+ });
+ await newSdk.onReady();
+ sdk = newSdk;
+ return sdk;
+ })();
+
+ return sdkReadyPromise;
+}
+
+// ---------------------------------------------------------------------------
+// Worker Entry Point
+// ---------------------------------------------------------------------------
+
+export default {
+ async fetch(
+ request: Request,
+ env: Env,
+ ctx: ExecutionContext
+ ): Promise {
+ const url = new URL(request.url);
+
+ // Only process HTML page requests (skip assets, API calls, etc.)
+ const accept = request.headers.get('Accept') || '';
+ const wantsHtml =
+ accept.includes('text/html') || accept.includes('*/*') || accept === '';
+ if (
+ !wantsHtml ||
+ url.pathname.startsWith('/api/') ||
+ url.pathname.match(/\.\w{2,4}$/)
+ ) {
+ return fetchOrigin(request, env);
+ }
+
+ // Check if this route has experiment configuration
+ const route = ROUTES[url.pathname];
+ if (!route) {
+ // Home page or unknown route — serve origin unmodified with visitor cookie
+ const response = await fetchOrigin(request, env);
+ const headers = new Headers(response.headers);
+ if (!getVisitorId(request)) {
+ setVisitorIdCookie(headers, generateVisitorId());
+ }
+ return new Response(response.body, {
+ status: response.status,
+ statusText: response.statusText,
+ headers
+ });
+ }
+
+ try {
+ // 1. Initialise the SDK
+ const convert = await getSDK(env);
+
+ // 2. Identify the visitor
+ let visitorId = getVisitorId(request);
+ const isNewVisitor = !visitorId;
+ if (isNewVisitor) {
+ visitorId = generateVisitorId();
+ }
+
+ // 3. Create visitor context with audience properties
+ // The staging project's "Adv Audience" requires mobile: true or desktop: true.
+ // This mirrors the Node.js demo's createContext(userId, {mobile: true}).
+ const context = convert.createContext(visitorId, {mobile: true});
+ if (!context) {
+ return fetchOrigin(request, env);
+ }
+
+ // Set default segments (mirrors Node.js demo)
+ context.setDefaultSegments({country: 'US'});
+
+ // 4. Run experiments based on route
+ const decisions = decideForRoute(context, route);
+
+ // 5. Fetch the origin page
+ const originResponse = await fetchOrigin(request, env);
+
+ // 6. Apply variations via HTMLRewriter
+ const modifiedResponse = applyDecisions(originResponse, decisions);
+
+ // 7. Build response headers (visitor cookie + cache control)
+ const headers = new Headers(modifiedResponse.headers);
+ if (isNewVisitor) {
+ setVisitorIdCookie(headers, visitorId);
+ }
+ setCacheHeaders(headers, 300);
+
+ // 8. Release tracking events in the background
+ // The SDK batches events with setTimeout which won't fire in Workers.
+ // releaseQueues() flushes immediately; waitUntil() keeps the isolate
+ // alive for the tracking POST without blocking the response.
+ ctx.waitUntil(context.releaseQueues('edge-request-complete'));
+
+ return new Response(modifiedResponse.body, {
+ status: modifiedResponse.status,
+ statusText: modifiedResponse.statusText,
+ headers
+ });
+ } catch (error) {
+ // On any SDK error, serve the origin page unmodified
+ console.error('Convert SDK error:', error);
+ return fetchOrigin(request, env);
+ }
+ }
+} satisfies ExportedHandler;
+
+// ---------------------------------------------------------------------------
+// Route-specific experiment logic
+// ---------------------------------------------------------------------------
+
+interface RouteDecisions {
+ variation: BucketedVariation | null;
+ variations: BucketedVariation[];
+ feature: any;
+}
+
+/**
+ * Run experiments and features for the current route.
+ * Mirrors the Node.js demo's per-route decide() functions.
+ */
+function decideForRoute(
+ context: any,
+ route: {location: string; experienceKey?: string; featureKey?: string}
+): RouteDecisions {
+ const decisions: RouteDecisions = {
+ variation: null,
+ variations: [],
+ feature: null
+ };
+ const locationProperties = {location: route.location};
+
+ if (route.experienceKey) {
+ // Single experience (like the Node.js events route)
+ const bucketed = context.runExperience(route.experienceKey, {
+ locationProperties
+ });
+ console.log('bucketed variation:', bucketed);
+ if (bucketed && typeof bucketed !== 'string') {
+ decisions.variation = bucketed;
+ }
+ } else {
+ // All matching experiences (like the Node.js statistics/pricing routes)
+ const bucketedAll = context.runExperiences({locationProperties});
+ console.log('bucketed variation(s):', bucketedAll);
+ if (Array.isArray(bucketedAll)) {
+ decisions.variations = bucketedAll.filter(
+ (v: any) => v && typeof v !== 'string'
+ );
+ }
+ }
+
+ if (route.featureKey) {
+ const feature = context.runFeature(route.featureKey, {locationProperties});
+ console.log('bucketed feature:', feature);
+ if (feature && feature.status === 'enabled') {
+ decisions.feature = feature;
+ }
+ }
+
+ return decisions;
+}
+
+// ---------------------------------------------------------------------------
+// HTMLRewriter transformations
+// ---------------------------------------------------------------------------
+
+/**
+ * Apply experiment decisions to the origin HTML response.
+ * Uses HTMLRewriter to inject bucketing results into the page.
+ */
+function applyDecisions(
+ response: Response,
+ decisions: RouteDecisions
+): Response {
+ const {variation, variations, feature, route} = decisions;
+
+ // Build a summary of all decisions for this request
+ const allVariations =
+ variation ? [variation] : variations.length ? variations : [];
+ if (allVariations.length === 0 && !feature) {
+ return response; // No experiments matched — return unmodified
+ }
+
+ // Inject experiment results into the page
+ return new HTMLRewriter()
+ .on('#experiment-results', {
+ element(el) {
+ const items = allVariations
+ .map(
+ (v) =>
+ `${v.experienceName || v.experienceKey}: ${v.name || v.key}`
+ )
+ .join('');
+ if (items) {
+ el.setInnerContent(``, {html: true});
+ }
+ }
+ })
+ .on('#feature-status', {
+ element(el) {
+ if (feature) {
+ el.setInnerContent(
+ `Feature enabled: ${feature.key || 'yes'}`,
+ {html: true}
+ );
+ }
+ }
+ })
+ .on('#variation-caption', {
+ element(el) {
+ // Extract the "caption" variable from feature-1 (attached to the experience)
+ const v = allVariations[0];
+ if (
+ v &&
+ Array.isArray(v.changes) &&
+ v.changes.length &&
+ v.changes[0].data?.variables_data?.caption
+ ) {
+ el.setInnerContent(v.changes[0].data.variables_data.caption);
+ }
+ }
+ })
+ .transform(response);
+}
+
+// ---------------------------------------------------------------------------
+// Optional: KV-Backed Visitor Persistence
+// ---------------------------------------------------------------------------
+
+// If you need to persist bucketing decisions across experience config changes
+// (e.g. ensuring a visitor stays in the same variation even when rules change),
+// add KV support:
+//
+// 1. Add to Env: CONVERT_KV: KVNamespace;
+// 2. Add to wrangler.toml: [[kv_namespaces]] binding/id
+// 3. Use in the handler:
+//
+// import { KVDataStore } from '@convertcom/js-sdk-cloudflare';
+//
+// const dataStore = new KVDataStore(env.CONVERT_KV);
+// await dataStore.load(visitorId);
+// const context = convert.createContext(visitorId, { dataStore });
+// // ... run experiments ...
+// ctx.waitUntil(dataStore.save(visitorId));
diff --git a/demo/cloudflare-workers/tsconfig.json b/demo/cloudflare-workers/tsconfig.json
new file mode 100644
index 00000000..4a9d79a3
--- /dev/null
+++ b/demo/cloudflare-workers/tsconfig.json
@@ -0,0 +1,16 @@
+{
+ "compilerOptions": {
+ "target": "ES2022",
+ "module": "ES2022",
+ "moduleResolution": "bundler",
+ "lib": ["ES2022"],
+ "types": ["@cloudflare/workers-types"],
+ "strict": true,
+ "noEmit": true,
+ "skipLibCheck": true,
+ "forceConsistentCasingInFileNames": true,
+ "resolveJsonModule": true,
+ "isolatedModules": true
+ },
+ "include": ["src/**/*.ts"]
+}
diff --git a/demo/cloudflare-workers/wrangler.toml b/demo/cloudflare-workers/wrangler.toml
new file mode 100644
index 00000000..231e77e8
--- /dev/null
+++ b/demo/cloudflare-workers/wrangler.toml
@@ -0,0 +1,24 @@
+name = "convert-edge-experiments"
+main = "src/index.ts"
+compatibility_date = "2024-12-01"
+
+[vars]
+# Your Convert SDK key (account_id/project_id)
+CONVERT_SDK_KEY = "10035569/10034190"
+# Origin server URL — the Worker proxies to this and modifies the response.
+# For local testing: "http://localhost:8888"
+# For production: "https://your-site.com"
+ORIGIN_URL = "http://localhost:8888"
+
+# ------------------------------------------------------------------
+# Optional: KV namespace for persisting visitor bucketing data.
+# Only needed if you use KVDataStore (see demo/index.ts comments).
+# Most setups do NOT need this — the SDK uses deterministic bucketing.
+#
+# Create with: wrangler kv namespace create CONVERT_KV
+# Then uncomment and replace the id below.
+# ------------------------------------------------------------------
+# [[kv_namespaces]]
+# binding = "CONVERT_KV"
+# id = "YOUR_KV_NAMESPACE_ID"
+# preview_id = "YOUR_PREVIEW_NAMESPACE_ID"
diff --git a/package.json b/package.json
index f12b949d..bbc1a68e 100644
--- a/package.json
+++ b/package.json
@@ -12,7 +12,8 @@
"types:lint": "cd packages/types && yarn lint",
"utils:lint": "cd packages/utils && yarn lint",
"sdk:lint": "cd packages/js-sdk && yarn lint",
- "lint": "yarn enums:lint && yarn types:lint && yarn utils:lint && yarn event:lint && yarn bucketing:lint && yarn logger:lint && yarn rules:lint && yarn segments:lint && yarn api:lint && yarn data:lint && yarn experience:lint && yarn sdk:lint",
+ "cloudflare:lint": "cd packages/cloudflare && yarn lint",
+ "lint": "yarn enums:lint && yarn types:lint && yarn utils:lint && yarn event:lint && yarn bucketing:lint && yarn logger:lint && yarn rules:lint && yarn segments:lint && yarn api:lint && yarn data:lint && yarn experience:lint && yarn sdk:lint && yarn cloudflare:lint",
"api:build": "cd packages/api && yarn build",
"bucketing:build": "cd packages/bucketing && yarn build",
"data:build": "cd packages/data && yarn build",
@@ -25,7 +26,8 @@
"types:build": "cd packages/types && yarn build",
"utils:build": "cd packages/utils && yarn build",
"sdk:build": "cd packages/js-sdk && yarn build",
- "build": "yarn enums:build && yarn types:build && yarn utils:build && yarn event:build && yarn bucketing:build && yarn logger:build && yarn rules:build && yarn segments:build && yarn api:build && yarn data:build && yarn experience:build && yarn sdk:build",
+ "cloudflare:build": "cd packages/cloudflare && yarn build",
+ "build": "yarn enums:build && yarn types:build && yarn utils:build && yarn event:build && yarn bucketing:build && yarn logger:build && yarn rules:build && yarn segments:build && yarn api:build && yarn data:build && yarn experience:build && yarn sdk:build && yarn cloudflare:build",
"api:test": "cd packages/api && yarn test:mocha",
"bucketing:test": "cd packages/bucketing && yarn test:mocha",
"data:test": "cd packages/data && yarn test:mocha",
@@ -43,7 +45,8 @@
"demo:nestjs:start": "cd demo/nestjs && yarn start",
"demo:nextjs:start": "cd demo/nextjs && yarn start",
"demo:remixjs:client:start": "cd demo/remixjs-client-side && yarn dev",
- "demo:remixjs:server:start": "cd demo/remixjs-server-side && yarn dev"
+ "demo:remixjs:server:start": "cd demo/remixjs-server-side && yarn dev",
+ "demo:cloudflare:start": "cd demo/cloudflare-workers && yarn dev"
},
"private": true,
"workspaces": [
diff --git a/packages/cloudflare/README.md b/packages/cloudflare/README.md
new file mode 100644
index 00000000..bd861cc1
--- /dev/null
+++ b/packages/cloudflare/README.md
@@ -0,0 +1,79 @@
+# @convertcom/js-sdk-cloudflare
+
+Cloudflare Workers utilities for the [Convert JavaScript SDK](https://github.com/convertcom/javascript-sdk). Provides the glue code between the FullStack SDK and Cloudflare-specific APIs (HTMLRewriter, Workers Request/Response, edge caching).
+
+## Installation
+
+```bash
+npm install @convertcom/js-sdk @convertcom/js-sdk-cloudflare
+# or
+yarn add @convertcom/js-sdk @convertcom/js-sdk-cloudflare
+```
+
+## What's Included
+
+| Export | Purpose |
+|--------|---------|
+| `EdgeConfigCache` | Cache SDK config using Cloudflare's native `fetch` cache (no KV needed) |
+| `KVDataStore` | **Optional** KV-backed DataStore adapter for persisting bucketing decisions |
+| `getVisitorId` | Parse visitor ID from Workers Request cookies |
+| `setVisitorIdCookie` | Set visitor ID cookie on Workers Response |
+| `generateVisitorId` | Generate a new UUID visitor ID |
+| `buildCacheKey` | Create variation-aware cache keys for Cloudflare's Cache API |
+| `setCacheHeaders` | Set `Cache-Control` + `Vary: Cookie` headers |
+
+## Quick Start
+
+```typescript
+import ConvertSDK from '@convertcom/js-sdk';
+import {
+ EdgeConfigCache,
+ getVisitorId,
+ setVisitorIdCookie,
+ generateVisitorId
+} from '@convertcom/js-sdk-cloudflare';
+
+export default {
+ async fetch(request, env, ctx) {
+ // 1. Get config (cached at edge via Cloudflare's fetch cache — no KV)
+ const config = await new EdgeConfigCache(env.SDK_KEY).getConfig();
+
+ // 2. Init SDK
+ const sdk = new ConvertSDK({ data: config, network: { tracking: true } });
+ await sdk.onReady();
+
+ // 3. Identify visitor
+ const visitorId = getVisitorId(request) || generateVisitorId();
+
+ // 4. Run experiment (deterministic bucketing — no persistence needed)
+ const context = sdk.createContext(visitorId);
+ const variation = context.runExperience('my-experiment');
+
+ // 5. Modify the page with HTMLRewriter (zero flicker)
+ const origin = await fetch(request);
+ let response = origin;
+ if (variation?.key === 'variation-1') {
+ response = new HTMLRewriter()
+ .on('h1', { element(el) { el.setInnerContent('New Headline'); } })
+ .transform(origin);
+ }
+
+ // 6. Set cookie and respond
+ const headers = new Headers(response.headers);
+ setVisitorIdCookie(headers, visitorId);
+
+ // 7. Flush tracking events before Worker finishes
+ ctx.waitUntil(context.releaseQueues());
+
+ return new Response(response.body, { status: response.status, headers });
+ }
+};
+```
+
+## Documentation
+
+See the full guide: [Cloudflare Workers Edge Experimentation](https://github.com/convertcom/javascript-sdk/wiki/CloudflareWorkers)
+
+## License
+
+Apache-2.0
diff --git a/packages/cloudflare/index.ts b/packages/cloudflare/index.ts
new file mode 100644
index 00000000..640006de
--- /dev/null
+++ b/packages/cloudflare/index.ts
@@ -0,0 +1,14 @@
+/*!
+ * Convert JS SDK - Cloudflare Workers Utilities
+ * Version 1.0.0
+ * Copyright(c) 2020 Convert Insights, Inc
+ * License Apache-2.0
+ */
+export {KVDataStore} from './src/kv-data-store';
+export {EdgeConfigCache} from './src/edge-config-cache';
+export {
+ getVisitorId,
+ setVisitorIdCookie,
+ generateVisitorId
+} from './src/cookie-helpers';
+export {buildCacheKey, setCacheHeaders} from './src/cache-helpers';
diff --git a/packages/cloudflare/package.json b/packages/cloudflare/package.json
new file mode 100644
index 00000000..039ec5ca
--- /dev/null
+++ b/packages/cloudflare/package.json
@@ -0,0 +1,51 @@
+{
+ "name": "@convertcom/js-sdk-cloudflare",
+ "version": "1.0.0",
+ "description": "Cloudflare Workers utilities for Convert JavaScript SDK",
+ "main": "./lib/index.js",
+ "module": "./lib/index.mjs",
+ "types": "./lib/index.d.ts",
+ "files": [
+ "lib/**/**/*"
+ ],
+ "author": "Convert Insights, Inc",
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/convertcom/javascript-sdk.git",
+ "directory": "packages/cloudflare"
+ },
+ "license": "Apache-2.0",
+ "scripts": {
+ "clean": "rm -rf lib",
+ "prebuild": "yarn clean",
+ "build": "rollup -c ../../rollup.config.mjs",
+ "lint": "eslint src",
+ "lint:fix": "yarn lint -- --fix"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ },
+ "devDependencies": {
+ "@babel/cli": "^7.28.3",
+ "@babel/core": "^7.28.5",
+ "@babel/preset-env": "^7.28.5",
+ "@eslint/eslintrc": "^3.3.1",
+ "@rollup/plugin-babel": "^6.1.0",
+ "@rollup/plugin-commonjs": "^29.0.0",
+ "@rollup/plugin-terser": "^0.4.4",
+ "@typescript-eslint/parser": "^8.46.4",
+ "eslint": "^9.39.1",
+ "eslint-config-prettier": "^10.1.8",
+ "eslint-plugin-prettier": "^5.5.4",
+ "prettier": "^3.6.2",
+ "rollup": "^4.53.2",
+ "rollup-plugin-generate-package-json": "^3.2.0",
+ "rollup-plugin-modify": "^3.0.0",
+ "rollup-plugin-typescript2": "^0.36.0",
+ "typescript": "^5.9.3",
+ "typescript-eslint": "^8.46.4"
+ },
+ "peerDependencies": {
+ "@convertcom/js-sdk": ">=4.0.0"
+ }
+}
diff --git a/packages/cloudflare/src/cache-helpers.ts b/packages/cloudflare/src/cache-helpers.ts
new file mode 100644
index 00000000..039c1260
--- /dev/null
+++ b/packages/cloudflare/src/cache-helpers.ts
@@ -0,0 +1,59 @@
+/*!
+ * Convert JS SDK - Cloudflare Workers Utilities
+ * Version 1.0.0
+ * Copyright(c) 2020 Convert Insights, Inc
+ * License Apache-2.0
+ */
+
+/**
+ * Build a variation-aware cache key for Cloudflare's Cache API.
+ *
+ * Without this, Cloudflare's edge cache would serve the same cached response
+ * to all visitors regardless of their bucketed variation. By appending the
+ * variation key as a query parameter, each variation gets its own cache entry.
+ *
+ * @param request - The original incoming request
+ * @param variationKey - The bucketed variation key (e.g. 'variation-1')
+ * @returns A new Request with the variation key appended as a query parameter
+ *
+ * @example
+ * ```typescript
+ * const cacheKey = buildCacheKey(request, variation.key);
+ * const cache = caches.default;
+ * let response = await cache.match(cacheKey);
+ * if (!response) {
+ * response = await fetch(request);
+ * await cache.put(cacheKey, response.clone());
+ * }
+ * ```
+ */
+export function buildCacheKey(request: Request, variationKey: string): Request {
+ const url = new URL(request.url);
+ url.searchParams.set('_conv_v', variationKey);
+ return new Request(url.toString(), {
+ method: request.method,
+ headers: request.headers
+ });
+}
+
+/**
+ * Set cache control headers appropriate for A/B tested responses.
+ *
+ * Adds `Vary: Cookie` so that Cloudflare's cache correctly separates
+ * responses by visitor cookie. Sets a configurable max-age.
+ *
+ * @param headers - The response Headers object to modify
+ * @param maxAge - Cache max-age in seconds (default: 300 = 5 minutes)
+ */
+export function setCacheHeaders(headers: Headers, maxAge = 300): void {
+ headers.set('Cache-Control', `public, max-age=${maxAge}`);
+ // Ensure Vary includes Cookie so cached responses respect visitor bucketing
+ const existingVary = headers.get('Vary');
+ if (existingVary) {
+ if (!existingVary.toLowerCase().includes('cookie')) {
+ headers.set('Vary', `${existingVary}, Cookie`);
+ }
+ } else {
+ headers.set('Vary', 'Cookie');
+ }
+}
diff --git a/packages/cloudflare/src/cookie-helpers.ts b/packages/cloudflare/src/cookie-helpers.ts
new file mode 100644
index 00000000..a35ea7f8
--- /dev/null
+++ b/packages/cloudflare/src/cookie-helpers.ts
@@ -0,0 +1,54 @@
+/*!
+ * Convert JS SDK - Cloudflare Workers Utilities
+ * Version 1.0.0
+ * Copyright(c) 2020 Convert Insights, Inc
+ * License Apache-2.0
+ */
+
+const DEFAULT_COOKIE_NAME = 'convert_visitor_id';
+const DEFAULT_MAX_AGE = 31536000; // 1 year in seconds
+
+/**
+ * Extract the visitor ID from a Workers Request cookie header.
+ *
+ * @param request - The incoming Workers Request
+ * @param cookieName - Cookie name to read (default: 'convert_visitor_id')
+ * @returns The visitor ID string, or null if not found
+ */
+export function getVisitorId(
+ request: Request,
+ cookieName = DEFAULT_COOKIE_NAME
+): string | null {
+ const cookie = request.headers.get('Cookie') || '';
+ const escaped = cookieName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
+ const match = cookie.match(new RegExp(`(?:^|;)\\s*${escaped}=([^;]+)`));
+ return match ? decodeURIComponent(match[1]) : null;
+}
+
+/**
+ * Append a Set-Cookie header for the visitor ID on the response.
+ *
+ * @param headers - The response Headers object to modify
+ * @param visitorId - The visitor ID to persist
+ * @param cookieName - Cookie name to set (default: 'convert_visitor_id')
+ * @param maxAge - Cookie max-age in seconds (default: 31536000 = 1 year)
+ */
+export function setVisitorIdCookie(
+ headers: Headers,
+ visitorId: string,
+ cookieName = DEFAULT_COOKIE_NAME,
+ maxAge = DEFAULT_MAX_AGE
+): void {
+ headers.append(
+ 'Set-Cookie',
+ `${cookieName}=${encodeURIComponent(visitorId)}; Path=/; Max-Age=${maxAge}; SameSite=Lax; Secure; HttpOnly`
+ );
+}
+
+/**
+ * Generate a new unique visitor ID using crypto.randomUUID().
+ * Available in all Cloudflare Workers runtimes.
+ */
+export function generateVisitorId(): string {
+ return crypto.randomUUID();
+}
diff --git a/packages/cloudflare/src/edge-config-cache.ts b/packages/cloudflare/src/edge-config-cache.ts
new file mode 100644
index 00000000..51bc17f3
--- /dev/null
+++ b/packages/cloudflare/src/edge-config-cache.ts
@@ -0,0 +1,77 @@
+/*!
+ * Convert JS SDK - Cloudflare Workers Utilities
+ * Version 1.0.0
+ * Copyright(c) 2020 Convert Insights, Inc
+ * License Apache-2.0
+ */
+
+const DEFAULT_CONFIG_ENDPOINT = 'https://cdn-4.convertexperiments.com/api/v1';
+
+/**
+ * Caches the Convert SDK configuration using Cloudflare's built-in fetch cache.
+ *
+ * Instead of requiring a KV namespace, this leverages the `cf` option on
+ * `fetch()` to cache the config response at the edge. This is simpler,
+ * works on all Cloudflare plans, and avoids KV read/write costs.
+ *
+ * @see https://developers.cloudflare.com/workers/examples/cache-using-fetch/
+ *
+ * @example
+ * ```typescript
+ * const configCache = new EdgeConfigCache('YOUR_SDK_KEY');
+ * const configData = await configCache.getConfig();
+ *
+ * const sdk = new ConvertSDK({ data: configData });
+ * ```
+ */
+export class EdgeConfigCache {
+ private _sdkKey: string;
+ private _ttl: number;
+ private _configEndpoint: string;
+
+ /**
+ * @param sdkKey - Your Convert SDK key (e.g. 'ACCOUNT_ID/PROJECT_ID')
+ * @param ttl - Cache TTL in seconds (default: 300 = 5 minutes)
+ * @param configEndpoint - Override the config CDN endpoint
+ */
+ constructor(sdkKey: string, ttl = 300, configEndpoint?: string) {
+ this._sdkKey = sdkKey;
+ this._ttl = ttl;
+ this._configEndpoint = configEndpoint || DEFAULT_CONFIG_ENDPOINT;
+ }
+
+ /**
+ * Get the SDK configuration, served from Cloudflare's edge cache when
+ * available. Falls back to fetching from the Convert CDN if the cache
+ * entry has expired.
+ */
+ async getConfig(): Promise {
+ return this._fetch(this._ttl);
+ }
+
+ /**
+ * Force-refresh the configuration by bypassing the edge cache.
+ * Use this for manual cache invalidation (e.g. via a cron trigger or webhook).
+ */
+ async refreshConfig(): Promise {
+ return this._fetch(0);
+ }
+
+ private async _fetch(cacheTtl: number): Promise {
+ const url = `${this._configEndpoint}/config/${this._sdkKey}`;
+ // The `cf` property is a Cloudflare Workers extension to the standard
+ // fetch API that controls edge caching behaviour.
+ const response = await fetch(url, {
+ headers: {'Content-Type': 'application/json'},
+ cf: {cacheTtl, cacheEverything: true}
+ } as any);
+
+ if (!response.ok) {
+ throw new Error(
+ `Convert config fetch failed: ${response.status} ${response.statusText}`
+ );
+ }
+
+ return response.json();
+ }
+}
diff --git a/packages/cloudflare/src/kv-data-store.ts b/packages/cloudflare/src/kv-data-store.ts
new file mode 100644
index 00000000..7074feb4
--- /dev/null
+++ b/packages/cloudflare/src/kv-data-store.ts
@@ -0,0 +1,115 @@
+/*!
+ * Convert JS SDK - Cloudflare Workers Utilities
+ * Version 1.0.0
+ * Copyright(c) 2020 Convert Insights, Inc
+ * License Apache-2.0
+ */
+
+/**
+ * Minimal interface compatible with Cloudflare Workers KVNamespace.
+ * Avoids a hard dependency on @cloudflare/workers-types.
+ */
+interface KVNamespaceLike {
+ get(key: string): Promise;
+ put(
+ key: string,
+ value: string,
+ options?: {expirationTtl?: number}
+ ): Promise;
+}
+
+/**
+ * **Optional** DataStore adapter for Cloudflare Workers KV.
+ *
+ * This is NOT required for basic A/B testing. The SDK uses deterministic
+ * MurmurHash bucketing, so the same visitor ID always gets the same
+ * variation. You only need this if you want to:
+ *
+ * - Preserve bucketing across experience config changes
+ * - Store custom visitor attributes between requests
+ * - Share state across multiple Workers or routes
+ *
+ * The Convert SDK expects a synchronous DataStore (get/set).
+ * Since KV is async, this adapter works in three phases:
+ * 1. load() - async read from KV into memory (call before SDK operations)
+ * 2. get/set - sync read/write on in-memory snapshot (used by SDK)
+ * 3. save() - async write from memory back to KV (call after SDK operations)
+ *
+ * **Note:** Cloudflare KV is a paid feature and may not be available on all
+ * plans. For most use cases, cookie-based visitor identification with
+ * deterministic bucketing is sufficient without KV persistence.
+ *
+ * @example
+ * ```typescript
+ * const dataStore = new KVDataStore(env.CONVERT_KV);
+ * await dataStore.load(visitorId);
+ *
+ * const sdk = new ConvertSDK({ data: configData, dataStore });
+ * // ... run experiments ...
+ *
+ * await dataStore.save(visitorId);
+ * ```
+ */
+export class KVDataStore {
+ private _data: Record = {};
+ private _kv: KVNamespaceLike;
+ private _dirty = false;
+ private _prefix: string;
+
+ /**
+ * @param kv - A Cloudflare KV namespace binding
+ * @param prefix - Key prefix for KV entries (default: 'visitor')
+ */
+ constructor(kv: KVNamespaceLike, prefix = 'visitor') {
+ this._kv = kv;
+ this._prefix = prefix;
+ }
+
+ /**
+ * Load visitor data from KV into memory.
+ * Call this BEFORE creating the SDK context.
+ */
+ async load(visitorId: string): Promise {
+ const raw = await this._kv.get(`${this._prefix}:${visitorId}`);
+ try {
+ this._data = raw ? JSON.parse(raw) : {};
+ } catch (e) {
+ // Corrupted data in KV, start fresh for this visitor.
+ this._data = {};
+ }
+ this._dirty = false;
+ }
+
+ /**
+ * Get a value by key (synchronous, reads from memory).
+ * Called internally by the SDK.
+ */
+ get(key: string): any {
+ return this._data[key];
+ }
+
+ /**
+ * Set a value by key (synchronous, writes to memory).
+ * Called internally by the SDK.
+ */
+ set(key: string, value: any): void {
+ this._data[key] = value;
+ this._dirty = true;
+ }
+
+ /**
+ * Save visitor data from memory back to KV.
+ * Call this AFTER SDK operations are complete.
+ * @param visitorId - The visitor ID used in load()
+ * @param ttl - KV entry TTL in seconds (default: 86400 = 24 hours)
+ */
+ async save(visitorId: string, ttl = 86400): Promise {
+ if (!this._dirty) return;
+ await this._kv.put(
+ `${this._prefix}:${visitorId}`,
+ JSON.stringify(this._data),
+ {expirationTtl: ttl}
+ );
+ this._dirty = false;
+ }
+}
diff --git a/packages/js-sdk/TESTING.md b/packages/js-sdk/TESTING.md
new file mode 100644
index 00000000..4ee0f790
--- /dev/null
+++ b/packages/js-sdk/TESTING.md
@@ -0,0 +1,199 @@
+# Testing Guide
+
+This document covers how to run and write tests for the `@convertcom/js-sdk` package.
+
+## Prerequisites
+
+- Node.js >= 22
+- Yarn (via corepack: `corepack enable && corepack prepare yarn@stable --activate`)
+- Playwright Chromium browser: `npx playwright install --with-deps chromium`
+- Built SDK bundles (run `yarn build` before browser/integration tests)
+
+## Test Suites
+
+The SDK has three test suites:
+
+| Suite | Runner | Scope | Command |
+|-------|--------|-------|---------|
+| **Unit tests** | Mocha + Chai | Core logic, context, feature manager, utilities | `yarn test:mocha` |
+| **Browser tests** | Playwright | UMD bundle loaded in Chromium | `yarn test:browser` |
+| **Integration tests** | Playwright | Full SDK lifecycle (init, bucket, feature, conversion) | `yarn test:browser` |
+
+### Run everything
+
+```bash
+yarn build
+yarn test:mocha
+yarn test:browser
+```
+
+Or use the combined command (includes coverage):
+
+```bash
+yarn build
+yarn test
+```
+
+## Unit Tests (Mocha)
+
+Located in `tests/**/*.tests.ts`. These test SDK internals using Mocha + Chai with `ts-node/register`.
+
+```bash
+yarn test:mocha
+```
+
+Test files:
+- `tests/core.tests.ts` — Core class (init, context creation, events)
+- `tests/context.tests.ts` — Context class (runExperience, runFeature, trackConversion)
+- `tests/feature-manager.tests.ts` — Feature manager logic
+- `tests/utils/*.tests.ts` — Array, object, string, and comparison utilities
+
+These tests use `tests/test-config.json` (fabricated IDs) and do **not** require network access.
+
+## Browser Tests (Playwright)
+
+Located in `tests/browser/`. These verify the built UMD bundle works correctly in a real browser environment.
+
+```bash
+yarn build # Must build first — tests serve the built bundles
+yarn test:browser
+```
+
+**How it works:**
+1. Playwright starts a local HTTP server (`tests/browser/test-server.js`) on port 3939
+2. The server serves the built UMD bundle (`lib/index.umd.min.js`) and a test HTML page
+3. Tests navigate to the page and use `page.evaluate()` to exercise the SDK in browser context
+
+Test file:
+- `tests/browser/umd-bundle.spec.ts` — 19 tests covering SDK instantiation, experiences, features, conversions, segments, and invalid visitor handling
+
+These tests use `tests/test-config.json` (fabricated IDs) and do **not** require network access.
+
+## Integration Tests (Playwright)
+
+Located in `tests/integration/`. These run the full SDK lifecycle in Node.js context (not browser), matching the PHP SDK's `FullChainIntegrationTest` pattern.
+
+```bash
+yarn build # Must build first — tests import from lib/
+yarn test:browser # Integration tests run as part of the Playwright suite
+```
+
+Test file:
+- `tests/integration/full-chain.spec.ts` — 17 tests per mode covering:
+ - **Happy path:** init, ready event, experience bucketing, bucketing determinism, bucketing events, typed feature variables, full chain verification
+ - **Negative path:** unknown feature key, non-qualifying location, audience mismatch
+ - **Conversion tracking:** basic conversion, conversion events, goal deduplication, revenue tracking, forced multiple transactions, nonexistent goal
+ - **Complete chain:** init -> context -> bucket -> feature -> conversion -> flush
+
+### Auth Modes
+
+Integration tests run in up to 3 modes, following the PHP SDK pattern:
+
+| Mode | Config source | Env vars required | Always runs? |
+|------|--------------|-------------------|-------------|
+| `static` | `tests/integration/static-config.json` | None | Yes |
+| `live` | CDN fetch (public key) | `CONVERT_STAGING_SDK_KEY` | No |
+| `live-secret` | CDN fetch (authenticated) | `CONVERT_STAGING_SDK_KEY2`, `CONVERT_STAGING_SDK_KEY2_SECRET` | No |
+
+The `static` mode always runs using a snapshot of the staging project config. The `live` and `live-secret` modes are skipped when the corresponding env vars are not set.
+
+### Setting up env vars for live tests
+
+Copy `.env.example` to `.env` and fill in the values:
+
+```bash
+# Public SDK key for unauthenticated CDN fetch
+CONVERT_STAGING_SDK_KEY=
+
+# SDK key + secret for authenticated CDN fetch
+CONVERT_STAGING_SDK_KEY2=
+CONVERT_STAGING_SDK_KEY2_SECRET=
+```
+
+Then run with the env vars loaded:
+
+```bash
+export $(grep -v '^#' .env | xargs)
+yarn build
+yarn test:browser
+```
+
+### Staging Project
+
+All integration tests use the shared staging project **"FS-Test-Proj - DO NOT DELETE"** (account `10035569`, project `10034190`). This is the same project used by the PHP SDK's integration tests.
+
+Key entities:
+- **Experience:** `test-experience-ab-fullstack-4` — 50/50 split, pricing-location, no audiences
+- **Feature-1:** boolean `enabled`, string `caption`
+- **Feature-2:** float `price` (100), integer `button-height` (40), json `additionalData`
+- **Goals:** `increase-engagement` (dom_interaction, no rules), `decrease-bounce-rate` (advanced)
+
+**Do not modify or delete this project.** Changes will break integration tests in both the JS and PHP SDKs.
+
+## Playwright Configuration
+
+Config file: `playwright.config.ts`
+
+- **Test server:** Auto-started on port 3939 (configurable via `PORT` env var)
+- **Browser:** Chromium only, headless, with `--no-sandbox`
+- **Workers:** 1 (sequential execution — tests share SDK state)
+- **Timeout:** 60 seconds per test
+- **Retries:** 2 on CI, 0 locally
+- **Traces:** Retained on failure
+
+## CI
+
+Tests run in GitHub Actions via `.github/workflows/qa.yml`:
+
+```
+yarn → build → lint → test:mocha → test:browser
+```
+
+Live integration tests run in CI when the `CONVERT_STAGING_SDK_KEY`, `CONVERT_STAGING_SDK_KEY2`, and `CONVERT_STAGING_SDK_KEY2_SECRET` secrets are configured in the repository.
+
+## Writing New Tests
+
+### Adding a unit test
+
+Add a `.tests.ts` file under `tests/`. It will be picked up automatically by the mocha glob `tests/**/*.tests.ts`.
+
+```typescript
+import 'mocha';
+import {expect} from 'chai';
+
+describe('MyFeature', () => {
+ it('should do something', () => {
+ expect(true).to.be.true;
+ });
+});
+```
+
+### Adding a browser test
+
+Add assertions to `tests/browser/umd-bundle.spec.ts` or create a new `.spec.ts` file under `tests/browser/`.
+
+```typescript
+import {test, expect} from '@playwright/test';
+
+test('SDK does something in browser', async ({page}) => {
+ await page.goto('/');
+ const result = await page.evaluate(() => {
+ // ConvertSDK is available as a global from the UMD bundle
+ return typeof ConvertSDK;
+ });
+ expect(result).toBe('function');
+});
+```
+
+### Adding an integration test
+
+Add tests inside the `for (const mode of modes)` loop in `tests/integration/full-chain.spec.ts` to ensure they run in all auth modes.
+
+```typescript
+test('My new integration test', async () => {
+ const sdk = createSdk(mode);
+ await sdk.onReady();
+ const context = sdk.createContext('my-visitor-id');
+ // ... exercise SDK and assert
+});
+```
diff --git a/packages/js-sdk/index.browser.cjs.tests.js b/packages/js-sdk/index.browser.cjs.tests.js
deleted file mode 100644
index 4efa54ef..00000000
--- a/packages/js-sdk/index.browser.cjs.tests.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import * as ConvertSDK from './lib/index';
-import runTests from './index.tests';
-
-describe('Karma browser tests for CommonJS bundle', function () {
- // eslint-disable-next-line mocha/no-setup-in-describe
- runTests(ConvertSDK);
-});
diff --git a/packages/js-sdk/index.browser.umd.tests.js b/packages/js-sdk/index.browser.umd.tests.js
deleted file mode 100644
index 88982033..00000000
--- a/packages/js-sdk/index.browser.umd.tests.js
+++ /dev/null
@@ -1,12 +0,0 @@
-// No SDK library imports here. A UMD script should be already loaded in browser by karma
-import {assert} from 'chai';
-import runTests from './index.tests';
-
-describe('Karma browser tests for UMD bundle', function () {
- it('Should have an SDK instance in namespace', function () {
- // eslint-disable-next-line no-undef
- assert.isDefined(ConvertSDK);
- });
- // eslint-disable-next-line mocha/no-setup-in-describe,no-undef
- runTests(ConvertSDK);
-});
diff --git a/packages/js-sdk/index.tests.js b/packages/js-sdk/index.tests.js
deleted file mode 100644
index 053b6ffd..00000000
--- a/packages/js-sdk/index.tests.js
+++ /dev/null
@@ -1,247 +0,0 @@
-/* eslint-disable mocha/consistent-spacing-between-blocks */
-import {expect} from 'chai';
-import {assert} from 'chai';
-import testConfig from './tests/test-config.json';
-import {
- getFeaturesWithStatuses,
- getMultipleFeatureWithStatus,
- getSingleFeatureWithStatus,
- getVariationsAcrossAllExperiences
-} from './tests/setup/shared';
-
-class DataStore {
- data = {};
- get(key) {
- if (!key) return this.data;
- return this.data[key.toString()];
- }
- set(key, value) {
- if (!key) throw new Error('Invalid DataStore key!');
- this.data[key.toString()] = value;
- }
-}
-
-const dataStore = new DataStore();
-testConfig.dataStore = dataStore;
-testConfig.events = {
- batch_size: 1,
- release_interval: 1000
-};
-
-const accountId = testConfig.data.account_id;
-const projectId = testConfig.data.project.id;
-const visitorId = 'XXX';
-const storeKey = `${accountId}-${projectId}-${visitorId}`;
-
-const defaultSegments = {browser: 'chrome'};
-
-// eslint-disable-next-line mocha/no-exports
-export default function runTests(bundle) {
- const ConvertSDK = bundle.default;
- let convert, context;
- describe('Basic SDK instance', function () {
- // eslint-disable-next-line mocha/no-hooks-for-single-case
- beforeEach(function () {
- convert = new ConvertSDK(testConfig);
- });
- it('Should have an SDK instance as an object', function () {
- expect(bundle).to.be.an('object');
- });
- it('Should have a constructor', function () {
- expect(ConvertSDK).to.be.a('function');
- });
- it('Should create a default SDK instance and fire ready event. Expect no errors', function (done) {
- convert.on('ready', function (args, err) {
- expect(err).to.be.null;
- //expect(convert).to.have.property('version').which.is.a('string');
- expect(convert).to.be.an('object');
- done();
- });
- });
- it('Should create a default SDK instance and resolve a promise. Expect no errors', async function () {
- await convert.onReady();
- assert.equal(true, true);
- });
- it('Shoud successfully create visitor context', function () {
- const visitorContext = convert.createContext(visitorId, defaultSegments);
- expect(visitorContext).to.be.an('object');
- [
- 'runExperience',
- 'runExperiences',
- 'runFeature',
- 'runFeatures',
- 'trackConversion',
- 'setDefaultSegments',
- 'runCustomSegments'
- ].forEach((method) => {
- expect(visitorContext).to.have.a.property(method);
- });
- });
- });
- describe('Basic SDK methods', function () {
- // eslint-disable-next-line mocha/no-hooks-for-single-case
- before(function () {
- convert = new ConvertSDK(testConfig);
- });
- // eslint-disable-next-line mocha/no-hooks-for-single-case
- beforeEach(function () {
- context = convert.createContext(visitorId, defaultSegments);
- });
- it('Shoud successfully get variation from specific experience', function (done) {
- const experienceKey = 'test-experience-ab-fullstack-2';
- const variation = context.runExperience(experienceKey, {
- locationProperties: {url: 'https://convert.com/'},
- visitorProperties: {
- varName3: 'something'
- }
- });
- expect(variation)
- .to.be.an('object')
- .that.have.keys(
- 'experienceId',
- 'experienceKey',
- 'experienceName',
- 'bucketingAllocation',
- 'id',
- 'key',
- 'name',
- 'status',
- 'changes',
- 'is_baseline',
- 'traffic_allocation'
- );
- expect(variation.experienceKey).to.equal(experienceKey);
- done();
- });
- it('Shoud successfully get variations across all experiences', function (done) {
- getVariationsAcrossAllExperiences(
- {
- accountId,
- projectId,
- context
- },
- done
- );
- });
- it('Shoud successfully get a single feature and its status', function (done) {
- const featureId = '10025';
- getSingleFeatureWithStatus(
- {
- accountId,
- projectId,
- featureId,
- context
- },
- done
- );
- });
- it('Shoud successfully get multiple features and its status', function (done) {
- getMultipleFeatureWithStatus(
- {
- accountId,
- projectId,
- context
- },
- done
- );
- });
- it('Shoud successfully get features and their statuses', function (done) {
- getFeaturesWithStatuses(
- {
- accountId,
- projectId,
- context
- },
- done
- );
- });
- it('Should trigger Conversion', function () {
- const goalKey = 'increase-engagement';
- const response = context.trackConversion(goalKey, {
- ruleData: {
- action: 'buy'
- },
- conversionData: [
- {
- key: 'amount',
- value: 10.3
- },
- {
- key: 'productsCount',
- value: 2
- }
- ]
- });
- expect(response).to.be.undefined;
- });
- it('Should successfully set default segments', function (done) {
- const segments = {country: 'US'};
- context.setDefaultSegments(segments);
- setTimeout(function () {
- const localSegments = dataStore.get(storeKey);
- expect(localSegments)
- .to.have.property('segments')
- .that.deep.equal({
- ...segments,
- ...defaultSegments
- });
- done();
- }, testConfig.events.release_interval + 1);
- });
- it('Should successfully set custom segments', function (done) {
- const segmentKey = 'test-segments-1';
- const segmentId = '200299434';
- context.runCustomSegments(segmentKey, {
- ruleData: {
- enabled: true
- }
- });
- setTimeout(function () {
- const {segments} = dataStore.get(storeKey) || {};
- expect(segments)
- .to.be.an('object')
- .that.has.property('customSegments')
- .to.deep.equal([segmentId]);
- done();
- }, testConfig.events.release_interval + 1);
- });
- });
- describe('Test invalid visitor', function () {
- // eslint-disable-next-line mocha/no-hooks-for-single-case
- before(function () {
- convert = new ConvertSDK(testConfig);
- });
- // eslint-disable-next-line mocha/no-hooks-for-single-case
- beforeEach(function () {
- context = convert.createContext();
- });
- it('Shoud fail to get variation from specific experience if no visitor is set', function () {
- const experienceKey = 'test-experience-ab-fullstack-2';
- const variation = context.runExperience(experienceKey);
- expect(variation).to.be.undefined;
- });
- it('Shoud fail to get variations across all experiences if no visitor is set', function () {
- const variations = context.runExperiences();
- expect(variations).to.be.undefined;
- });
- it('Shoud fail to get feature and its status if no visitor is set', function () {
- const featureKey = 'feature-1';
- const features = context.runFeature(featureKey);
- expect(features).to.be.undefined;
- });
- it('Shoud fail to get features and their statuses if no visitor is set', function () {
- const features = context.runFeatures();
- expect(features).to.be.undefined;
- });
- it('Should fail to trigger Conversion if no visitor is set', function () {
- const goalKey = 'increase-engagement';
- const output = context.trackConversion(goalKey);
- expect(output).to.be.undefined;
- });
- it('Should fail to set custom segments if no visitor is set', function () {
- const segmentKey = 'test-segments-1';
- const output = context.runCustomSegments(segmentKey);
- expect(output).to.be.undefined;
- });
- });
-}
diff --git a/packages/js-sdk/karma.base.conf.js b/packages/js-sdk/karma.base.conf.js
deleted file mode 100644
index cdde42e4..00000000
--- a/packages/js-sdk/karma.base.conf.js
+++ /dev/null
@@ -1,104 +0,0 @@
-// eslint-disable-next-line @typescript-eslint/no-var-requires
-const dotenv = require('dotenv');
-// eslint-disable-next-line @typescript-eslint/no-var-requires
-const path = require('path');
-dotenv.config();
-// eslint-disable-next-line @typescript-eslint/no-var-requires
-process.env.CHROME_BIN = require('puppeteer').executablePath();
-module.exports = {
- // base path that will be used to resolve all patterns (eg. files, exclude)
- basePath: './',
-
- // frameworks to use
- // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
- frameworks: ['mocha', 'chai', 'webpack'],
-
- // list of files / patterns to load in the browser
- files: [],
-
- // list of files / patterns to exclude
- exclude: [],
-
- // preprocess matching files before serving them to the browser
- // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
- preprocessors: {},
-
- plugins: [
- 'karma-mocha',
- 'karma-chai',
- 'karma-webpack',
- 'karma-chrome-launcher',
- require('karma-browserstack-launcher'),
- 'karma-mocha-reporter'
- ],
- // test results reporter to use
- // possible values: 'dots', 'progress'
- // available reporters: https://npmjs.org/browse/keyword/karma-reporter
- // reporters: ['progress'],
- reporters: ['mocha', 'BrowserStack'],
-
- // web server port
- port: 9876,
-
- // enable / disable colors in the output (reporters and logs)
- colors: true,
-
- // enable / disable watching file and executing tests whenever any file changes
- autoWatch: false,
-
- // Continuous Integration mode
- // if true, Karma captures browsers, runs the tests and exits
- singleRun: true,
-
- // Concurrency level
- // how many browser should be started simultaneous
- concurrency: Infinity,
-
- browserStack: {
- username: process.env.BROWSER_STACK_USERNAME,
- accessKey: process.env.BROWSER_STACK_ACCESS,
- startTunnel: true
- },
- webpack: {
- mode: 'production',
- devtool: 'inline-source-map',
- performance: {
- hints: false
- }
- },
- // define browsers
- customLaunchers: {
- bs_firefox100_win10: {
- base: 'BrowserStack',
- os: 'Windows',
- os_version: '10',
- browser: 'firefox',
- device: null,
- browser_version: '100.0',
- real_mobile: null
- },
- bs_chrome_100_osx: {
- base: 'BrowserStack',
- os: 'OS X',
- os_version: 'Mojave',
- browser: 'chrome',
- device: null,
- browser_version: '100.0',
- real_mobile: null
- },
- custom_chrome_headless: {
- base: 'ChromeHeadless',
- chromeDataDir: path.resolve(__dirname, 'webpack-build/.chrome-karma'),
- flags: [
- '--disable-gpu',
- '--no-sandbox',
- '--crash-dumps-dir=' +
- path.resolve(__dirname, 'webpack-build/.chrome-karma-crash')
- ]
- }
- },
-
- // start these browsers
- // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
- browsers: ['custom_chrome_headless']
-};
diff --git a/packages/js-sdk/karma.cjs.conf.js b/packages/js-sdk/karma.cjs.conf.js
deleted file mode 100644
index 735db53b..00000000
--- a/packages/js-sdk/karma.cjs.conf.js
+++ /dev/null
@@ -1,28 +0,0 @@
-// Karma configuration
-// eslint-disable-next-line @typescript-eslint/no-var-requires
-const baseConfig = require('./karma.base.conf.js');
-// eslint-disable-next-line @typescript-eslint/no-var-requires
-const path = require('path');
-// eslint-disable-next-line @typescript-eslint/no-var-requires
-const os = require('os');
-module.exports = function (config) {
- config.set({
- ...baseConfig,
-
- files: [{pattern: './index.browser.cjs.tests.js'}],
- preprocessors: {
- './index.browser.cjs.tests.js': ['webpack']
- },
- webpack: {
- output: {
- filename: '[name].js',
- path:
- path.join(os.tmpdir(), '_karma_webpack_') +
- Math.floor(Math.random() * 1000000)
- }
- },
- // level of logging
- // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
- logLevel: config.LOG_INFO
- });
-};
diff --git a/packages/js-sdk/karma.umd.conf.js b/packages/js-sdk/karma.umd.conf.js
deleted file mode 100644
index 10f596d8..00000000
--- a/packages/js-sdk/karma.umd.conf.js
+++ /dev/null
@@ -1,30 +0,0 @@
-// Karma configuration
-// eslint-disable-next-line @typescript-eslint/no-var-requires
-const baseConfig = require('./karma.base.conf.js');
-// eslint-disable-next-line @typescript-eslint/no-var-requires
-const path = require('path');
-// eslint-disable-next-line @typescript-eslint/no-var-requires
-const os = require('os');
-module.exports = function (config) {
- config.set({
- ...baseConfig,
- // list of files / patterns to load in the browser
- files: ['./lib/index.umd.min.js', './index.browser.umd.tests.js'],
- // preprocess matching files before serving them to the browser
- // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
- preprocessors: {
- './index.browser.umd.tests.js': ['webpack']
- },
- webpack: {
- output: {
- filename: '[name].js',
- path:
- path.join(os.tmpdir(), '_karma_webpack_') +
- Math.floor(Math.random() * 1000000)
- }
- },
- // level of logging
- // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
- logLevel: config.LOG_INFO
- });
-};
diff --git a/packages/js-sdk/package.json b/packages/js-sdk/package.json
index bafceeb9..8bb9c249 100644
--- a/packages/js-sdk/package.json
+++ b/packages/js-sdk/package.json
@@ -16,12 +16,10 @@
},
"license": "Apache-2.0",
"scripts": {
- "pretest": "mkdir -p webpack-build && rm -rf coverage",
+ "pretest": "rm -rf coverage",
"test": "nyc yarn test:all && yarn coverage",
"test:all": "yarn test:mocha && yarn test:browser",
- "test:browser": "yarn build && yarn test:cjsbrowser && yarn test:umdbrowser",
- "test:cjsbrowser": "karma start karma.cjs.conf.js --single-run",
- "test:umdbrowser": "karma start karma.umd.conf.js --single-run",
+ "test:browser": "playwright test --config playwright.config.ts --project chromium",
"test:server": "nyc yarn test:mocha",
"test:mocha": "mocha -r ts-node/register --recursive \"tests/**/*.tests.ts\" --exit",
"clean": "rm -rf lib",
@@ -43,6 +41,7 @@
"@babel/preset-env": "^7.28.5",
"@eslint/eslintrc": "^3.3.1",
"@jsdoc/salty": "^0.2.9",
+ "@playwright/test": "^1.52.0",
"@rollup/plugin-babel": "^6.1.0",
"@rollup/plugin-commonjs": "^29.0.0",
"@rollup/plugin-json": "^6.1.0",
@@ -68,20 +67,9 @@
"eslint-plugin-prettier": "^5.5.4",
"glob": "^11.0.3",
"istanbul-cobertura-badger": "^1.3.1",
- "karma": "^6.4.4",
- "karma-browserify": "^8.1.0",
- "karma-browserstack-launcher": "^1.6.0",
- "karma-chai": "^0.1.0",
- "karma-chrome-launcher": "^3.2.0",
- "karma-cli": "^2.0.0",
- "karma-mocha": "^2.0.1",
- "karma-mocha-reporter": "^2.2.5",
- "karma-sourcemap-loader": "^0.4.0",
- "karma-webpack": "5.0.1",
"mocha": "^11.7.5",
"nyc": "^17.1.0",
"prettier": "^3.6.2",
- "puppeteer": "^24.29.1",
"rollup": "^4.53.2",
"rollup-plugin-copy": "^3.5.0",
"rollup-plugin-generate-package-json": "^3.2.0",
@@ -97,15 +85,6 @@
"watchify": "^4.0.0",
"webpack": "^5.102.1"
},
- "overrides": {
- "karma-browserstack-launcher": {
- "browserstack": {
- ".": "1.6.1",
- "https-proxy-agent": "7.0.4"
- },
- "browserstack-local": "1.5.5"
- }
- },
"version": "4.3.4",
"peerDependencies": {
"@convertcom/js-sdk-api": ">=2.1.4",
diff --git a/packages/js-sdk/playwright.config.ts b/packages/js-sdk/playwright.config.ts
new file mode 100644
index 00000000..e3654dbf
--- /dev/null
+++ b/packages/js-sdk/playwright.config.ts
@@ -0,0 +1,51 @@
+import {defineConfig, devices} from '@playwright/test';
+
+const PORT = process.env.PORT || 3939;
+
+/**
+ * Playwright configuration for JS SDK browser and integration tests.
+ * See https://playwright.dev/docs/test-configuration.
+ */
+export default defineConfig({
+ testDir: './tests',
+ testMatch: ['browser/**/*.spec.ts', 'integration/**/*.spec.ts'],
+ /* Run tests sequentially — SDK tests share state */
+ fullyParallel: false,
+ /* Fail the build on CI if you accidentally left test.only in the source code. */
+ forbidOnly: !!process.env.CI,
+ /* Retry on CI only */
+ retries: process.env.CI ? 2 : 0,
+ /* Single worker to avoid port conflicts and shared state issues */
+ workers: 1,
+ /* Reporter to use */
+ reporter: [['list']],
+ /* Shared settings for all the projects below */
+ use: {
+ /* Base URL to use in actions like `await page.goto('/')`. */
+ baseURL: `http://localhost:${PORT}`,
+ /* Collect trace when retrying the failed test */
+ trace: 'retain-on-failure'
+ },
+ /* Each test is given 60 seconds */
+ timeout: 60_000,
+
+ /* Configure projects for major browsers */
+ projects: [
+ {
+ name: 'chromium',
+ use: {
+ ...devices['Desktop Chrome'],
+ launchOptions: {
+ args: ['--disable-gpu', '--no-sandbox']
+ }
+ }
+ }
+ ],
+
+ /* Run local test server before starting the tests */
+ webServer: {
+ command: `node tests/browser/test-server.js`,
+ url: `http://localhost:${PORT}`,
+ reuseExistingServer: false
+ }
+});
diff --git a/packages/js-sdk/tests/browser/test-page.html b/packages/js-sdk/tests/browser/test-page.html
new file mode 100644
index 00000000..e2a79f5a
--- /dev/null
+++ b/packages/js-sdk/tests/browser/test-page.html
@@ -0,0 +1,26 @@
+
+
+
+
+
+ JS SDK Browser Test
+
+
+
+
+
+
+
diff --git a/packages/js-sdk/tests/browser/test-server.js b/packages/js-sdk/tests/browser/test-server.js
new file mode 100644
index 00000000..ae73e0d9
--- /dev/null
+++ b/packages/js-sdk/tests/browser/test-server.js
@@ -0,0 +1,52 @@
+const http = require('http');
+const fs = require('fs');
+const path = require('path');
+
+const PORT = process.env.PORT || 3939;
+const ROOT = path.resolve(__dirname, '..', '..');
+
+const MIME_TYPES = {
+ '.html': 'text/html',
+ '.js': 'application/javascript',
+ '.mjs': 'application/javascript',
+ '.json': 'application/json',
+ '.css': 'text/css'
+};
+
+const ROUTES = {
+ '/': path.join(ROOT, 'tests/browser/test-page.html'),
+ '/umd.html': path.join(ROOT, 'tests/browser/test-page.html'),
+ '/lib/index.js': path.join(ROOT, 'lib/index.js'),
+ '/lib/index.umd.min.js': path.join(ROOT, 'lib/index.umd.min.js'),
+ '/test-config.json': path.join(ROOT, 'tests/test-config.json'),
+ '/static-config.json': path.join(
+ ROOT,
+ 'tests/integration/static-config.json'
+ )
+};
+
+const server = http.createServer((req, res) => {
+ const url = req.url.split('?')[0];
+ const filePath = ROUTES[url];
+
+ if (!filePath) {
+ res.writeHead(404, {'Content-Type': 'text/plain'});
+ res.end('Not Found');
+ return;
+ }
+
+ try {
+ const content = fs.readFileSync(filePath);
+ const ext = path.extname(filePath);
+ const contentType = MIME_TYPES[ext] || 'application/octet-stream';
+ res.writeHead(200, {'Content-Type': contentType});
+ res.end(content);
+ } catch (err) {
+ res.writeHead(500, {'Content-Type': 'text/plain'});
+ res.end('Internal Server Error: ' + err.message);
+ }
+});
+
+server.listen(PORT, () => {
+ console.log(`Test server listening on http://localhost:${PORT}`);
+});
diff --git a/packages/js-sdk/tests/browser/umd-bundle.spec.ts b/packages/js-sdk/tests/browser/umd-bundle.spec.ts
new file mode 100644
index 00000000..3779685a
--- /dev/null
+++ b/packages/js-sdk/tests/browser/umd-bundle.spec.ts
@@ -0,0 +1,365 @@
+import {test, expect, Page} from '@playwright/test';
+
+// Helper: navigate to UMD test page and wait for config to load
+async function setupPage(page: Page) {
+ await page.goto('/umd.html');
+ await page.waitForFunction(
+ () => (window as any).__CONFIG_LOADED__ === true,
+ {timeout: 5000}
+ );
+}
+
+// Helper: inject SDK factory and DataStore onto window so page.evaluate()
+// callbacks can call window.__createSdk() / window.__createContext() without
+// repeating the boilerplate every time.
+async function injectHelpers(page: Page) {
+ await page.evaluate(() => {
+ const w = window as any;
+ w.__createSdk = (extraConfig?: Record) => {
+ const config = {...w.__TEST_CONFIG__};
+ config.events = {batch_size: 1, release_interval: 1000};
+ Object.assign(config, extraConfig || {});
+ return new w.ConvertSDK.default(config);
+ };
+ w.__createContext = (
+ visitorId?: string,
+ visitorProps?: Record,
+ extraConfig?: Record
+ ) => {
+ const sdk = w.__createSdk(extraConfig);
+ return sdk.createContext(visitorId, visitorProps);
+ };
+ // Shorthand: create context with default test visitor
+ w.__defaultContext = (extraConfig?: Record) =>
+ w.__createContext('XXX', {browser: 'chrome'}, extraConfig);
+ w.__makeDataStore = () => ({
+ data: {} as Record,
+ get(key: string) {
+ if (!key) return this.data;
+ return this.data[key.toString()];
+ },
+ set(key: string, value: any) {
+ if (!key) throw new Error('Invalid DataStore key!');
+ this.data[key.toString()] = value;
+ }
+ });
+ w.__createSegmentTestContext = () => {
+ const dataStore = w.__makeDataStore();
+ const sdk = w.__createSdk({dataStore});
+ const accountId = w.__TEST_CONFIG__.data.account_id;
+ const projectId = w.__TEST_CONFIG__.data.project.id;
+ const visitorId = 'XXX';
+ const storeKey = `${accountId}-${projectId}-${visitorId}`;
+ const context = sdk.createContext(visitorId, {browser: 'chrome'});
+ return {context, dataStore, storeKey};
+ };
+ });
+}
+
+// Combined setup: navigate + inject helpers
+async function setup(page: Page) {
+ await setupPage(page);
+ await injectHelpers(page);
+}
+
+// Qualifying attributes used across multiple tests
+const LOCATION_PROPS = {
+ locationProperties: {url: 'https://convert.com/'},
+ visitorProperties: {varName3: 'something'}
+};
+
+// Expected object keys for SDK return types (pre-sorted for assertion)
+const cmp = (a: string, b: string) => a.localeCompare(b);
+const VARIATION_KEYS = [
+ 'bucketingAllocation', 'changes', 'experienceId', 'experienceKey',
+ 'experienceName', 'id', 'is_baseline', 'key', 'name', 'status',
+ 'traffic_allocation'
+].sort(cmp);
+const FEATURE_KEYS = [
+ 'experienceId', 'experienceKey', 'experienceName', 'id', 'key',
+ 'name', 'status', 'variables'
+].sort(cmp);
+const FEATURE_DISABLED_KEYS = ['id', 'key', 'name', 'status'].sort(cmp);
+
+test.describe('UMD bundle browser tests', () => {
+ test.describe('Basic SDK instance', () => {
+ test('Should have ConvertSDK as a global', async ({page}) => {
+ await setupPage(page);
+ const hasSDK = await page.evaluate(
+ () => typeof (window as any).ConvertSDK !== 'undefined'
+ );
+ expect(hasSDK).toBe(true);
+ });
+
+ test('Should have a constructor', async ({page}) => {
+ await setupPage(page);
+ const isFunction = await page.evaluate(
+ () => typeof (window as any).ConvertSDK.default === 'function'
+ );
+ expect(isFunction).toBe(true);
+ });
+
+ test('Should create a default SDK instance and fire ready event with no errors', async ({
+ page
+ }) => {
+ await setup(page);
+ const result = await page.evaluate(() => {
+ return new Promise((resolve) => {
+ const sdk = (window as any).__createSdk();
+ sdk.on('ready', (_args: any, err: any) => {
+ resolve({hasError: err !== null, isObject: typeof sdk === 'object'});
+ });
+ });
+ });
+ expect((result as any).hasError).toBe(false);
+ expect((result as any).isObject).toBe(true);
+ });
+
+ test('Should create a default SDK instance and resolve onReady promise', async ({
+ page
+ }) => {
+ await setup(page);
+ const resolved = await page.evaluate(async () => {
+ const sdk = (window as any).__createSdk();
+ await sdk.onReady();
+ return true;
+ });
+ expect(resolved).toBe(true);
+ });
+
+ test('Should successfully create visitor context', async ({page}) => {
+ await setup(page);
+ const result = await page.evaluate(() => {
+ const context = (window as any).__defaultContext();
+ const methods = [
+ 'runExperience',
+ 'runExperiences',
+ 'runFeature',
+ 'runFeatures',
+ 'trackConversion',
+ 'setDefaultSegments',
+ 'runCustomSegments'
+ ];
+ const hasMethods = methods.every(
+ (m) => typeof context[m] === 'function'
+ );
+ return {isObject: typeof context === 'object', hasMethods};
+ });
+ expect((result as any).isObject).toBe(true);
+ expect((result as any).hasMethods).toBe(true);
+ });
+ });
+
+ test.describe('Basic SDK methods', () => {
+ test('Should successfully get variation from specific experience', async ({
+ page
+ }) => {
+ await setup(page);
+ const result = await page.evaluate((props) => {
+ const context = (window as any).__defaultContext();
+ const variation = context.runExperience(
+ 'test-experience-ab-fullstack-2',
+ props
+ );
+ return {
+ isObject: typeof variation === 'object' && variation !== null,
+ experienceKey: variation?.experienceKey,
+ keys: variation ? Object.keys(variation).sort((a, b) => a.localeCompare(b)) : []
+ };
+ }, LOCATION_PROPS);
+ expect((result as any).isObject).toBe(true);
+ expect((result as any).experienceKey).toBe(
+ 'test-experience-ab-fullstack-2'
+ );
+ expect((result as any).keys).toEqual(VARIATION_KEYS);
+ });
+
+ test('Should successfully get variations across all experiences', async ({
+ page
+ }) => {
+ await setup(page);
+ const result = await page.evaluate((props) => {
+ const context = (window as any).__defaultContext();
+ const variations = context.runExperiences(props);
+ return {
+ isArray: Array.isArray(variations),
+ length: variations?.length,
+ ids: variations?.map((v: any) => v.id)
+ };
+ }, LOCATION_PROPS);
+ expect((result as any).isArray).toBe(true);
+ expect((result as any).length).toBe(2);
+ const validIds = ['100299456', '100299457', '100299460', '100299461'];
+ for (const id of (result as any).ids) {
+ expect(validIds).toContain(id);
+ }
+ });
+
+ test('Should successfully get a single feature and its status', async ({
+ page
+ }) => {
+ await setup(page);
+ const result = await page.evaluate((props) => {
+ const context = (window as any).__defaultContext();
+ const feature = context.runFeature('feature-2', props);
+ return {
+ isObject: typeof feature === 'object' && feature !== null,
+ id: feature?.id,
+ keys: feature ? Object.keys(feature).sort((a, b) => a.localeCompare(b)) : []
+ };
+ }, LOCATION_PROPS);
+ expect((result as any).isObject).toBe(true);
+ expect((result as any).id).toBe('10025');
+ expect((result as any).keys).toEqual(FEATURE_KEYS);
+ });
+
+ test('Should successfully get multiple features and their status', async ({
+ page
+ }) => {
+ await setup(page);
+ const result = await page.evaluate((props) => {
+ const context = (window as any).__defaultContext();
+ const features = context.runFeature('feature-1', props);
+ return {
+ isArray: Array.isArray(features),
+ length: features?.length,
+ ids: features?.map((f: any) => f.id)
+ };
+ }, LOCATION_PROPS);
+ expect((result as any).isArray).toBe(true);
+ expect((result as any).length).toBe(2);
+ const validIds = ['10024', '10025'];
+ for (const id of (result as any).ids) {
+ expect(validIds).toContain(id);
+ }
+ });
+
+ test('Should successfully get features and their statuses', async ({
+ page
+ }) => {
+ await setup(page);
+ const result = await page.evaluate((props) => {
+ const context = (window as any).__defaultContext();
+ const features = context.runFeatures(props);
+ return {
+ isArray: Array.isArray(features),
+ length: features?.length,
+ ids: features?.map((f: any) => f.id),
+ enabledKeys: features
+ ?.filter((f: any) => f.status === 'enabled')
+ .map((f: any) => Object.keys(f).sort((a, b) => a.localeCompare(b))),
+ disabledKeys: features
+ ?.filter((f: any) => f.status === 'disabled')
+ .map((f: any) => Object.keys(f).sort((a, b) => a.localeCompare(b)))
+ };
+ }, LOCATION_PROPS);
+ expect((result as any).isArray).toBe(true);
+ expect((result as any).length).toBe(4);
+ const validIds = ['10024', '10025', '10026'];
+ for (const id of (result as any).ids.filter(
+ (id: string) => id !== undefined
+ )) {
+ expect(validIds).toContain(id);
+ }
+ for (const keys of (result as any).enabledKeys) {
+ expect(keys).toEqual(FEATURE_KEYS);
+ }
+ for (const keys of (result as any).disabledKeys) {
+ expect(keys).toEqual(FEATURE_DISABLED_KEYS);
+ }
+ });
+
+ test('Should trigger Conversion', async ({page}) => {
+ await setup(page);
+ const result = await page.evaluate((props) => {
+ const context = (window as any).__defaultContext();
+ context.runExperience('test-experience-ab-fullstack-2', props);
+ const response = context.trackConversion('increase-engagement', {
+ ruleData: {action: 'buy'},
+ conversionData: [
+ {key: 'amount', value: 10.3},
+ {key: 'productsCount', value: 2}
+ ]
+ });
+ return {isUndefined: response === undefined};
+ }, LOCATION_PROPS);
+ expect((result as any).isUndefined).toBe(true);
+ });
+
+ test('Should successfully set default segments', async ({page}) => {
+ await setup(page);
+ const result = await page.evaluate(() => {
+ return new Promise((resolve) => {
+ const {context, dataStore, storeKey} = (
+ window as any
+ ).__createSegmentTestContext();
+ context.setDefaultSegments({country: 'US'});
+
+ setTimeout(() => {
+ const localSegments = dataStore.get(storeKey);
+ resolve({
+ hasSegments: localSegments?.segments !== undefined,
+ segments: localSegments?.segments
+ });
+ }, 1100);
+ });
+ });
+ expect((result as any).hasSegments).toBe(true);
+ expect((result as any).segments).toEqual({
+ country: 'US',
+ browser: 'chrome'
+ });
+ });
+
+ test('Should successfully set custom segments', async ({page}) => {
+ await setup(page);
+ const result = await page.evaluate(() => {
+ return new Promise((resolve) => {
+ const {context, dataStore, storeKey} = (
+ window as any
+ ).__createSegmentTestContext();
+ context.runCustomSegments('test-segments-1', {
+ ruleData: {enabled: true}
+ });
+
+ setTimeout(() => {
+ const data = dataStore.get(storeKey);
+ resolve({
+ hasCustomSegments:
+ data?.segments?.customSegments !== undefined,
+ customSegments: data?.segments?.customSegments
+ });
+ }, 1100);
+ });
+ });
+ expect((result as any).hasCustomSegments).toBe(true);
+ expect((result as any).customSegments).toEqual(['200299434']);
+ });
+ });
+
+ test.describe('Test invalid visitor', () => {
+ // All SDK methods should return undefined when no visitor ID is set
+ const invalidVisitorCases = [
+ {method: 'runExperience', args: ['test-experience-ab-fullstack-2']},
+ {method: 'runExperiences', args: []},
+ {method: 'runFeature', args: ['feature-1']},
+ {method: 'runFeatures', args: []},
+ {method: 'trackConversion', args: ['increase-engagement']},
+ {method: 'runCustomSegments', args: ['test-segments-1']}
+ ];
+
+ for (const {method, args} of invalidVisitorCases) {
+ test(`Should fail ${method} if no visitor is set`, async ({page}) => {
+ await setup(page);
+ const result = await page.evaluate(
+ ({m, a}) => {
+ const context = (window as any).__createContext();
+ return context[m](...a);
+ },
+ {m: method, a: args}
+ );
+ expect(result).toBeUndefined();
+ });
+ }
+ });
+});
diff --git a/packages/js-sdk/tests/integration/full-chain.spec.ts b/packages/js-sdk/tests/integration/full-chain.spec.ts
new file mode 100644
index 00000000..5aba02e1
--- /dev/null
+++ b/packages/js-sdk/tests/integration/full-chain.spec.ts
@@ -0,0 +1,462 @@
+import {test, expect} from '@playwright/test';
+
+// Import from the built CJS bundle — same as consumers would use
+// eslint-disable-next-line @typescript-eslint/no-var-requires
+const SDK = require('../../lib/index');
+const ConvertSDK = SDK.default;
+const {SystemEvents} = SDK;
+
+// Static config for offline/always-run mode
+// eslint-disable-next-line @typescript-eslint/no-var-requires
+const staticConfig = require('./static-config.json');
+
+// --- Constants matching staging project "FS-Test-Proj - DO NOT DELETE" ---
+const EXPERIENCE_KEY = 'test-experience-ab-fullstack-4';
+const FEATURE_TYPED_KEY = 'feature-2';
+const FEATURE_BASIC_KEY = 'feature-1';
+const GOAL_KEY = 'increase-engagement';
+const VARIATION_IDS = ['1003180877', '1003180878'];
+
+// Experience -1 has audience "adv-audience" requiring (desktop=true AND browser!="CH") OR (mobile=true)
+const EXPERIENCE_WITH_AUDIENCE_KEY = 'test-experience-ab-fullstack-1';
+
+// Location "pricing-location" requires location=pricing
+const qualifyingAttributes = {
+ locationProperties: {location: 'pricing'}
+};
+
+// --- In-memory DataStore for dedup tests ---
+class MemoryDataStore {
+ private data: Record = {};
+ get(key: string): any {
+ if (!key) return this.data;
+ return this.data[key.toString()];
+ }
+ set(key: string, value: any): void {
+ if (!key) throw new Error('Invalid DataStore key!');
+ this.data[key.toString()] = value;
+ }
+}
+
+// --- Dual-mode: static always runs, live only when env var is set ---
+const modes: Array<'static' | 'live' | 'live-secret'> = [
+ 'static',
+ ...(process.env.CONVERT_STAGING_SDK_KEY ? (['live'] as const) : []),
+ ...(process.env.CONVERT_STAGING_SDK_KEY2 &&
+ process.env.CONVERT_STAGING_SDK_KEY2_SECRET
+ ? (['live-secret'] as const)
+ : [])
+];
+
+function createSdk(
+ mode: 'static' | 'live' | 'live-secret',
+ overrides: Record = {}
+) {
+ if (mode === 'live') {
+ return new ConvertSDK({
+ sdkKey: process.env.CONVERT_STAGING_SDK_KEY,
+ environment: 'staging',
+ network: {tracking: false},
+ ...overrides
+ });
+ }
+ if (mode === 'live-secret') {
+ return new ConvertSDK({
+ sdkKey: process.env.CONVERT_STAGING_SDK_KEY2,
+ sdkKeySecret: process.env.CONVERT_STAGING_SDK_KEY2_SECRET,
+ environment: 'staging',
+ network: {tracking: false},
+ ...overrides
+ });
+ }
+ return new ConvertSDK({
+ data: staticConfig,
+ environment: 'staging',
+ network: {tracking: false},
+ ...overrides
+ });
+}
+
+// Helper: create SDK, wait for ready, and create a visitor context
+async function createReadyContext(
+ mode: 'static' | 'live' | 'live-secret',
+ visitorId: string,
+ overrides: Record = {}
+) {
+ const sdk = createSdk(mode, overrides);
+ await sdk.onReady();
+ const context = sdk.createContext(visitorId);
+ return {sdk, context};
+}
+
+// Helper: create SDK with tracking enabled and a fresh MemoryDataStore
+function createTrackingSdk(
+ mode: 'static' | 'live' | 'live-secret',
+ overrides: Record = {}
+) {
+ const dataStore = new MemoryDataStore();
+ const sdk = createSdk(mode, {
+ network: {tracking: true},
+ dataStore,
+ ...overrides
+ });
+ return {sdk, dataStore};
+}
+
+// Helper: create tracking SDK, wait for ready, create context, and bucket into experience
+async function createBucketedTrackingContext(
+ mode: 'static' | 'live' | 'live-secret',
+ visitorId: string,
+ overrides: Record = {}
+) {
+ const {sdk, dataStore} = createTrackingSdk(mode, overrides);
+ await sdk.onReady();
+ const context = sdk.createContext(visitorId);
+ context.runExperience(EXPERIENCE_KEY, qualifyingAttributes);
+ return {sdk, dataStore, context};
+}
+
+// Helper: bucket into experience + run feature, return both with assertions
+function bucketAndVerifyFeature(context: any) {
+ const variation = context.runExperience(EXPERIENCE_KEY, qualifyingAttributes);
+ expect(variation).toBeDefined();
+ expect(VARIATION_IDS).toContain(variation.id);
+
+ const feature = context.runFeature(FEATURE_TYPED_KEY, qualifyingAttributes);
+ expect(feature).toBeDefined();
+ expect(feature.status).toBe('enabled');
+ expect(feature.variables.price).toBe(100);
+
+ return {variation, feature};
+}
+
+for (const mode of modes) {
+ test.describe(`Full-chain integration tests [${mode} mode]`, () => {
+ // --- Happy Path ---
+
+ test('SDK initializes and is ready', async () => {
+ const sdk = createSdk(mode);
+ await sdk.onReady();
+ });
+
+ test('Ready event fired on init', async () => {
+ const sdk = createSdk(mode);
+ let readyCalled = 0;
+ let readyError: any = null;
+ sdk.on(SystemEvents.READY, (_args: any, err: any) => {
+ readyCalled++;
+ readyError = err;
+ });
+ await sdk.onReady();
+ expect(readyCalled).toBe(1);
+ expect(readyError).toBeNull();
+ });
+
+ test('Create context and run experience', async () => {
+ const {context} = await createReadyContext(
+ mode,
+ 'visitor-integration-test'
+ );
+ const variation = context.runExperience(
+ EXPERIENCE_KEY,
+ qualifyingAttributes
+ );
+ expect(variation).toBeDefined();
+ expect(variation).not.toBeNull();
+ expect(variation.experienceKey).toBe(EXPERIENCE_KEY);
+ expect(VARIATION_IDS).toContain(variation.id);
+ expect(variation.changes).toBeDefined();
+ expect(Array.isArray(variation.changes)).toBe(true);
+ expect(variation.changes.length).toBeGreaterThan(0);
+ });
+
+ test('Bucketing determinism', async () => {
+ const {context} = await createReadyContext(
+ mode,
+ 'visitor-determinism-test'
+ );
+
+ const results: string[] = [];
+ for (let i = 0; i < 10; i++) {
+ const variation = context.runExperience(
+ EXPERIENCE_KEY,
+ qualifyingAttributes
+ );
+ expect(variation).toBeDefined();
+ results.push(variation.id);
+ }
+
+ // All 10 runs should return the same variation
+ const uniqueIds = [...new Set(results)];
+ expect(uniqueIds).toHaveLength(1);
+ expect(VARIATION_IDS).toContain(uniqueIds[0]);
+ });
+
+ test('Bucketing event fired on experience', async () => {
+ const {sdk, context} = await createReadyContext(
+ mode,
+ 'visitor-bucketing-event-test'
+ );
+
+ let bucketingFired = false;
+ sdk.on(SystemEvents.BUCKETING, () => {
+ bucketingFired = true;
+ });
+ context.runExperience(EXPERIENCE_KEY, qualifyingAttributes);
+ expect(bucketingFired).toBe(true);
+ });
+
+ test('Run feature with typed variables', async () => {
+ const {context} = await createReadyContext(
+ mode,
+ 'visitor-feature-typed-test'
+ );
+
+ // Must run experience first to bucket into a variation
+ context.runExperience(EXPERIENCE_KEY, qualifyingAttributes);
+
+ const feature = context.runFeature(
+ FEATURE_TYPED_KEY,
+ qualifyingAttributes
+ );
+ expect(feature).toBeDefined();
+ expect(feature).not.toBeNull();
+ expect(feature.status).toBe('enabled');
+
+ // Verify typed variables
+ expect(feature.variables).toBeDefined();
+ expect(typeof feature.variables.price).toBe('number');
+ expect(feature.variables.price).toBe(100);
+ expect(typeof feature.variables['button-height']).toBe('number');
+ expect(feature.variables['button-height']).toBe(40);
+ expect(typeof feature.variables.additionalData).toBe('object');
+ expect(feature.variables.additionalData.foo).toBe('bar');
+ expect(feature.variables.additionalData.v).toBe(2);
+ });
+
+ test('Full chain: init -> context -> bucket -> feature -> verify', async () => {
+ const {sdk, context} = await createReadyContext(
+ mode,
+ 'visitor-full-chain-test'
+ );
+
+ let readyFired = false;
+ let bucketingFired = false;
+ sdk.on(SystemEvents.READY, () => {
+ readyFired = true;
+ });
+ sdk.on(SystemEvents.BUCKETING, () => {
+ bucketingFired = true;
+ });
+
+ expect(readyFired).toBe(true);
+ bucketAndVerifyFeature(context);
+ expect(bucketingFired).toBe(true);
+ });
+
+ // --- Negative Path ---
+
+ test('Run feature with unknown key returns disabled status', async () => {
+ const {context} = await createReadyContext(
+ mode,
+ 'visitor-negative-test'
+ );
+ const result = context.runFeature('nonexistent-feature');
+ // SDK returns a BucketedFeature with status 'disabled' for unknown features
+ expect(result).toBeDefined();
+ expect(result.key).toBe('nonexistent-feature');
+ expect(result.status).toBe('disabled');
+ });
+
+ test('Run experience with non-qualifying location returns null', async () => {
+ const {context} = await createReadyContext(
+ mode,
+ 'visitor-non-qualifying-test'
+ );
+ const result = context.runExperience(EXPERIENCE_KEY, {
+ locationProperties: {location: 'nonexistent'}
+ });
+ // SDK returns null when location doesn't match
+ expect(result).toBeNull();
+ });
+
+ test('Run experience with audience and no visitor properties returns null', async () => {
+ const {context} = await createReadyContext(
+ mode,
+ 'visitor-audience-test'
+ );
+ // exp-1 has audience requiring (desktop=true AND browser!="CH") OR (mobile=true)
+ // Passing only locationProperties and no visitorProperties should fail audience check
+ const result = context.runExperience(EXPERIENCE_WITH_AUDIENCE_KEY, {
+ locationProperties: {location: 'pricing'}
+ });
+ // SDK returns null when audience doesn't match
+ expect(result).toBeNull();
+ });
+
+ // --- Conversion Tracking ---
+
+ test('Track conversion', async () => {
+ const {context} = await createBucketedTrackingContext(
+ mode,
+ 'visitor-conversion-test'
+ );
+ // increase-engagement goal has rules: null, so no ruleData should be passed
+ const result = context.trackConversion(GOAL_KEY);
+ // trackConversion returns undefined on success
+ expect(result).toBeUndefined();
+ });
+
+ test('Conversion event fired on trackConversion', async () => {
+ const {sdk, context} = await createBucketedTrackingContext(
+ mode,
+ 'visitor-conversion-event-test'
+ );
+
+ let conversionFired = false;
+ let conversionData: any = null;
+ sdk.on(SystemEvents.CONVERSION, (data: any) => {
+ conversionFired = true;
+ conversionData = data;
+ });
+
+ // increase-engagement goal has rules: null, so no ruleData should be passed
+ context.trackConversion(GOAL_KEY);
+
+ expect(conversionFired).toBe(true);
+ expect(conversionData).toBeDefined();
+ });
+
+ test('Goal deduplication', async () => {
+ const {sdk, context} = await createBucketedTrackingContext(
+ mode,
+ 'visitor-dedup-test'
+ );
+
+ let conversionCount = 0;
+ sdk.on(SystemEvents.CONVERSION, () => {
+ conversionCount++;
+ });
+
+ // First call — increase-engagement has no rules, so no ruleData
+ context.trackConversion(GOAL_KEY);
+ // Second call — should be deduplicated
+ context.trackConversion(GOAL_KEY);
+
+ expect(conversionCount).toBe(1);
+ });
+
+ test('Track conversion with revenue', async () => {
+ const {sdk, context} = await createBucketedTrackingContext(
+ mode,
+ 'visitor-revenue-test'
+ );
+
+ let queueReleased = false;
+ sdk.on(SystemEvents.API_QUEUE_RELEASED, () => {
+ queueReleased = true;
+ });
+
+ // increase-engagement goal has rules: null, so no ruleData
+ const result = context.trackConversion(GOAL_KEY, {
+ conversionData: [
+ {key: 'amount', value: 49.99},
+ {key: 'transactionId', value: 'txn-integration-001'}
+ ]
+ });
+
+ expect(result).toBeUndefined();
+
+ // Wait for the queue to release
+ await new Promise((resolve) => {
+ if (queueReleased) {
+ resolve();
+ } else {
+ const checkInterval = setInterval(() => {
+ if (queueReleased) {
+ clearInterval(checkInterval);
+ resolve();
+ }
+ }, 100);
+ // Timeout after 5 seconds
+ setTimeout(() => {
+ clearInterval(checkInterval);
+ resolve();
+ }, 5000);
+ }
+ });
+ });
+
+ test('Force multiple transactions', async () => {
+ const {sdk, context} = await createBucketedTrackingContext(
+ mode,
+ 'visitor-force-multi-test'
+ );
+
+ let conversionCount = 0;
+ sdk.on(SystemEvents.CONVERSION, () => {
+ conversionCount++;
+ });
+
+ // First call — no ruleData since increase-engagement has rules: null
+ context.trackConversion(GOAL_KEY, {
+ conversionData: [{key: 'amount', value: 10}]
+ });
+
+ // Second call with forceMultipleTransactions — should NOT be deduplicated
+ context.trackConversion(GOAL_KEY, {
+ conversionData: [{key: 'amount', value: 20}],
+ conversionSetting: {forceMultipleTransactions: true}
+ });
+
+ expect(conversionCount).toBe(2);
+ });
+
+ test('Track conversion with nonexistent goal returns undefined', async () => {
+ const {sdk, context} = await createBucketedTrackingContext(
+ mode,
+ 'visitor-fake-goal-test'
+ );
+
+ let conversionFired = false;
+ sdk.on(SystemEvents.CONVERSION, () => {
+ conversionFired = true;
+ });
+
+ const result = context.trackConversion('totally-fake-goal');
+ expect(result).toBeUndefined();
+ expect(conversionFired).toBe(false);
+ });
+
+ // --- Complete Chain ---
+
+ test('Complete chain: init -> context -> bucket -> feature -> conversion -> flush', async () => {
+ const {sdk, context} = await createBucketedTrackingContext(
+ mode,
+ 'visitor-complete-chain-test',
+ {events: {batch_size: 1, release_interval: 1000}}
+ );
+
+ let conversionFired = false;
+ sdk.on(SystemEvents.CONVERSION, () => {
+ conversionFired = true;
+ });
+
+ // Verify feature (experience already bucketed by createBucketedTrackingContext)
+ const feature = context.runFeature(
+ FEATURE_TYPED_KEY,
+ qualifyingAttributes
+ );
+ expect(feature).toBeDefined();
+ expect(feature.status).toBe('enabled');
+ expect(feature.variables.price).toBe(100);
+
+ // Track conversion — no ruleData since increase-engagement has rules: null
+ const conversionResult = context.trackConversion(GOAL_KEY, {
+ conversionData: [{key: 'amount', value: 99.99}]
+ });
+ expect(conversionResult).toBeUndefined();
+ expect(conversionFired).toBe(true);
+ });
+ });
+}
diff --git a/packages/js-sdk/tests/integration/static-config.json b/packages/js-sdk/tests/integration/static-config.json
new file mode 100644
index 00000000..f324b7bb
--- /dev/null
+++ b/packages/js-sdk/tests/integration/static-config.json
@@ -0,0 +1 @@
+{"account_id":"10035569","project":{"id":"10034190","name":"FS-Test-Proj - DO NOT DELETE","type":"fullstack","utc_offset":"0","domains":[],"global_javascript":"","settings":{"include_jquery":false,"include_jquery_v1":false,"disable_spa_functionality":false,"do_not_track_referral":false,"allow_crossdomain_tracking":false,"data_anonymization":false,"do_not_track":"OFF","global_privacy_control":"OFF","min_order_value":0,"max_order_value":99999,"version":"2026-03-22T07:46:28+00:00-259","tracking_script":null,"outliers":{"order_value":{"detection_type":"none"},"products_ordered_count":{"detection_type":"none"}},"placeholders":[],"global_javascript_placeholders":[],"integrations":{"google_analytics":{"enabled":false},"kissmetrics":{"enabled":false},"visitor_insights":{"tracking_id":null}}},"custom_domain":null},"experiences":[{"id":"100334665","name":"Test Experience AB Fullstack","type":"a\/b_fullstack","status":"active","global_js":"","global_css":"","environment":"staging","settings":{"min_order_value":0,"max_order_value":99999,"matching_options":{"audiences":"any","locations":"any"},"placeholders":[],"outliers":{"order_value":{"detection_type":"none"},"products_ordered_count":{"detection_type":"none"}}},"key":"test-experience-ab-fullstack-1","version":8,"locations":["1003350","1003351","1003352","10036409"],"site_area":null,"audiences":["10033684"],"goals":["100322784"],"integrations":[],"environments":["staging"],"variations":[{"id":"1003142550","name":"Original Page","key":"1003142550-original-page","status":"running","changes":[{"id":1003122037,"type":"fullStackFeature","data":{"feature_id":10031,"variables_data":{"enabled":false,"caption":"Click this"}}}],"traffic_allocation":50.0},{"id":"1003142551","name":"Variation 1","key":"1003142551-variation-1","status":"running","changes":[{"id":1003122038,"type":"fullStackFeature","data":{"feature_id":10031,"variables_data":{"enabled":false,"caption":"Click that"}}}],"traffic_allocation":50.0}]},{"id":"100349071","name":"Test Experience AB Fullstack 4","type":"a\/b_fullstack","status":"active","global_js":"","global_css":"","environment":"staging","settings":{"min_order_value":0,"max_order_value":99999,"matching_options":{"audiences":"any","locations":"any"},"placeholders":[],"outliers":{"order_value":{"detection_type":"none"},"products_ordered_count":{"detection_type":"none"}}},"key":"test-experience-ab-fullstack-4","version":11,"locations":["1003352"],"site_area":null,"audiences":[],"goals":["100322782","100322783"],"integrations":[],"environments":["staging"],"variations":[{"id":"1003180877","name":"Original","key":"original","status":"running","changes":[{"id":1003183443,"type":"fullStackFeature","data":{"feature_id":100334,"variables_data":{"price":100,"button-height":40,"additionalData":{"foo":"bar","v":2}}}},{"id":1003183444,"type":"fullStackFeature","data":{"feature_id":10031,"variables_data":{"enabled":false,"caption":"Click that"}}}],"traffic_allocation":50.0},{"id":"1003180878","name":"Variation 1","key":"variation-1","status":"running","changes":[{"id":1003183445,"type":"fullStackFeature","data":{"feature_id":100334,"variables_data":{"price":100,"button-height":40,"additionalData":{"foo":"bar","v":2}}}},{"id":1003183446,"type":"fullStackFeature","data":{"feature_id":10031,"variables_data":{"enabled":false,"caption":"Not allowed"}}}],"traffic_allocation":50.0}]}],"audiences":[{"id":"10033684","name":"Adv Audience","key":"adv-audience","rules":{"OR":[{"AND":[{"OR_WHEN":[{"rule_type":"generic_bool_key_value","matching":{"match_type":"equals","negated":false},"value":true,"key":"desktop"}]},{"OR_WHEN":[{"rule_type":"generic_text_key_value","matching":{"match_type":"matches","negated":true},"value":"CH","key":"browser"}]}]},{"AND":[{"OR_WHEN":[{"rule_type":"generic_bool_key_value","matching":{"match_type":"equals","negated":false},"value":true,"key":"mobile"}]}]}]},"type":"permanent"}],"segments":[{"id":"10033690","name":"Test Segments","key":"test-segment-1","rules":{"OR":[{"AND":[{"OR_WHEN":[{"rule_type":"generic_bool_key_value","matching":{"match_type":"equals","negated":false},"value":true,"key":"enabled"}]}]}]}}],"goals":[{"id":"100322782","name":"Decrease BounceRate","key":"decrease-bounce-rate","type":"advanced","rules":{"OR":[{"AND":[{"OR_WHEN":[{"rule_type":"pages_visited_count","matching":{"match_type":"lessEqual","negated":true},"value":1,"key":"d"},{"rule_type":"visit_duration","matching":{"match_type":"lessEqual","negated":true},"value":10}]}]}]}},{"id":"100322783","name":"Increase Engagement","key":"increase-engagement","type":"dom_interaction","rules":null,"settings":{"tracked_items":[{"event":"click","selector":"a"},{"event":"submit","selector":"form"}]}},{"id":"100322784","name":"primary button click","key":"button-primary-click","type":"revenue","rules":{"OR":[{"AND":[{"OR_WHEN":[{"rule_type":"generic_text_key_value","matching":{"match_type":"matches","negated":false},"value":"buy","key":"action"}]}]}]},"settings":{"triggering_type":"manual"}}],"locations":[{"id":"1003350","key":"events-location","name":"Events Location","rules":{"OR":[{"AND":[{"OR_WHEN":[{"rule_type":"generic_text_key_value","matching":{"match_type":"matches","negated":false},"value":"events","key":"location"}]}]}]},"trigger":{"type":"upon_run"}},{"id":"1003351","key":"statistics-location","name":"Statistics Location","rules":{"OR":[{"AND":[{"OR_WHEN":[{"rule_type":"generic_text_key_value","matching":{"match_type":"matches","negated":false},"value":"statistics","key":"location"}]}]}]},"trigger":{"type":"upon_run"}},{"id":"1003352","key":"pricing-location","name":"Pricing Location","rules":{"OR":[{"AND":[{"OR_WHEN":[{"rule_type":"generic_text_key_value","matching":{"match_type":"matches","negated":false},"value":"pricing","key":"location"}]}]}]},"trigger":{"type":"upon_run"}},{"id":"10036407","key":"homescreen","name":"HomeScreen","rules":{"OR":[{"AND":[{"OR_WHEN":[{"rule_type":"generic_text_key_value","matching":{"match_type":"matches","negated":false},"value":"home","key":"screen"},{"rule_type":"generic_text_key_value","matching":{"match_type":"matches","negated":false},"value":"https:\/\/test.com","key":"feature"}]}]}]},"trigger":{"type":"upon_run"}},{"id":"10036409","key":"dasadsa","name":"dasadsa","rules":{"OR":[{"AND":[{"OR_WHEN":[{"rule_type":"generic_numeric_key_value","matching":{"match_type":"less","negated":false},"value":5,"key":"feature"}]}]}]},"trigger":{"type":"upon_run"}}],"archived_experiences":["100334668","100344096"],"features":[{"id":"10031","name":"Feature 1","key":"feature-1","variables":[{"key":"enabled","type":"boolean"},{"key":"caption","type":"string"}]},{"id":"10032","name":"Feature 4","key":"feature-4","variables":[{"key":"statistics","type":"json"}]},{"id":"10033","name":"Feature 5","key":"feature-5","variables":[{"key":"plans","type":"json"}]},{"id":"100320","name":"Button","key":"button","variables":[{"key":"Border","type":"boolean"},{"key":"Color","type":"string"}]},{"id":"100334","name":"Feature 2","key":"feature-2","variables":[{"key":"price","type":"float"},{"key":"button-height","type":"integer"},{"key":"additionalData","type":"json"}]},{"id":"100335","name":"Not Attached Feature 3","key":"not-attached-feature-3","variables":[{"key":"fee","type":"float"},{"key":"link","type":"string"},{"key":"additionalData","type":"json"}]}],"_s_t":"2026-03-22 08:01:02Z","is_debug":false}
\ No newline at end of file
diff --git a/release-please-config.json b/release-please-config.json
index 4621a199..7eb84481 100644
--- a/release-please-config.json
+++ b/release-please-config.json
@@ -74,6 +74,12 @@
"draft": false,
"prerelease": false,
"monorepo-tags": true
+ },
+ "packages/cloudflare": {
+ "changelog-path": "CHANGELOG.md",
+ "draft": false,
+ "prerelease": false,
+ "monorepo-tags": true
}
},
"$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json"
diff --git a/yarn.lock b/yarn.lock
index 90f8c33b..cc4cd58d 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3185,6 +3185,70 @@ __metadata:
languageName: node
linkType: hard
+"@cloudflare/kv-asset-handler@npm:0.3.4":
+ version: 0.3.4
+ resolution: "@cloudflare/kv-asset-handler@npm:0.3.4"
+ dependencies:
+ mime: "npm:^3.0.0"
+ checksum: 10c0/5895d28a4489f470acd217485e3ffbbe2e4a63b0772bb2925ee0f646b6ccce1fd224e07c4610cf514b5e7d0100053c81745a21c0af9a89a98fe16990a4e38ce7
+ languageName: node
+ linkType: hard
+
+"@cloudflare/unenv-preset@npm:2.0.2":
+ version: 2.0.2
+ resolution: "@cloudflare/unenv-preset@npm:2.0.2"
+ peerDependencies:
+ unenv: 2.0.0-rc.14
+ workerd: ^1.20250124.0
+ peerDependenciesMeta:
+ workerd:
+ optional: true
+ checksum: 10c0/8efc49c9c8eec3c03e75bfc65115c54635aef886461f605e4d6e72a594c6e6dd20e05cdedb174feec7c4d7a88ef962eed7380e64c48209f31d56d34ee479a617
+ languageName: node
+ linkType: hard
+
+"@cloudflare/workerd-darwin-64@npm:1.20250718.0":
+ version: 1.20250718.0
+ resolution: "@cloudflare/workerd-darwin-64@npm:1.20250718.0"
+ conditions: os=darwin & cpu=x64
+ languageName: node
+ linkType: hard
+
+"@cloudflare/workerd-darwin-arm64@npm:1.20250718.0":
+ version: 1.20250718.0
+ resolution: "@cloudflare/workerd-darwin-arm64@npm:1.20250718.0"
+ conditions: os=darwin & cpu=arm64
+ languageName: node
+ linkType: hard
+
+"@cloudflare/workerd-linux-64@npm:1.20250718.0":
+ version: 1.20250718.0
+ resolution: "@cloudflare/workerd-linux-64@npm:1.20250718.0"
+ conditions: os=linux & cpu=x64
+ languageName: node
+ linkType: hard
+
+"@cloudflare/workerd-linux-arm64@npm:1.20250718.0":
+ version: 1.20250718.0
+ resolution: "@cloudflare/workerd-linux-arm64@npm:1.20250718.0"
+ conditions: os=linux & cpu=arm64
+ languageName: node
+ linkType: hard
+
+"@cloudflare/workerd-windows-64@npm:1.20250718.0":
+ version: 1.20250718.0
+ resolution: "@cloudflare/workerd-windows-64@npm:1.20250718.0"
+ conditions: os=win32 & cpu=x64
+ languageName: node
+ linkType: hard
+
+"@cloudflare/workers-types@npm:^4.20241205.0":
+ version: 4.20260405.1
+ resolution: "@cloudflare/workers-types@npm:4.20260405.1"
+ checksum: 10c0/931bc1566dc61ea48e78dbd6a3c3d50465bf5031e66f9d19b085cc9b106f110f625b35d5258c111e41fa45a37fd8f84920ce1aecc8f1cb66a282179e5e8b96ae
+ languageName: node
+ linkType: hard
+
"@colors/colors@npm:1.5.0":
version: 1.5.0
resolution: "@colors/colors@npm:1.5.0"
@@ -3289,6 +3353,33 @@ __metadata:
languageName: unknown
linkType: soft
+"@convertcom/js-sdk-cloudflare@npm:^1.0.0, @convertcom/js-sdk-cloudflare@workspace:packages/cloudflare":
+ version: 0.0.0-use.local
+ resolution: "@convertcom/js-sdk-cloudflare@workspace:packages/cloudflare"
+ dependencies:
+ "@babel/cli": "npm:^7.28.3"
+ "@babel/core": "npm:^7.28.5"
+ "@babel/preset-env": "npm:^7.28.5"
+ "@eslint/eslintrc": "npm:^3.3.1"
+ "@rollup/plugin-babel": "npm:^6.1.0"
+ "@rollup/plugin-commonjs": "npm:^29.0.0"
+ "@rollup/plugin-terser": "npm:^0.4.4"
+ "@typescript-eslint/parser": "npm:^8.46.4"
+ eslint: "npm:^9.39.1"
+ eslint-config-prettier: "npm:^10.1.8"
+ eslint-plugin-prettier: "npm:^5.5.4"
+ prettier: "npm:^3.6.2"
+ rollup: "npm:^4.53.2"
+ rollup-plugin-generate-package-json: "npm:^3.2.0"
+ rollup-plugin-modify: "npm:^3.0.0"
+ rollup-plugin-typescript2: "npm:^0.36.0"
+ typescript: "npm:^5.9.3"
+ typescript-eslint: "npm:^8.46.4"
+ peerDependencies:
+ "@convertcom/js-sdk": ">=4.0.0"
+ languageName: unknown
+ linkType: soft
+
"@convertcom/js-sdk-data@workspace:packages/data":
version: 0.0.0-use.local
resolution: "@convertcom/js-sdk-data@workspace:packages/data"
@@ -3341,6 +3432,18 @@ __metadata:
languageName: unknown
linkType: soft
+"@convertcom/js-sdk-demo-cloudflare-workers@workspace:demo/cloudflare-workers":
+ version: 0.0.0-use.local
+ resolution: "@convertcom/js-sdk-demo-cloudflare-workers@workspace:demo/cloudflare-workers"
+ dependencies:
+ "@cloudflare/workers-types": "npm:^4.20241205.0"
+ "@convertcom/js-sdk": "npm:^4.3.4"
+ "@convertcom/js-sdk-cloudflare": "npm:^1.0.0"
+ typescript: "npm:^5.9.3"
+ wrangler: "npm:^3.99.0"
+ languageName: unknown
+ linkType: soft
+
"@convertcom/js-sdk-demo-nodejs@workspace:demo/nodejs":
version: 0.0.0-use.local
resolution: "@convertcom/js-sdk-demo-nodejs@workspace:demo/nodejs"
@@ -3714,7 +3817,7 @@ __metadata:
languageName: unknown
linkType: soft
-"@convertcom/js-sdk@workspace:packages/js-sdk":
+"@convertcom/js-sdk@npm:^4.3.4, @convertcom/js-sdk@workspace:packages/js-sdk":
version: 0.0.0-use.local
resolution: "@convertcom/js-sdk@workspace:packages/js-sdk"
dependencies:
@@ -3723,6 +3826,7 @@ __metadata:
"@babel/preset-env": "npm:^7.28.5"
"@eslint/eslintrc": "npm:^3.3.1"
"@jsdoc/salty": "npm:^0.2.9"
+ "@playwright/test": "npm:^1.52.0"
"@rollup/plugin-babel": "npm:^6.1.0"
"@rollup/plugin-commonjs": "npm:^29.0.0"
"@rollup/plugin-json": "npm:^6.1.0"
@@ -3748,20 +3852,9 @@ __metadata:
eslint-plugin-prettier: "npm:^5.5.4"
glob: "npm:^11.0.3"
istanbul-cobertura-badger: "npm:^1.3.1"
- karma: "npm:^6.4.4"
- karma-browserify: "npm:^8.1.0"
- karma-browserstack-launcher: "npm:^1.6.0"
- karma-chai: "npm:^0.1.0"
- karma-chrome-launcher: "npm:^3.2.0"
- karma-cli: "npm:^2.0.0"
- karma-mocha: "npm:^2.0.1"
- karma-mocha-reporter: "npm:^2.2.5"
- karma-sourcemap-loader: "npm:^0.4.0"
- karma-webpack: "npm:5.0.1"
mocha: "npm:^11.7.5"
nyc: "npm:^17.1.0"
prettier: "npm:^3.6.2"
- puppeteer: "npm:^24.29.1"
rollup: "npm:^4.53.2"
rollup-plugin-copy: "npm:^3.5.0"
rollup-plugin-generate-package-json: "npm:^3.2.0"
@@ -3791,7 +3884,7 @@ __metadata:
languageName: unknown
linkType: soft
-"@cspotcode/source-map-support@npm:^0.8.0":
+"@cspotcode/source-map-support@npm:0.8.1, @cspotcode/source-map-support@npm:^0.8.0":
version: 0.8.1
resolution: "@cspotcode/source-map-support@npm:0.8.1"
dependencies:
@@ -3983,6 +4076,15 @@ __metadata:
languageName: node
linkType: hard
+"@emnapi/runtime@npm:^1.2.0":
+ version: 1.9.2
+ resolution: "@emnapi/runtime@npm:1.9.2"
+ dependencies:
+ tslib: "npm:^2.4.0"
+ checksum: 10c0/61c3a59e0c36784558b8d58eb02bd04815aa5fb0dbfbaf84d1b3050a78aa0cc63ea129ae806bd1e48062bfeb7fc36eb0e5431740d62f64ea51bdf426404b8caa
+ languageName: node
+ linkType: hard
+
"@emnapi/runtime@npm:^1.4.3, @emnapi/runtime@npm:^1.5.0, @emnapi/runtime@npm:^1.6.0, @emnapi/runtime@npm:^1.7.0":
version: 1.7.0
resolution: "@emnapi/runtime@npm:1.7.0"
@@ -4031,6 +4133,27 @@ __metadata:
languageName: node
linkType: hard
+"@esbuild-plugins/node-globals-polyfill@npm:0.2.3":
+ version: 0.2.3
+ resolution: "@esbuild-plugins/node-globals-polyfill@npm:0.2.3"
+ peerDependencies:
+ esbuild: "*"
+ checksum: 10c0/da3591b3943076a8d4a78320c176f37e5a5802512e2c3a792d4dfe495c051e097668dc56513160147b43e86987078559490164905ef41d1326ac0a9e7a6498ac
+ languageName: node
+ linkType: hard
+
+"@esbuild-plugins/node-modules-polyfill@npm:0.2.2":
+ version: 0.2.2
+ resolution: "@esbuild-plugins/node-modules-polyfill@npm:0.2.2"
+ dependencies:
+ escape-string-regexp: "npm:^4.0.0"
+ rollup-plugin-node-polyfills: "npm:^0.2.1"
+ peerDependencies:
+ esbuild: "*"
+ checksum: 10c0/8573eb409d19769ea6a2f621d8d7e344d84a9f19d03f37f4ace053e23dab8eeea08feea871c1704a2d39c0859adadfba808b59a50de4d227cb3879dbd90e7f52
+ languageName: node
+ linkType: hard
+
"@esbuild/aix-ppc64@npm:0.19.12":
version: 0.19.12
resolution: "@esbuild/aix-ppc64@npm:0.19.12"
@@ -4052,6 +4175,13 @@ __metadata:
languageName: node
linkType: hard
+"@esbuild/android-arm64@npm:0.17.19":
+ version: 0.17.19
+ resolution: "@esbuild/android-arm64@npm:0.17.19"
+ conditions: os=android & cpu=arm64
+ languageName: node
+ linkType: hard
+
"@esbuild/android-arm64@npm:0.17.6":
version: 0.17.6
resolution: "@esbuild/android-arm64@npm:0.17.6"
@@ -4080,6 +4210,13 @@ __metadata:
languageName: node
linkType: hard
+"@esbuild/android-arm@npm:0.17.19":
+ version: 0.17.19
+ resolution: "@esbuild/android-arm@npm:0.17.19"
+ conditions: os=android & cpu=arm
+ languageName: node
+ linkType: hard
+
"@esbuild/android-arm@npm:0.17.6":
version: 0.17.6
resolution: "@esbuild/android-arm@npm:0.17.6"
@@ -4108,6 +4245,13 @@ __metadata:
languageName: node
linkType: hard
+"@esbuild/android-x64@npm:0.17.19":
+ version: 0.17.19
+ resolution: "@esbuild/android-x64@npm:0.17.19"
+ conditions: os=android & cpu=x64
+ languageName: node
+ linkType: hard
+
"@esbuild/android-x64@npm:0.17.6":
version: 0.17.6
resolution: "@esbuild/android-x64@npm:0.17.6"
@@ -4136,6 +4280,13 @@ __metadata:
languageName: node
linkType: hard
+"@esbuild/darwin-arm64@npm:0.17.19":
+ version: 0.17.19
+ resolution: "@esbuild/darwin-arm64@npm:0.17.19"
+ conditions: os=darwin & cpu=arm64
+ languageName: node
+ linkType: hard
+
"@esbuild/darwin-arm64@npm:0.17.6":
version: 0.17.6
resolution: "@esbuild/darwin-arm64@npm:0.17.6"
@@ -4164,6 +4315,13 @@ __metadata:
languageName: node
linkType: hard
+"@esbuild/darwin-x64@npm:0.17.19":
+ version: 0.17.19
+ resolution: "@esbuild/darwin-x64@npm:0.17.19"
+ conditions: os=darwin & cpu=x64
+ languageName: node
+ linkType: hard
+
"@esbuild/darwin-x64@npm:0.17.6":
version: 0.17.6
resolution: "@esbuild/darwin-x64@npm:0.17.6"
@@ -4192,6 +4350,13 @@ __metadata:
languageName: node
linkType: hard
+"@esbuild/freebsd-arm64@npm:0.17.19":
+ version: 0.17.19
+ resolution: "@esbuild/freebsd-arm64@npm:0.17.19"
+ conditions: os=freebsd & cpu=arm64
+ languageName: node
+ linkType: hard
+
"@esbuild/freebsd-arm64@npm:0.17.6":
version: 0.17.6
resolution: "@esbuild/freebsd-arm64@npm:0.17.6"
@@ -4220,6 +4385,13 @@ __metadata:
languageName: node
linkType: hard
+"@esbuild/freebsd-x64@npm:0.17.19":
+ version: 0.17.19
+ resolution: "@esbuild/freebsd-x64@npm:0.17.19"
+ conditions: os=freebsd & cpu=x64
+ languageName: node
+ linkType: hard
+
"@esbuild/freebsd-x64@npm:0.17.6":
version: 0.17.6
resolution: "@esbuild/freebsd-x64@npm:0.17.6"
@@ -4248,6 +4420,13 @@ __metadata:
languageName: node
linkType: hard
+"@esbuild/linux-arm64@npm:0.17.19":
+ version: 0.17.19
+ resolution: "@esbuild/linux-arm64@npm:0.17.19"
+ conditions: os=linux & cpu=arm64
+ languageName: node
+ linkType: hard
+
"@esbuild/linux-arm64@npm:0.17.6":
version: 0.17.6
resolution: "@esbuild/linux-arm64@npm:0.17.6"
@@ -4276,6 +4455,13 @@ __metadata:
languageName: node
linkType: hard
+"@esbuild/linux-arm@npm:0.17.19":
+ version: 0.17.19
+ resolution: "@esbuild/linux-arm@npm:0.17.19"
+ conditions: os=linux & cpu=arm
+ languageName: node
+ linkType: hard
+
"@esbuild/linux-arm@npm:0.17.6":
version: 0.17.6
resolution: "@esbuild/linux-arm@npm:0.17.6"
@@ -4304,6 +4490,13 @@ __metadata:
languageName: node
linkType: hard
+"@esbuild/linux-ia32@npm:0.17.19":
+ version: 0.17.19
+ resolution: "@esbuild/linux-ia32@npm:0.17.19"
+ conditions: os=linux & cpu=ia32
+ languageName: node
+ linkType: hard
+
"@esbuild/linux-ia32@npm:0.17.6":
version: 0.17.6
resolution: "@esbuild/linux-ia32@npm:0.17.6"
@@ -4332,6 +4525,13 @@ __metadata:
languageName: node
linkType: hard
+"@esbuild/linux-loong64@npm:0.17.19":
+ version: 0.17.19
+ resolution: "@esbuild/linux-loong64@npm:0.17.19"
+ conditions: os=linux & cpu=loong64
+ languageName: node
+ linkType: hard
+
"@esbuild/linux-loong64@npm:0.17.6":
version: 0.17.6
resolution: "@esbuild/linux-loong64@npm:0.17.6"
@@ -4360,6 +4560,13 @@ __metadata:
languageName: node
linkType: hard
+"@esbuild/linux-mips64el@npm:0.17.19":
+ version: 0.17.19
+ resolution: "@esbuild/linux-mips64el@npm:0.17.19"
+ conditions: os=linux & cpu=mips64el
+ languageName: node
+ linkType: hard
+
"@esbuild/linux-mips64el@npm:0.17.6":
version: 0.17.6
resolution: "@esbuild/linux-mips64el@npm:0.17.6"
@@ -4388,6 +4595,13 @@ __metadata:
languageName: node
linkType: hard
+"@esbuild/linux-ppc64@npm:0.17.19":
+ version: 0.17.19
+ resolution: "@esbuild/linux-ppc64@npm:0.17.19"
+ conditions: os=linux & cpu=ppc64
+ languageName: node
+ linkType: hard
+
"@esbuild/linux-ppc64@npm:0.17.6":
version: 0.17.6
resolution: "@esbuild/linux-ppc64@npm:0.17.6"
@@ -4416,6 +4630,13 @@ __metadata:
languageName: node
linkType: hard
+"@esbuild/linux-riscv64@npm:0.17.19":
+ version: 0.17.19
+ resolution: "@esbuild/linux-riscv64@npm:0.17.19"
+ conditions: os=linux & cpu=riscv64
+ languageName: node
+ linkType: hard
+
"@esbuild/linux-riscv64@npm:0.17.6":
version: 0.17.6
resolution: "@esbuild/linux-riscv64@npm:0.17.6"
@@ -4444,6 +4665,13 @@ __metadata:
languageName: node
linkType: hard
+"@esbuild/linux-s390x@npm:0.17.19":
+ version: 0.17.19
+ resolution: "@esbuild/linux-s390x@npm:0.17.19"
+ conditions: os=linux & cpu=s390x
+ languageName: node
+ linkType: hard
+
"@esbuild/linux-s390x@npm:0.17.6":
version: 0.17.6
resolution: "@esbuild/linux-s390x@npm:0.17.6"
@@ -4472,6 +4700,13 @@ __metadata:
languageName: node
linkType: hard
+"@esbuild/linux-x64@npm:0.17.19":
+ version: 0.17.19
+ resolution: "@esbuild/linux-x64@npm:0.17.19"
+ conditions: os=linux & cpu=x64
+ languageName: node
+ linkType: hard
+
"@esbuild/linux-x64@npm:0.17.6":
version: 0.17.6
resolution: "@esbuild/linux-x64@npm:0.17.6"
@@ -4507,6 +4742,13 @@ __metadata:
languageName: node
linkType: hard
+"@esbuild/netbsd-x64@npm:0.17.19":
+ version: 0.17.19
+ resolution: "@esbuild/netbsd-x64@npm:0.17.19"
+ conditions: os=netbsd & cpu=x64
+ languageName: node
+ linkType: hard
+
"@esbuild/netbsd-x64@npm:0.17.6":
version: 0.17.6
resolution: "@esbuild/netbsd-x64@npm:0.17.6"
@@ -4542,6 +4784,13 @@ __metadata:
languageName: node
linkType: hard
+"@esbuild/openbsd-x64@npm:0.17.19":
+ version: 0.17.19
+ resolution: "@esbuild/openbsd-x64@npm:0.17.19"
+ conditions: os=openbsd & cpu=x64
+ languageName: node
+ linkType: hard
+
"@esbuild/openbsd-x64@npm:0.17.6":
version: 0.17.6
resolution: "@esbuild/openbsd-x64@npm:0.17.6"
@@ -4577,6 +4826,13 @@ __metadata:
languageName: node
linkType: hard
+"@esbuild/sunos-x64@npm:0.17.19":
+ version: 0.17.19
+ resolution: "@esbuild/sunos-x64@npm:0.17.19"
+ conditions: os=sunos & cpu=x64
+ languageName: node
+ linkType: hard
+
"@esbuild/sunos-x64@npm:0.17.6":
version: 0.17.6
resolution: "@esbuild/sunos-x64@npm:0.17.6"
@@ -4605,6 +4861,13 @@ __metadata:
languageName: node
linkType: hard
+"@esbuild/win32-arm64@npm:0.17.19":
+ version: 0.17.19
+ resolution: "@esbuild/win32-arm64@npm:0.17.19"
+ conditions: os=win32 & cpu=arm64
+ languageName: node
+ linkType: hard
+
"@esbuild/win32-arm64@npm:0.17.6":
version: 0.17.6
resolution: "@esbuild/win32-arm64@npm:0.17.6"
@@ -4633,6 +4896,13 @@ __metadata:
languageName: node
linkType: hard
+"@esbuild/win32-ia32@npm:0.17.19":
+ version: 0.17.19
+ resolution: "@esbuild/win32-ia32@npm:0.17.19"
+ conditions: os=win32 & cpu=ia32
+ languageName: node
+ linkType: hard
+
"@esbuild/win32-ia32@npm:0.17.6":
version: 0.17.6
resolution: "@esbuild/win32-ia32@npm:0.17.6"
@@ -4661,6 +4931,13 @@ __metadata:
languageName: node
linkType: hard
+"@esbuild/win32-x64@npm:0.17.19":
+ version: 0.17.19
+ resolution: "@esbuild/win32-x64@npm:0.17.19"
+ conditions: os=win32 & cpu=x64
+ languageName: node
+ linkType: hard
+
"@esbuild/win32-x64@npm:0.17.6":
version: 0.17.6
resolution: "@esbuild/win32-x64@npm:0.17.6"
@@ -4819,6 +5096,13 @@ __metadata:
languageName: node
linkType: hard
+"@fastify/busboy@npm:^2.0.0":
+ version: 2.1.1
+ resolution: "@fastify/busboy@npm:2.1.1"
+ checksum: 10c0/6f8027a8cba7f8f7b736718b013f5a38c0476eea67034c94a0d3c375e2b114366ad4419e6a6fa7ffc2ef9c6d3e0435d76dd584a7a1cbac23962fda7650b579e3
+ languageName: node
+ linkType: hard
+
"@humanfs/core@npm:^0.19.1":
version: 0.19.1
resolution: "@humanfs/core@npm:0.19.1"
@@ -4875,6 +5159,18 @@ __metadata:
languageName: node
linkType: hard
+"@img/sharp-darwin-arm64@npm:0.33.5":
+ version: 0.33.5
+ resolution: "@img/sharp-darwin-arm64@npm:0.33.5"
+ dependencies:
+ "@img/sharp-libvips-darwin-arm64": "npm:1.0.4"
+ dependenciesMeta:
+ "@img/sharp-libvips-darwin-arm64":
+ optional: true
+ conditions: os=darwin & cpu=arm64
+ languageName: node
+ linkType: hard
+
"@img/sharp-darwin-arm64@npm:0.34.5":
version: 0.34.5
resolution: "@img/sharp-darwin-arm64@npm:0.34.5"
@@ -4887,6 +5183,18 @@ __metadata:
languageName: node
linkType: hard
+"@img/sharp-darwin-x64@npm:0.33.5":
+ version: 0.33.5
+ resolution: "@img/sharp-darwin-x64@npm:0.33.5"
+ dependencies:
+ "@img/sharp-libvips-darwin-x64": "npm:1.0.4"
+ dependenciesMeta:
+ "@img/sharp-libvips-darwin-x64":
+ optional: true
+ conditions: os=darwin & cpu=x64
+ languageName: node
+ linkType: hard
+
"@img/sharp-darwin-x64@npm:0.34.5":
version: 0.34.5
resolution: "@img/sharp-darwin-x64@npm:0.34.5"
@@ -4899,6 +5207,13 @@ __metadata:
languageName: node
linkType: hard
+"@img/sharp-libvips-darwin-arm64@npm:1.0.4":
+ version: 1.0.4
+ resolution: "@img/sharp-libvips-darwin-arm64@npm:1.0.4"
+ conditions: os=darwin & cpu=arm64
+ languageName: node
+ linkType: hard
+
"@img/sharp-libvips-darwin-arm64@npm:1.2.4":
version: 1.2.4
resolution: "@img/sharp-libvips-darwin-arm64@npm:1.2.4"
@@ -4906,6 +5221,13 @@ __metadata:
languageName: node
linkType: hard
+"@img/sharp-libvips-darwin-x64@npm:1.0.4":
+ version: 1.0.4
+ resolution: "@img/sharp-libvips-darwin-x64@npm:1.0.4"
+ conditions: os=darwin & cpu=x64
+ languageName: node
+ linkType: hard
+
"@img/sharp-libvips-darwin-x64@npm:1.2.4":
version: 1.2.4
resolution: "@img/sharp-libvips-darwin-x64@npm:1.2.4"
@@ -4913,6 +5235,13 @@ __metadata:
languageName: node
linkType: hard
+"@img/sharp-libvips-linux-arm64@npm:1.0.4":
+ version: 1.0.4
+ resolution: "@img/sharp-libvips-linux-arm64@npm:1.0.4"
+ conditions: os=linux & cpu=arm64 & libc=glibc
+ languageName: node
+ linkType: hard
+
"@img/sharp-libvips-linux-arm64@npm:1.2.4":
version: 1.2.4
resolution: "@img/sharp-libvips-linux-arm64@npm:1.2.4"
@@ -4920,6 +5249,13 @@ __metadata:
languageName: node
linkType: hard
+"@img/sharp-libvips-linux-arm@npm:1.0.5":
+ version: 1.0.5
+ resolution: "@img/sharp-libvips-linux-arm@npm:1.0.5"
+ conditions: os=linux & cpu=arm & libc=glibc
+ languageName: node
+ linkType: hard
+
"@img/sharp-libvips-linux-arm@npm:1.2.4":
version: 1.2.4
resolution: "@img/sharp-libvips-linux-arm@npm:1.2.4"
@@ -4941,6 +5277,13 @@ __metadata:
languageName: node
linkType: hard
+"@img/sharp-libvips-linux-s390x@npm:1.0.4":
+ version: 1.0.4
+ resolution: "@img/sharp-libvips-linux-s390x@npm:1.0.4"
+ conditions: os=linux & cpu=s390x & libc=glibc
+ languageName: node
+ linkType: hard
+
"@img/sharp-libvips-linux-s390x@npm:1.2.4":
version: 1.2.4
resolution: "@img/sharp-libvips-linux-s390x@npm:1.2.4"
@@ -4948,6 +5291,13 @@ __metadata:
languageName: node
linkType: hard
+"@img/sharp-libvips-linux-x64@npm:1.0.4":
+ version: 1.0.4
+ resolution: "@img/sharp-libvips-linux-x64@npm:1.0.4"
+ conditions: os=linux & cpu=x64 & libc=glibc
+ languageName: node
+ linkType: hard
+
"@img/sharp-libvips-linux-x64@npm:1.2.4":
version: 1.2.4
resolution: "@img/sharp-libvips-linux-x64@npm:1.2.4"
@@ -4955,6 +5305,13 @@ __metadata:
languageName: node
linkType: hard
+"@img/sharp-libvips-linuxmusl-arm64@npm:1.0.4":
+ version: 1.0.4
+ resolution: "@img/sharp-libvips-linuxmusl-arm64@npm:1.0.4"
+ conditions: os=linux & cpu=arm64 & libc=musl
+ languageName: node
+ linkType: hard
+
"@img/sharp-libvips-linuxmusl-arm64@npm:1.2.4":
version: 1.2.4
resolution: "@img/sharp-libvips-linuxmusl-arm64@npm:1.2.4"
@@ -4962,6 +5319,13 @@ __metadata:
languageName: node
linkType: hard
+"@img/sharp-libvips-linuxmusl-x64@npm:1.0.4":
+ version: 1.0.4
+ resolution: "@img/sharp-libvips-linuxmusl-x64@npm:1.0.4"
+ conditions: os=linux & cpu=x64 & libc=musl
+ languageName: node
+ linkType: hard
+
"@img/sharp-libvips-linuxmusl-x64@npm:1.2.4":
version: 1.2.4
resolution: "@img/sharp-libvips-linuxmusl-x64@npm:1.2.4"
@@ -4969,6 +5333,18 @@ __metadata:
languageName: node
linkType: hard
+"@img/sharp-linux-arm64@npm:0.33.5":
+ version: 0.33.5
+ resolution: "@img/sharp-linux-arm64@npm:0.33.5"
+ dependencies:
+ "@img/sharp-libvips-linux-arm64": "npm:1.0.4"
+ dependenciesMeta:
+ "@img/sharp-libvips-linux-arm64":
+ optional: true
+ conditions: os=linux & cpu=arm64 & libc=glibc
+ languageName: node
+ linkType: hard
+
"@img/sharp-linux-arm64@npm:0.34.5":
version: 0.34.5
resolution: "@img/sharp-linux-arm64@npm:0.34.5"
@@ -4981,6 +5357,18 @@ __metadata:
languageName: node
linkType: hard
+"@img/sharp-linux-arm@npm:0.33.5":
+ version: 0.33.5
+ resolution: "@img/sharp-linux-arm@npm:0.33.5"
+ dependencies:
+ "@img/sharp-libvips-linux-arm": "npm:1.0.5"
+ dependenciesMeta:
+ "@img/sharp-libvips-linux-arm":
+ optional: true
+ conditions: os=linux & cpu=arm & libc=glibc
+ languageName: node
+ linkType: hard
+
"@img/sharp-linux-arm@npm:0.34.5":
version: 0.34.5
resolution: "@img/sharp-linux-arm@npm:0.34.5"
@@ -5017,6 +5405,18 @@ __metadata:
languageName: node
linkType: hard
+"@img/sharp-linux-s390x@npm:0.33.5":
+ version: 0.33.5
+ resolution: "@img/sharp-linux-s390x@npm:0.33.5"
+ dependencies:
+ "@img/sharp-libvips-linux-s390x": "npm:1.0.4"
+ dependenciesMeta:
+ "@img/sharp-libvips-linux-s390x":
+ optional: true
+ conditions: os=linux & cpu=s390x & libc=glibc
+ languageName: node
+ linkType: hard
+
"@img/sharp-linux-s390x@npm:0.34.5":
version: 0.34.5
resolution: "@img/sharp-linux-s390x@npm:0.34.5"
@@ -5029,6 +5429,18 @@ __metadata:
languageName: node
linkType: hard
+"@img/sharp-linux-x64@npm:0.33.5":
+ version: 0.33.5
+ resolution: "@img/sharp-linux-x64@npm:0.33.5"
+ dependencies:
+ "@img/sharp-libvips-linux-x64": "npm:1.0.4"
+ dependenciesMeta:
+ "@img/sharp-libvips-linux-x64":
+ optional: true
+ conditions: os=linux & cpu=x64 & libc=glibc
+ languageName: node
+ linkType: hard
+
"@img/sharp-linux-x64@npm:0.34.5":
version: 0.34.5
resolution: "@img/sharp-linux-x64@npm:0.34.5"
@@ -5041,6 +5453,18 @@ __metadata:
languageName: node
linkType: hard
+"@img/sharp-linuxmusl-arm64@npm:0.33.5":
+ version: 0.33.5
+ resolution: "@img/sharp-linuxmusl-arm64@npm:0.33.5"
+ dependencies:
+ "@img/sharp-libvips-linuxmusl-arm64": "npm:1.0.4"
+ dependenciesMeta:
+ "@img/sharp-libvips-linuxmusl-arm64":
+ optional: true
+ conditions: os=linux & cpu=arm64 & libc=musl
+ languageName: node
+ linkType: hard
+
"@img/sharp-linuxmusl-arm64@npm:0.34.5":
version: 0.34.5
resolution: "@img/sharp-linuxmusl-arm64@npm:0.34.5"
@@ -5053,6 +5477,18 @@ __metadata:
languageName: node
linkType: hard
+"@img/sharp-linuxmusl-x64@npm:0.33.5":
+ version: 0.33.5
+ resolution: "@img/sharp-linuxmusl-x64@npm:0.33.5"
+ dependencies:
+ "@img/sharp-libvips-linuxmusl-x64": "npm:1.0.4"
+ dependenciesMeta:
+ "@img/sharp-libvips-linuxmusl-x64":
+ optional: true
+ conditions: os=linux & cpu=x64 & libc=musl
+ languageName: node
+ linkType: hard
+
"@img/sharp-linuxmusl-x64@npm:0.34.5":
version: 0.34.5
resolution: "@img/sharp-linuxmusl-x64@npm:0.34.5"
@@ -5065,6 +5501,15 @@ __metadata:
languageName: node
linkType: hard
+"@img/sharp-wasm32@npm:0.33.5":
+ version: 0.33.5
+ resolution: "@img/sharp-wasm32@npm:0.33.5"
+ dependencies:
+ "@emnapi/runtime": "npm:^1.2.0"
+ conditions: cpu=wasm32
+ languageName: node
+ linkType: hard
+
"@img/sharp-wasm32@npm:0.34.5":
version: 0.34.5
resolution: "@img/sharp-wasm32@npm:0.34.5"
@@ -5081,6 +5526,13 @@ __metadata:
languageName: node
linkType: hard
+"@img/sharp-win32-ia32@npm:0.33.5":
+ version: 0.33.5
+ resolution: "@img/sharp-win32-ia32@npm:0.33.5"
+ conditions: os=win32 & cpu=ia32
+ languageName: node
+ linkType: hard
+
"@img/sharp-win32-ia32@npm:0.34.5":
version: 0.34.5
resolution: "@img/sharp-win32-ia32@npm:0.34.5"
@@ -5088,6 +5540,13 @@ __metadata:
languageName: node
linkType: hard
+"@img/sharp-win32-x64@npm:0.33.5":
+ version: 0.33.5
+ resolution: "@img/sharp-win32-x64@npm:0.33.5"
+ conditions: os=win32 & cpu=x64
+ languageName: node
+ linkType: hard
+
"@img/sharp-win32-x64@npm:0.34.5":
version: 0.34.5
resolution: "@img/sharp-win32-x64@npm:0.34.5"
@@ -6470,6 +6929,17 @@ __metadata:
languageName: node
linkType: hard
+"@playwright/test@npm:^1.52.0":
+ version: 1.59.1
+ resolution: "@playwright/test@npm:1.59.1"
+ dependencies:
+ playwright: "npm:1.59.1"
+ bin:
+ playwright: cli.js
+ checksum: 10c0/8c2d94a860d3c254a0b114df2f888ad0a0e9310f45b6059bd5d4da196d965cadf6922267cef0881cfa9784d4bef6d78363d2c2d94caa64be67ff644c41162137
+ languageName: node
+ linkType: hard
+
"@pmmmwh/react-refresh-webpack-plugin@npm:^0.5.3":
version: 0.5.15
resolution: "@pmmmwh/react-refresh-webpack-plugin@npm:0.5.15"
@@ -6507,23 +6977,6 @@ __metadata:
languageName: node
linkType: hard
-"@puppeteer/browsers@npm:2.10.13":
- version: 2.10.13
- resolution: "@puppeteer/browsers@npm:2.10.13"
- dependencies:
- debug: "npm:^4.4.3"
- extract-zip: "npm:^2.0.1"
- progress: "npm:^2.0.3"
- proxy-agent: "npm:^6.5.0"
- semver: "npm:^7.7.3"
- tar-fs: "npm:^3.1.1"
- yargs: "npm:^17.7.2"
- bin:
- browsers: lib/cjs/main-cli.js
- checksum: 10c0/b6e003649f5d5231fa8c3aab32423cd3f89cdacc4cf8cf7e0e85b40c53858b09be4c5daf32bbbe481bdaaee1bc28bc78bfb5c19495de8d8736c9728ec25b7a02
- languageName: node
- linkType: hard
-
"@remix-run/css-bundle@npm:^2.17.2":
version: 2.17.2
resolution: "@remix-run/css-bundle@npm:2.17.2"
@@ -7154,13 +7607,6 @@ __metadata:
languageName: node
linkType: hard
-"@socket.io/component-emitter@npm:~3.1.0":
- version: 3.1.2
- resolution: "@socket.io/component-emitter@npm:3.1.2"
- checksum: 10c0/c4242bad66f67e6f7b712733d25b43cbb9e19a595c8701c3ad99cbeb5901555f78b095e24852f862fffb43e96f1d8552e62def885ca82ae1bb05da3668fd87d7
- languageName: node
- linkType: hard
-
"@surma/rollup-plugin-off-main-thread@npm:^2.2.3":
version: 2.2.3
resolution: "@surma/rollup-plugin-off-main-thread@npm:2.2.3"
@@ -7502,13 +7948,6 @@ __metadata:
languageName: node
linkType: hard
-"@tootallnate/quickjs-emscripten@npm:^0.23.0":
- version: 0.23.0
- resolution: "@tootallnate/quickjs-emscripten@npm:0.23.0"
- checksum: 10c0/2a939b781826fb5fd3edd0f2ec3b321d259d760464cf20611c9877205aaca3ccc0b7304dea68416baa0d568e82cd86b17d29548d1e5139fa3155a4a86a2b4b49
- languageName: node
- linkType: hard
-
"@trysound/sax@npm:0.2.0":
version: 0.2.0
resolution: "@trysound/sax@npm:0.2.0"
@@ -7692,13 +8131,6 @@ __metadata:
languageName: node
linkType: hard
-"@types/cookie@npm:^0.4.1":
- version: 0.4.1
- resolution: "@types/cookie@npm:0.4.1"
- checksum: 10c0/f96afe12bd51be1ec61410b0641243d93fa3a494702407c787a4c872b5c8bcd39b224471452055e44a9ce42af1a636e87d161994226eaf4c2be9c30f60418409
- languageName: node
- linkType: hard
-
"@types/cookie@npm:^0.6.0":
version: 0.6.0
resolution: "@types/cookie@npm:0.6.0"
@@ -7713,15 +8145,6 @@ __metadata:
languageName: node
linkType: hard
-"@types/cors@npm:^2.8.12":
- version: 2.8.17
- resolution: "@types/cors@npm:2.8.17"
- dependencies:
- "@types/node": "npm:*"
- checksum: 10c0/457364c28c89f3d9ed34800e1de5c6eaaf344d1bb39af122f013322a50bc606eb2aa6f63de4e41a7a08ba7ef454473926c94a830636723da45bf786df032696d
- languageName: node
- linkType: hard
-
"@types/debug@npm:^4.0.0":
version: 4.1.12
resolution: "@types/debug@npm:4.1.12"
@@ -8044,7 +8467,7 @@ __metadata:
languageName: node
linkType: hard
-"@types/node@npm:*, @types/node@npm:>=10.0.0":
+"@types/node@npm:*":
version: 20.14.5
resolution: "@types/node@npm:20.14.5"
dependencies:
@@ -8305,15 +8728,6 @@ __metadata:
languageName: node
linkType: hard
-"@types/yauzl@npm:^2.9.1":
- version: 2.10.3
- resolution: "@types/yauzl@npm:2.10.3"
- dependencies:
- "@types/node": "npm:*"
- checksum: 10c0/f1b7c1b99fef9f2fe7f1985ef7426d0cebe48cd031f1780fcdc7451eec7e31ac97028f16f50121a59bcf53086a1fc8c856fd5b7d3e00970e43d92ae27d6b43dc
- languageName: node
- linkType: hard
-
"@typescript-eslint/eslint-plugin@npm:8.46.4, @typescript-eslint/eslint-plugin@npm:^8.46.4":
version: 8.46.4
resolution: "@typescript-eslint/eslint-plugin@npm:8.46.4"
@@ -9245,6 +9659,13 @@ __metadata:
languageName: node
linkType: hard
+"acorn-walk@npm:8.3.2":
+ version: 8.3.2
+ resolution: "acorn-walk@npm:8.3.2"
+ checksum: 10c0/7e2a8dad5480df7f872569b9dccff2f3da7e65f5353686b1d6032ab9f4ddf6e3a2cb83a9b52cf50b1497fd522154dda92f0abf7153290cc79cd14721ff121e52
+ languageName: node
+ linkType: hard
+
"acorn-walk@npm:^7.0.0, acorn-walk@npm:^7.1.1":
version: 7.2.0
resolution: "acorn-walk@npm:7.2.0"
@@ -9261,6 +9682,15 @@ __metadata:
languageName: node
linkType: hard
+"acorn@npm:8.14.0, acorn@npm:^8.0.0, acorn@npm:^8.14.0":
+ version: 8.14.0
+ resolution: "acorn@npm:8.14.0"
+ bin:
+ acorn: bin/acorn
+ checksum: 10c0/6d4ee461a7734b2f48836ee0fbb752903606e576cc100eb49340295129ca0b452f3ba91ddd4424a1d4406a98adfb2ebb6bd0ff4c49d7a0930c10e462719bbfd7
+ languageName: node
+ linkType: hard
+
"acorn@npm:^3.1.0":
version: 3.3.0
resolution: "acorn@npm:3.3.0"
@@ -9288,15 +9718,6 @@ __metadata:
languageName: node
linkType: hard
-"acorn@npm:^8.0.0, acorn@npm:^8.14.0":
- version: 8.14.0
- resolution: "acorn@npm:8.14.0"
- bin:
- acorn: bin/acorn
- checksum: 10c0/6d4ee461a7734b2f48836ee0fbb752903606e576cc100eb49340295129ca0b452f3ba91ddd4424a1d4406a98adfb2ebb6bd0ff4c49d7a0930c10e462719bbfd7
- languageName: node
- linkType: hard
-
"acorn@npm:^8.11.0, acorn@npm:^8.12.0, acorn@npm:^8.2.4, acorn@npm:^8.4.1, acorn@npm:^8.7.1, acorn@npm:^8.8.2, acorn@npm:^8.9.0":
version: 8.12.0
resolution: "acorn@npm:8.12.0"
@@ -9332,7 +9753,7 @@ __metadata:
languageName: node
linkType: hard
-"agent-base@npm:6, agent-base@npm:^6.0.2":
+"agent-base@npm:6":
version: 6.0.2
resolution: "agent-base@npm:6.0.2"
dependencies:
@@ -9341,15 +9762,6 @@ __metadata:
languageName: node
linkType: hard
-"agent-base@npm:^4.3.0":
- version: 4.3.0
- resolution: "agent-base@npm:4.3.0"
- dependencies:
- es6-promisify: "npm:^5.0.0"
- checksum: 10c0/a618d4e4ca7c0c2023b2664346570773455c501a930718764f65016a8a9eea6d2ab5ba54255589e46de529bab4026a088523dce17f94e34ba385af1f644febe1
- languageName: node
- linkType: hard
-
"agent-base@npm:^7.0.2, agent-base@npm:^7.1.0, agent-base@npm:^7.1.1":
version: 7.1.1
resolution: "agent-base@npm:7.1.1"
@@ -9359,13 +9771,6 @@ __metadata:
languageName: node
linkType: hard
-"agent-base@npm:^7.1.2":
- version: 7.1.4
- resolution: "agent-base@npm:7.1.4"
- checksum: 10c0/c2c9ab7599692d594b6a161559ada307b7a624fa4c7b03e3afdb5a5e31cd0e53269115b620fcab024c5ac6a6f37fa5eb2e004f076ad30f5f7e6b8b671f7b35fe
- languageName: node
- linkType: hard
-
"aggregate-error@npm:^3.0.0":
version: 3.1.0
resolution: "aggregate-error@npm:3.1.0"
@@ -9526,13 +9931,6 @@ __metadata:
languageName: node
linkType: hard
-"ansi-regex@npm:^3.0.0":
- version: 3.0.1
- resolution: "ansi-regex@npm:3.0.1"
- checksum: 10c0/d108a7498b8568caf4a46eea4f1784ab4e0dfb2e3f3938c697dee21443d622d765c958f2b7e2b9f6b9e55e2e2af0584eaa9915d51782b89a841c28e744e7a167
- languageName: node
- linkType: hard
-
"ansi-regex@npm:^5.0.1":
version: 5.0.1
resolution: "ansi-regex@npm:5.0.1"
@@ -9912,6 +10310,15 @@ __metadata:
languageName: node
linkType: hard
+"as-table@npm:^1.0.36":
+ version: 1.0.55
+ resolution: "as-table@npm:1.0.55"
+ dependencies:
+ printable-characters: "npm:^1.0.42"
+ checksum: 10c0/8c5693a84621fe53c62fcad6b779dc55c5caf4d43b8e67077964baea4a337769ef53f590d7395c806805b4ef1a391b614ba9acdee19b2ca4309ddedaf13894e6
+ languageName: node
+ linkType: hard
+
"asap@npm:^2.0.0, asap@npm:~2.0.3, asap@npm:~2.0.6":
version: 2.0.6
resolution: "asap@npm:2.0.6"
@@ -9988,15 +10395,6 @@ __metadata:
languageName: node
linkType: hard
-"ast-types@npm:^0.13.4":
- version: 0.13.4
- resolution: "ast-types@npm:0.13.4"
- dependencies:
- tslib: "npm:^2.0.1"
- checksum: 10c0/3a1a409764faa1471601a0ad01b3aa699292991aa9c8a30c7717002cabdf5d98008e7b53ae61f6e058f757fc6ba965e147967a93c13e62692c907d79cfb245f8
- languageName: node
- linkType: hard
-
"ast-types@npm:^0.14.2":
version: 0.14.2
resolution: "ast-types@npm:0.14.2"
@@ -10107,13 +10505,6 @@ __metadata:
languageName: node
linkType: hard
-"b4a@npm:^1.6.4":
- version: 1.6.6
- resolution: "b4a@npm:1.6.6"
- checksum: 10c0/56f30277666cb511a15829e38d369b114df7dc8cec4cedc09cc5d685bc0f27cb63c7bcfb58e09a19a1b3c4f2541069ab078b5328542e85d74a39620327709a38
- languageName: node
- linkType: hard
-
"babel-jest@npm:30.2.0":
version: 30.2.0
resolution: "babel-jest@npm:30.2.0"
@@ -10427,114 +10818,35 @@ __metadata:
languageName: node
linkType: hard
-"babel-walk@npm:3.0.0-canary-5":
- version: 3.0.0-canary-5
- resolution: "babel-walk@npm:3.0.0-canary-5"
- dependencies:
- "@babel/types": "npm:^7.9.6"
- checksum: 10c0/17b689874d15c37714cedf6797dd9321dcb998d8e0dda9a8fe8c8bbbf128bbdeb8935cf56e8630d6b67eae76d2a0bc1e470751e082c3b0e30b80d58beafb5e64
- languageName: node
- linkType: hard
-
-"babylon@npm:^6.18.0":
- version: 6.18.0
- resolution: "babylon@npm:6.18.0"
- bin:
- babylon: ./bin/babylon.js
- checksum: 10c0/9b1bf946e16782deadb1f5414c1269efa6044eb1e97a3de2051f09a3f2a54e97be3542d4242b28d23de0ef67816f519d38ce1ec3ddb7be306131c39a60e5a667
- languageName: node
- linkType: hard
-
-"bail@npm:^2.0.0":
- version: 2.0.2
- resolution: "bail@npm:2.0.2"
- checksum: 10c0/25cbea309ef6a1f56214187004e8f34014eb015713ea01fa5b9b7e9e776ca88d0fdffd64143ac42dc91966c915a4b7b683411b56e14929fad16153fc026ffb8b
- languageName: node
- linkType: hard
-
-"balanced-match@npm:^1.0.0":
- version: 1.0.2
- resolution: "balanced-match@npm:1.0.2"
- checksum: 10c0/9308baf0a7e4838a82bbfd11e01b1cb0f0cf2893bc1676c27c2a8c0e70cbae1c59120c3268517a8ae7fb6376b4639ef81ca22582611dbee4ed28df945134aaee
- languageName: node
- linkType: hard
-
-"bare-events@npm:^2.2.0":
- version: 2.4.2
- resolution: "bare-events@npm:2.4.2"
- checksum: 10c0/09fa923061f31f815e83504e2ed4a8ba87732a01db40a7fae703dbb7eef7f05d99264b5e186074cbe9698213990d1af564c62cca07a5ff88baea8099ad9a6303
- languageName: node
- linkType: hard
-
-"bare-events@npm:^2.5.4, bare-events@npm:^2.7.0":
- version: 2.8.2
- resolution: "bare-events@npm:2.8.2"
- peerDependencies:
- bare-abort-controller: "*"
- peerDependenciesMeta:
- bare-abort-controller:
- optional: true
- checksum: 10c0/53fef240cf2cdcca62f78b6eead90ddb5a59b0929f414b13a63764c2b4f9de98ea8a578d033b04d64bb7b86dfbc402e937984e69950855cc3754c7b63da7db21
- languageName: node
- linkType: hard
-
-"bare-fs@npm:^4.0.1":
- version: 4.5.1
- resolution: "bare-fs@npm:4.5.1"
+"babel-walk@npm:3.0.0-canary-5":
+ version: 3.0.0-canary-5
+ resolution: "babel-walk@npm:3.0.0-canary-5"
dependencies:
- bare-events: "npm:^2.5.4"
- bare-path: "npm:^3.0.0"
- bare-stream: "npm:^2.6.4"
- bare-url: "npm:^2.2.2"
- fast-fifo: "npm:^1.3.2"
- peerDependencies:
- bare-buffer: "*"
- peerDependenciesMeta:
- bare-buffer:
- optional: true
- checksum: 10c0/ea977c101802dd1fcde80e8847443e584a9f1a8b13f688ddc2658a989cca6762c789db66b0de035a2fcc3d7497dbcb361986383bbbdcf73bb6bb8df1342eef01
- languageName: node
- linkType: hard
-
-"bare-os@npm:^3.0.1":
- version: 3.6.2
- resolution: "bare-os@npm:3.6.2"
- checksum: 10c0/7d917bc202b7efbb6b78658403fac04ae4e91db98d38cbd24037f896a2b1b4f4571d8cd408d12bed6a4c406d6abaf8d03836eacbcc4c75a0b6974e268574fc5a
+ "@babel/types": "npm:^7.9.6"
+ checksum: 10c0/17b689874d15c37714cedf6797dd9321dcb998d8e0dda9a8fe8c8bbbf128bbdeb8935cf56e8630d6b67eae76d2a0bc1e470751e082c3b0e30b80d58beafb5e64
languageName: node
linkType: hard
-"bare-path@npm:^3.0.0":
- version: 3.0.0
- resolution: "bare-path@npm:3.0.0"
- dependencies:
- bare-os: "npm:^3.0.1"
- checksum: 10c0/56a3ca82a9f808f4976cb1188640ac206546ce0ddff582afafc7bd2a6a5b31c3bd16422653aec656eeada2830cfbaa433c6cbf6d6b4d9eba033d5e06d60d9a68
+"babylon@npm:^6.18.0":
+ version: 6.18.0
+ resolution: "babylon@npm:6.18.0"
+ bin:
+ babylon: ./bin/babylon.js
+ checksum: 10c0/9b1bf946e16782deadb1f5414c1269efa6044eb1e97a3de2051f09a3f2a54e97be3542d4242b28d23de0ef67816f519d38ce1ec3ddb7be306131c39a60e5a667
languageName: node
linkType: hard
-"bare-stream@npm:^2.6.4":
- version: 2.7.0
- resolution: "bare-stream@npm:2.7.0"
- dependencies:
- streamx: "npm:^2.21.0"
- peerDependencies:
- bare-buffer: "*"
- bare-events: "*"
- peerDependenciesMeta:
- bare-buffer:
- optional: true
- bare-events:
- optional: true
- checksum: 10c0/3acd840b7b288dc066226c36446ff605fba2ecce98f1a0ce6aa611b81aabbcd204046a3209bce172373d17eaeaa5b7d35a85649c18ffcb9f2c783242854e99bd
+"bail@npm:^2.0.0":
+ version: 2.0.2
+ resolution: "bail@npm:2.0.2"
+ checksum: 10c0/25cbea309ef6a1f56214187004e8f34014eb015713ea01fa5b9b7e9e776ca88d0fdffd64143ac42dc91966c915a4b7b683411b56e14929fad16153fc026ffb8b
languageName: node
linkType: hard
-"bare-url@npm:^2.2.2":
- version: 2.3.2
- resolution: "bare-url@npm:2.3.2"
- dependencies:
- bare-path: "npm:^3.0.0"
- checksum: 10c0/4fd0046314390a54404519d9db20e130ab3a341ef638d040f9603ae3fa0a1d84f6970357d21c8fc64e6163d1f61fd212cb1cfa4cb537dfead99fb06e3c030b15
+"balanced-match@npm:^1.0.0":
+ version: 1.0.2
+ resolution: "balanced-match@npm:1.0.2"
+ checksum: 10c0/9308baf0a7e4838a82bbfd11e01b1cb0f0cf2893bc1676c27c2a8c0e70cbae1c59120c3268517a8ae7fb6376b4639ef81ca22582611dbee4ed28df945134aaee
languageName: node
linkType: hard
@@ -10545,13 +10857,6 @@ __metadata:
languageName: node
linkType: hard
-"base64id@npm:2.0.0, base64id@npm:~2.0.0":
- version: 2.0.0
- resolution: "base64id@npm:2.0.0"
- checksum: 10c0/6919efd237ed44b9988cbfc33eca6f173a10e810ce50292b271a1a421aac7748ef232a64d1e6032b08f19aae48dce6ee8f66c5ae2c9e5066c82b884861d4d453
- languageName: node
- linkType: hard
-
"baseline-browser-mapping@npm:^2.8.25":
version: 2.8.25
resolution: "baseline-browser-mapping@npm:2.8.25"
@@ -10570,13 +10875,6 @@ __metadata:
languageName: node
linkType: hard
-"basic-ftp@npm:^5.0.2":
- version: 5.0.5
- resolution: "basic-ftp@npm:5.0.5"
- checksum: 10c0/be983a3997749856da87b839ffce6b8ed6c7dbf91ea991d5c980d8add275f9f2926c19f80217ac3e7f353815be879371d636407ca72b038cea8cab30e53928a6
- languageName: node
- linkType: hard
-
"batch@npm:0.6.1":
version: 0.6.1
resolution: "batch@npm:0.6.1"
@@ -10641,6 +10939,13 @@ __metadata:
languageName: node
linkType: hard
+"blake3-wasm@npm:2.1.5":
+ version: 2.1.5
+ resolution: "blake3-wasm@npm:2.1.5"
+ checksum: 10c0/5dc729d8e3a9d1d7ab016b36cdda264a327ada0239716df48435163e11d2bf6df25d6e421655a1f52649098ae49555268a654729b7d02768f77c571ab37ef814
+ languageName: node
+ linkType: hard
+
"bluebird@npm:^3.7.2":
version: 3.7.2
resolution: "bluebird@npm:3.7.2"
@@ -11035,28 +11340,6 @@ __metadata:
languageName: node
linkType: hard
-"browserstack-local@npm:^1.3.7":
- version: 1.5.5
- resolution: "browserstack-local@npm:1.5.5"
- dependencies:
- agent-base: "npm:^6.0.2"
- https-proxy-agent: "npm:^5.0.1"
- is-running: "npm:^2.1.0"
- ps-tree: "npm:=1.2.0"
- temp-fs: "npm:^0.9.9"
- checksum: 10c0/329b5a68129d17f2b9a37a7b2788847fe25cf59378e6e8c966f387124a5ab651a2c57aa20183a6a5399d93db4545797706c006d24f29723d9f6ea100b8e1b5bc
- languageName: node
- linkType: hard
-
-"browserstack@npm:~1.5.1":
- version: 1.5.3
- resolution: "browserstack@npm:1.5.3"
- dependencies:
- https-proxy-agent: "npm:^2.2.1"
- checksum: 10c0/118704796f0a83aab4d23c7aa506a80cb4cd8338ddafe1fb184cb664c6d9c5527d4748df1529deeeffce53cd6f1e123f329c328ff8a4443ebc6698255a4b3c75
- languageName: node
- linkType: hard
-
"bs-logger@npm:^0.2.6":
version: 0.2.6
resolution: "bs-logger@npm:0.2.6"
@@ -11075,13 +11358,6 @@ __metadata:
languageName: node
linkType: hard
-"buffer-crc32@npm:~0.2.3":
- version: 0.2.13
- resolution: "buffer-crc32@npm:0.2.13"
- checksum: 10c0/cb0a8ddf5cf4f766466db63279e47761eb825693eeba6a5a95ee4ec8cb8f81ede70aa7f9d8aeec083e781d47154290eb5d4d26b3f7a465ec57fb9e7d59c47150
- languageName: node
- linkType: hard
-
"buffer-from@npm:^1.0.0":
version: 1.1.2
resolution: "buffer-from@npm:1.1.2"
@@ -11484,7 +11760,7 @@ __metadata:
languageName: node
linkType: hard
-"chalk@npm:^2.0.1, chalk@npm:^2.1.0, chalk@npm:^2.3.0, chalk@npm:^2.4.1, chalk@npm:^2.4.2":
+"chalk@npm:^2.3.0, chalk@npm:^2.4.1, chalk@npm:^2.4.2":
version: 2.4.2
resolution: "chalk@npm:2.4.2"
dependencies:
@@ -11625,18 +11901,6 @@ __metadata:
languageName: node
linkType: hard
-"chromium-bidi@npm:10.5.1":
- version: 10.5.1
- resolution: "chromium-bidi@npm:10.5.1"
- dependencies:
- mitt: "npm:^3.0.1"
- zod: "npm:^3.24.1"
- peerDependencies:
- devtools-protocol: "*"
- checksum: 10c0/094fca13c1361a1cd6b951cf21f7d68f9cb0d1a5aee31b55f0ace5bb144c4606f2cff5625a6328146e5c326f3baaae45a2cc1e11ca47cb9ad36aaf35107647fe
- languageName: node
- linkType: hard
-
"ci-info@npm:^3.2.0":
version: 3.9.0
resolution: "ci-info@npm:3.9.0"
@@ -11884,13 +12148,33 @@ __metadata:
languageName: node
linkType: hard
-"color-name@npm:~1.1.4":
+"color-name@npm:^1.0.0, color-name@npm:~1.1.4":
version: 1.1.4
resolution: "color-name@npm:1.1.4"
checksum: 10c0/a1a3f914156960902f46f7f56bc62effc6c94e84b2cae157a526b1c1f74b677a47ec602bf68a61abfa2b42d15b7c5651c6dbe72a43af720bc588dff885b10f95
languageName: node
linkType: hard
+"color-string@npm:^1.9.0":
+ version: 1.9.1
+ resolution: "color-string@npm:1.9.1"
+ dependencies:
+ color-name: "npm:^1.0.0"
+ simple-swizzle: "npm:^0.2.2"
+ checksum: 10c0/b0bfd74c03b1f837f543898b512f5ea353f71630ccdd0d66f83028d1f0924a7d4272deb278b9aef376cacf1289b522ac3fb175e99895283645a2dc3a33af2404
+ languageName: node
+ linkType: hard
+
+"color@npm:^4.2.3":
+ version: 4.2.3
+ resolution: "color@npm:4.2.3"
+ dependencies:
+ color-convert: "npm:^2.0.1"
+ color-string: "npm:^1.9.0"
+ checksum: 10c0/7fbe7cfb811054c808349de19fb380252e5e34e61d7d168ec3353e9e9aacb1802674bddc657682e4e9730c2786592a4de6f8283e7e0d3870b829bb0b7b2f6118
+ languageName: node
+ linkType: hard
+
"colord@npm:^2.9.1":
version: 2.9.3
resolution: "colord@npm:2.9.3"
@@ -12098,18 +12382,6 @@ __metadata:
languageName: node
linkType: hard
-"connect@npm:^3.7.0":
- version: 3.7.0
- resolution: "connect@npm:3.7.0"
- dependencies:
- debug: "npm:2.6.9"
- finalhandler: "npm:1.1.2"
- parseurl: "npm:~1.3.3"
- utils-merge: "npm:1.0.1"
- checksum: 10c0/f120c6116bb16a0a7d2703c0b4a0cd7ed787dc5ec91978097bf62aa967289020a9f41a9cd3c3276a7b92aaa36f382d2cd35fed7138fd466a55c8e9fdbed11ca8
- languageName: node
- linkType: hard
-
"consola@npm:^3.2.3":
version: 3.4.2
resolution: "consola@npm:3.4.2"
@@ -12185,7 +12457,7 @@ __metadata:
languageName: node
linkType: hard
-"convert-source-map@npm:^1.4.0, convert-source-map@npm:^1.6.0, convert-source-map@npm:^1.7.0, convert-source-map@npm:^1.8.0":
+"convert-source-map@npm:^1.4.0, convert-source-map@npm:^1.6.0, convert-source-map@npm:^1.7.0":
version: 1.9.0
resolution: "convert-source-map@npm:1.9.0"
checksum: 10c0/281da55454bf8126cbc6625385928c43479f2060984180c42f3a86c8b8c12720a24eac260624a7d1e090004028d2dee78602330578ceec1a08e27cb8bb0a8a5b
@@ -12258,13 +12530,6 @@ __metadata:
languageName: node
linkType: hard
-"cookie@npm:~0.4.1":
- version: 0.4.2
- resolution: "cookie@npm:0.4.2"
- checksum: 10c0/beab41fbd7c20175e3a2799ba948c1dcc71ef69f23fe14eeeff59fc09f50c517b0f77098db87dbb4c55da802f9d86ee86cdc1cd3efd87760341551838d53fca2
- languageName: node
- linkType: hard
-
"cookiejar@npm:^2.1.4":
version: 2.1.4
resolution: "cookiejar@npm:2.1.4"
@@ -12330,7 +12595,7 @@ __metadata:
languageName: node
linkType: hard
-"cors@npm:2.8.5, cors@npm:~2.8.5":
+"cors@npm:2.8.5":
version: 2.8.5
resolution: "cors@npm:2.8.5"
dependencies:
@@ -12383,23 +12648,6 @@ __metadata:
languageName: node
linkType: hard
-"cosmiconfig@npm:^9.0.0":
- version: 9.0.0
- resolution: "cosmiconfig@npm:9.0.0"
- dependencies:
- env-paths: "npm:^2.2.1"
- import-fresh: "npm:^3.3.0"
- js-yaml: "npm:^4.1.0"
- parse-json: "npm:^5.2.0"
- peerDependencies:
- typescript: ">=4.9.5"
- peerDependenciesMeta:
- typescript:
- optional: true
- checksum: 10c0/1c1703be4f02a250b1d6ca3267e408ce16abfe8364193891afc94c2d5c060b69611fdc8d97af74b7e6d5d1aac0ab2fb94d6b079573146bc2d756c2484ce5f0ee
- languageName: node
- linkType: hard
-
"create-ecdh@npm:^4.0.0":
version: 4.0.4
resolution: "create-ecdh@npm:4.0.4"
@@ -12776,13 +13024,6 @@ __metadata:
languageName: node
linkType: hard
-"custom-event@npm:~1.0.0":
- version: 1.0.1
- resolution: "custom-event@npm:1.0.1"
- checksum: 10c0/86cd8497328b1e17dcda894c8df34a73b7a99f915123940d39b33c709482b2d3a2e689cd5e79e4775eb4167227689f57a2ae2f99a3f0bc9c54c0ac1b06853bd5
- languageName: node
- linkType: hard
-
"damerau-levenshtein@npm:^1.0.8":
version: 1.0.8
resolution: "damerau-levenshtein@npm:1.0.8"
@@ -12797,6 +13038,13 @@ __metadata:
languageName: node
linkType: hard
+"data-uri-to-buffer@npm:^2.0.0":
+ version: 2.0.2
+ resolution: "data-uri-to-buffer@npm:2.0.2"
+ checksum: 10c0/341b6191ed65fa453e97a6d44db06082121ebc2ef3e6e096dfb6a1ebbc75e8be39d4199a5b4dba0f0efc43f2a3b2bcc276d85cf1407eba880eb09ebf17c3c31e
+ languageName: node
+ linkType: hard
+
"data-uri-to-buffer@npm:^3.0.1":
version: 3.0.1
resolution: "data-uri-to-buffer@npm:3.0.1"
@@ -12804,13 +13052,6 @@ __metadata:
languageName: node
linkType: hard
-"data-uri-to-buffer@npm:^6.0.2":
- version: 6.0.2
- resolution: "data-uri-to-buffer@npm:6.0.2"
- checksum: 10c0/f76922bf895b3d7d443059ff278c9cc5efc89d70b8b80cd9de0aa79b3adc6d7a17948eefb8692e30398c43635f70ece1673d6085cc9eba2878dbc6c6da5292ac
- languageName: node
- linkType: hard
-
"data-urls@npm:^2.0.0":
version: 2.0.0
resolution: "data-urls@npm:2.0.0"
@@ -12888,13 +13129,6 @@ __metadata:
languageName: node
linkType: hard
-"date-format@npm:^4.0.14":
- version: 4.0.14
- resolution: "date-format@npm:4.0.14"
- checksum: 10c0/1c67a4d77c677bb880328c81d81f5b9ed7fbf672bdaff74e5a0f7314b21188f3a829b06acf120c70cc1df876a7724e3e5c23d511e86d64656a3035a76ac3930b
- languageName: node
- linkType: hard
-
"de-indent@npm:^1.0.2":
version: 1.0.2
resolution: "de-indent@npm:1.0.2"
@@ -12911,7 +13145,7 @@ __metadata:
languageName: node
linkType: hard
-"debug@npm:4, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4, debug@npm:^4.3.5, debug@npm:~4.3.1, debug@npm:~4.3.2, debug@npm:~4.3.4":
+"debug@npm:4, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4, debug@npm:^4.3.5":
version: 4.3.5
resolution: "debug@npm:4.3.5"
dependencies:
@@ -12923,7 +13157,7 @@ __metadata:
languageName: node
linkType: hard
-"debug@npm:^3.1.0, debug@npm:^3.2.7":
+"debug@npm:^3.2.7":
version: 3.2.7
resolution: "debug@npm:3.2.7"
dependencies:
@@ -13117,14 +13351,10 @@ __metadata:
languageName: node
linkType: hard
-"degenerator@npm:^5.0.0":
- version: 5.0.1
- resolution: "degenerator@npm:5.0.1"
- dependencies:
- ast-types: "npm:^0.13.4"
- escodegen: "npm:^2.1.0"
- esprima: "npm:^4.0.1"
- checksum: 10c0/e48d8a651edeb512a648711a09afec269aac6de97d442a4bb9cf121a66877e0eec11b9727100a10252335c0666ae1c84a8bc1e3a3f47788742c975064d2c7b1c
+"defu@npm:^6.1.4":
+ version: 6.1.6
+ resolution: "defu@npm:6.1.6"
+ checksum: 10c0/6755a914d4d1b40346d582cadf3af0c4efb1b89c462631f4c8a20c933da88d5da674344dd0856426d611d5fc0c65a3ffa82388519127b06f1a688dc103ddf5ba
languageName: node
linkType: hard
@@ -13300,13 +13530,6 @@ __metadata:
languageName: node
linkType: hard
-"devtools-protocol@npm:0.0.1521046":
- version: 0.0.1521046
- resolution: "devtools-protocol@npm:0.0.1521046"
- checksum: 10c0/ba4b83a94e2b9c26772b22a8f6029ff296976a72db8e4567c9076393fccc39a452f6c0530869eebe2e1ad483db0e6233cd6b7b723ce466a05660c758f5e06db0
- languageName: node
- linkType: hard
-
"dezalgo@npm:^1.0.4":
version: 1.0.4
resolution: "dezalgo@npm:1.0.4"
@@ -13317,13 +13540,6 @@ __metadata:
languageName: node
linkType: hard
-"di@npm:^0.0.1":
- version: 0.0.1
- resolution: "di@npm:0.0.1"
- checksum: 10c0/fbca4cc93e8c493d50f82df3a9ecaa5d8b2935674aabddeb8f68db3ab03c942c201f9c3d920de094407392ee6f488eac16b96f500c0ea6b408634864b7b939d1
- languageName: node
- linkType: hard
-
"didyoumean@npm:^1.2.2":
version: 1.2.2
resolution: "didyoumean@npm:1.2.2"
@@ -13436,18 +13652,6 @@ __metadata:
languageName: node
linkType: hard
-"dom-serialize@npm:^2.2.1":
- version: 2.2.1
- resolution: "dom-serialize@npm:2.2.1"
- dependencies:
- custom-event: "npm:~1.0.0"
- ent: "npm:~2.2.0"
- extend: "npm:^3.0.0"
- void-elements: "npm:^2.0.0"
- checksum: 10c0/ceb6e62b73c658986ca4c9b8b2fae358d8ae914eb06712d137da595a327c3bbca45a762f412a6d181f892ce5e3cffb855c2db2b64c53ad0534b2a0ad8e65b05e
- languageName: node
- linkType: hard
-
"dom-serializer@npm:0":
version: 0.2.2
resolution: "dom-serializer@npm:0.2.2"
@@ -13610,7 +13814,7 @@ __metadata:
languageName: node
linkType: hard
-"duplexer@npm:^0.1.2, duplexer@npm:~0.1.1":
+"duplexer@npm:^0.1.2":
version: 0.1.2
resolution: "duplexer@npm:0.1.2"
checksum: 10c0/c57bcd4bdf7e623abab2df43a7b5b23d18152154529d166c1e0da6bee341d84c432d157d7e97b32fecb1bf3a8b8857dd85ed81a915789f550637ed25b8e64fc2
@@ -13764,31 +13968,6 @@ __metadata:
languageName: node
linkType: hard
-"engine.io-parser@npm:~5.2.1":
- version: 5.2.2
- resolution: "engine.io-parser@npm:5.2.2"
- checksum: 10c0/38e71a92ed75e2873d4d9cfab7f889e4a3cfc939b689abd1045e1b2ef9f1a50d0350a2bef69f33d313c1aa626232702da5a9043a1038d76f5ecc0be440c648ab
- languageName: node
- linkType: hard
-
-"engine.io@npm:~6.5.2":
- version: 6.5.5
- resolution: "engine.io@npm:6.5.5"
- dependencies:
- "@types/cookie": "npm:^0.4.1"
- "@types/cors": "npm:^2.8.12"
- "@types/node": "npm:>=10.0.0"
- accepts: "npm:~1.3.4"
- base64id: "npm:2.0.0"
- cookie: "npm:~0.4.1"
- cors: "npm:~2.8.5"
- debug: "npm:~4.3.1"
- engine.io-parser: "npm:~5.2.1"
- ws: "npm:~8.17.1"
- checksum: 10c0/b0994134917c5d3649fd7aea283492eaf092131e572a8d379c7c9081548b42cff756730b4641edd0d1598148dd3be253c4d634cea2ba5c59622d175d9e567469
- languageName: node
- linkType: hard
-
"enhanced-resolve@npm:^5.0.0, enhanced-resolve@npm:^5.17.0, enhanced-resolve@npm:^5.7.0":
version: 5.17.0
resolution: "enhanced-resolve@npm:5.17.0"
@@ -13819,13 +13998,6 @@ __metadata:
languageName: node
linkType: hard
-"ent@npm:~2.2.0":
- version: 2.2.0
- resolution: "ent@npm:2.2.0"
- checksum: 10c0/d12c504d93afb8b22551323f78f60f0a2660289cf2de2210bdd2fdb07ac204956da23510a7711bf48079aa0aa726e21724224de6c6289120ddcf27652b30cb17
- languageName: node
- linkType: hard
-
"entities@npm:^2.0.0":
version: 2.2.0
resolution: "entities@npm:2.2.0"
@@ -13840,7 +14012,7 @@ __metadata:
languageName: node
linkType: hard
-"env-paths@npm:^2.2.0, env-paths@npm:^2.2.1":
+"env-paths@npm:^2.2.0":
version: 2.2.1
resolution: "env-paths@npm:2.2.1"
checksum: 10c0/285325677bf00e30845e330eec32894f5105529db97496ee3f598478e50f008c5352a41a30e5e72ec9de8a542b5a570b85699cd63bd2bc646dbcb9f311d83bc4
@@ -14173,22 +14345,6 @@ __metadata:
languageName: node
linkType: hard
-"es6-promise@npm:^4.0.3":
- version: 4.2.8
- resolution: "es6-promise@npm:4.2.8"
- checksum: 10c0/2373d9c5e9a93bdd9f9ed32ff5cb6dd3dd785368d1c21e9bbbfd07d16345b3774ae260f2bd24c8f836a6903f432b4151e7816a7fa8891ccb4e1a55a028ec42c3
- languageName: node
- linkType: hard
-
-"es6-promisify@npm:^5.0.0":
- version: 5.0.0
- resolution: "es6-promisify@npm:5.0.0"
- dependencies:
- es6-promise: "npm:^4.0.3"
- checksum: 10c0/23284c6a733cbf7842ec98f41eac742c9f288a78753c4fe46652bae826446ced7615b9e8a5c5f121a08812b1cd478ea58630f3e1c3d70835bd5dcd69c7cd75c9
- languageName: node
- linkType: hard
-
"esbuild-plugins-node-modules-polyfill@npm:^1.6.0":
version: 1.6.8
resolution: "esbuild-plugins-node-modules-polyfill@npm:1.6.8"
@@ -14202,6 +14358,83 @@ __metadata:
languageName: node
linkType: hard
+"esbuild@npm:0.17.19":
+ version: 0.17.19
+ resolution: "esbuild@npm:0.17.19"
+ dependencies:
+ "@esbuild/android-arm": "npm:0.17.19"
+ "@esbuild/android-arm64": "npm:0.17.19"
+ "@esbuild/android-x64": "npm:0.17.19"
+ "@esbuild/darwin-arm64": "npm:0.17.19"
+ "@esbuild/darwin-x64": "npm:0.17.19"
+ "@esbuild/freebsd-arm64": "npm:0.17.19"
+ "@esbuild/freebsd-x64": "npm:0.17.19"
+ "@esbuild/linux-arm": "npm:0.17.19"
+ "@esbuild/linux-arm64": "npm:0.17.19"
+ "@esbuild/linux-ia32": "npm:0.17.19"
+ "@esbuild/linux-loong64": "npm:0.17.19"
+ "@esbuild/linux-mips64el": "npm:0.17.19"
+ "@esbuild/linux-ppc64": "npm:0.17.19"
+ "@esbuild/linux-riscv64": "npm:0.17.19"
+ "@esbuild/linux-s390x": "npm:0.17.19"
+ "@esbuild/linux-x64": "npm:0.17.19"
+ "@esbuild/netbsd-x64": "npm:0.17.19"
+ "@esbuild/openbsd-x64": "npm:0.17.19"
+ "@esbuild/sunos-x64": "npm:0.17.19"
+ "@esbuild/win32-arm64": "npm:0.17.19"
+ "@esbuild/win32-ia32": "npm:0.17.19"
+ "@esbuild/win32-x64": "npm:0.17.19"
+ dependenciesMeta:
+ "@esbuild/android-arm":
+ optional: true
+ "@esbuild/android-arm64":
+ optional: true
+ "@esbuild/android-x64":
+ optional: true
+ "@esbuild/darwin-arm64":
+ optional: true
+ "@esbuild/darwin-x64":
+ optional: true
+ "@esbuild/freebsd-arm64":
+ optional: true
+ "@esbuild/freebsd-x64":
+ optional: true
+ "@esbuild/linux-arm":
+ optional: true
+ "@esbuild/linux-arm64":
+ optional: true
+ "@esbuild/linux-ia32":
+ optional: true
+ "@esbuild/linux-loong64":
+ optional: true
+ "@esbuild/linux-mips64el":
+ optional: true
+ "@esbuild/linux-ppc64":
+ optional: true
+ "@esbuild/linux-riscv64":
+ optional: true
+ "@esbuild/linux-s390x":
+ optional: true
+ "@esbuild/linux-x64":
+ optional: true
+ "@esbuild/netbsd-x64":
+ optional: true
+ "@esbuild/openbsd-x64":
+ optional: true
+ "@esbuild/sunos-x64":
+ optional: true
+ "@esbuild/win32-arm64":
+ optional: true
+ "@esbuild/win32-ia32":
+ optional: true
+ "@esbuild/win32-x64":
+ optional: true
+ bin:
+ esbuild: bin/esbuild
+ checksum: 10c0/c7ac14bfaaebe4745d5d18347b4f6854fd1140acb9389e88dbfa5c20d4e2122451d9647d5498920470a880a605d6e5502b5c2102da6c282b01f129ddd49d2874
+ languageName: node
+ linkType: hard
+
"esbuild@npm:0.17.6":
version: 0.17.6
resolution: "esbuild@npm:0.17.6"
@@ -14589,7 +14822,7 @@ __metadata:
languageName: node
linkType: hard
-"escodegen@npm:^2.0.0, escodegen@npm:^2.1.0":
+"escodegen@npm:^2.0.0":
version: 2.1.0
resolution: "escodegen@npm:2.1.0"
dependencies:
@@ -15382,6 +15615,13 @@ __metadata:
languageName: node
linkType: hard
+"estree-walker@npm:^0.6.1":
+ version: 0.6.1
+ resolution: "estree-walker@npm:0.6.1"
+ checksum: 10c0/6dabc855faa04a1ffb17b6a9121b6008ba75ab5a163ad9dc3d7fca05cfda374c5f5e91418d783496620ca75e99a73c40874d8b75f23b4117508cc8bde78e7b41
+ languageName: node
+ linkType: hard
+
"estree-walker@npm:^1.0.1":
version: 1.0.1
resolution: "estree-walker@npm:1.0.1"
@@ -15429,21 +15669,6 @@ __metadata:
languageName: node
linkType: hard
-"event-stream@npm:=3.3.4":
- version: 3.3.4
- resolution: "event-stream@npm:3.3.4"
- dependencies:
- duplexer: "npm:~0.1.1"
- from: "npm:~0"
- map-stream: "npm:~0.1.0"
- pause-stream: "npm:0.0.11"
- split: "npm:0.3"
- stream-combiner: "npm:~0.0.4"
- through: "npm:~2.3.1"
- checksum: 10c0/c3ec4e1efc27ab3e73a98923f0a2fa9a19051b87068fea2f3d53d2e4e8c5cfdadf8c8a115b17f3d90b16a46432d396bad91b6e8d0cceb3e449be717a03b75209
- languageName: node
- linkType: hard
-
"event-target-shim@npm:^5.0.0":
version: 5.0.1
resolution: "event-target-shim@npm:5.0.1"
@@ -15458,15 +15683,6 @@ __metadata:
languageName: node
linkType: hard
-"events-universal@npm:^1.0.0":
- version: 1.0.1
- resolution: "events-universal@npm:1.0.1"
- dependencies:
- bare-events: "npm:^2.7.0"
- checksum: 10c0/a1d9a5e9f95843650f8ec240dd1221454c110189a9813f32cdf7185759b43f1f964367ac7dca4ebc69150b59043f2d77c7e122b0d03abf7c25477ea5494785a5
- languageName: node
- linkType: hard
-
"events@npm:^3.0.0, events@npm:^3.2.0":
version: 3.3.0
resolution: "events@npm:3.3.0"
@@ -15676,6 +15892,13 @@ __metadata:
languageName: node
linkType: hard
+"exsolve@npm:^1.0.1":
+ version: 1.0.8
+ resolution: "exsolve@npm:1.0.8"
+ checksum: 10c0/65e44ae05bd4a4a5d87cfdbbd6b8f24389282cf9f85fa5feb17ca87ad3f354877e6af4cd99e02fc29044174891f82d1d68c77f69234410eb8f163530e6278c67
+ languageName: node
+ linkType: hard
+
"extend@npm:^3.0.0":
version: 3.0.2
resolution: "extend@npm:3.0.2"
@@ -15683,23 +15906,6 @@ __metadata:
languageName: node
linkType: hard
-"extract-zip@npm:^2.0.1":
- version: 2.0.1
- resolution: "extract-zip@npm:2.0.1"
- dependencies:
- "@types/yauzl": "npm:^2.9.1"
- debug: "npm:^4.1.1"
- get-stream: "npm:^5.1.0"
- yauzl: "npm:^2.10.0"
- dependenciesMeta:
- "@types/yauzl":
- optional: true
- bin:
- extract-zip: cli.js
- checksum: 10c0/9afbd46854aa15a857ae0341a63a92743a7b89c8779102c3b4ffc207516b2019337353962309f85c66ee3d9092202a83cdc26dbf449a11981272038443974aee
- languageName: node
- linkType: hard
-
"fast-deep-equal@npm:^3.1.1, fast-deep-equal@npm:^3.1.3":
version: 3.1.3
resolution: "fast-deep-equal@npm:3.1.3"
@@ -15714,13 +15920,6 @@ __metadata:
languageName: node
linkType: hard
-"fast-fifo@npm:^1.2.0, fast-fifo@npm:^1.3.2":
- version: 1.3.2
- resolution: "fast-fifo@npm:1.3.2"
- checksum: 10c0/d53f6f786875e8b0529f784b59b4b05d4b5c31c651710496440006a398389a579c8dbcd2081311478b5bf77f4b0b21de69109c5a4eabea9d8e8783d1eb864e4c
- languageName: node
- linkType: hard
-
"fast-glob@npm:3.3.1":
version: 3.3.1
resolution: "fast-glob@npm:3.3.1"
@@ -15811,15 +16010,6 @@ __metadata:
languageName: node
linkType: hard
-"fd-slicer@npm:~1.1.0":
- version: 1.1.0
- resolution: "fd-slicer@npm:1.1.0"
- dependencies:
- pend: "npm:~1.2.0"
- checksum: 10c0/304dd70270298e3ffe3bcc05e6f7ade2511acc278bc52d025f8918b48b6aa3b77f10361bddfadfe2a28163f7af7adbdce96f4d22c31b2f648ba2901f0c5fc20e
- languageName: node
- linkType: hard
-
"fdir@npm:^6.2.0, fdir@npm:^6.5.0":
version: 6.5.0
resolution: "fdir@npm:6.5.0"
@@ -15907,27 +16097,12 @@ __metadata:
languageName: node
linkType: hard
-"fill-range@npm:^7.1.1":
- version: 7.1.1
- resolution: "fill-range@npm:7.1.1"
- dependencies:
- to-regex-range: "npm:^5.0.1"
- checksum: 10c0/b75b691bbe065472f38824f694c2f7449d7f5004aa950426a2c28f0306c60db9b880c0b0e4ed819997ffb882d1da02cfcfc819bddc94d71627f5269682edf018
- languageName: node
- linkType: hard
-
-"finalhandler@npm:1.1.2":
- version: 1.1.2
- resolution: "finalhandler@npm:1.1.2"
- dependencies:
- debug: "npm:2.6.9"
- encodeurl: "npm:~1.0.2"
- escape-html: "npm:~1.0.3"
- on-finished: "npm:~2.3.0"
- parseurl: "npm:~1.3.3"
- statuses: "npm:~1.5.0"
- unpipe: "npm:~1.0.0"
- checksum: 10c0/6a96e1f5caab085628c11d9fdceb82ba608d5e426c6913d4d918409baa271037a47f28fbba73279e8ad614f0b8fa71ea791d265e408d760793829edd8c2f4584
+"fill-range@npm:^7.1.1":
+ version: 7.1.1
+ resolution: "fill-range@npm:7.1.1"
+ dependencies:
+ to-regex-range: "npm:^5.0.1"
+ checksum: 10c0/b75b691bbe065472f38824f694c2f7449d7f5004aa950426a2c28f0306c60db9b880c0b0e4ed819997ffb882d1da02cfcfc819bddc94d71627f5269682edf018
languageName: node
linkType: hard
@@ -16045,7 +16220,7 @@ __metadata:
languageName: node
linkType: hard
-"flatted@npm:^3.2.7, flatted@npm:^3.2.9":
+"flatted@npm:^3.2.9":
version: 3.3.1
resolution: "flatted@npm:3.3.1"
checksum: 10c0/324166b125ee07d4ca9bcf3a5f98d915d5db4f39d711fba640a3178b959919aae1f7cfd8aabcfef5826ed8aa8a2aa14cc85b2d7d18ff638ddf4ae3df39573eaf
@@ -16245,13 +16420,6 @@ __metadata:
languageName: node
linkType: hard
-"from@npm:~0":
- version: 0.1.7
- resolution: "from@npm:0.1.7"
- checksum: 10c0/3aab5aea8fe8e1f12a5dee7f390d46a93431ce691b6222dcd5701c5d34378e51ca59b44967da1105a0f90fcdf5d7629d963d51e7ccd79827d19693bdcfb688d4
- languageName: node
- linkType: hard
-
"fromentries@npm:^1.2.0":
version: 1.3.2
resolution: "fromentries@npm:1.3.2"
@@ -16277,17 +16445,6 @@ __metadata:
languageName: node
linkType: hard
-"fs-extra@npm:^11.2.0":
- version: 11.2.0
- resolution: "fs-extra@npm:11.2.0"
- dependencies:
- graceful-fs: "npm:^4.2.0"
- jsonfile: "npm:^6.0.1"
- universalify: "npm:^2.0.0"
- checksum: 10c0/d77a9a9efe60532d2e790e938c81a02c1b24904ef7a3efb3990b835514465ba720e99a6ea56fd5e2db53b4695319b644d76d5a0e9988a2beef80aa7b1da63398
- languageName: node
- linkType: hard
-
"fs-extra@npm:^8.1.0":
version: 8.1.0
resolution: "fs-extra@npm:8.1.0"
@@ -16350,6 +16507,16 @@ __metadata:
languageName: node
linkType: hard
+"fsevents@npm:2.3.2":
+ version: 2.3.2
+ resolution: "fsevents@npm:2.3.2"
+ dependencies:
+ node-gyp: "npm:latest"
+ checksum: 10c0/be78a3efa3e181cda3cf7a4637cb527bcebb0bd0ea0440105a3bb45b86f9245b307dc10a2507e8f4498a7d4ec349d1910f4d73e4d4495b16103106e07eee735b
+ conditions: os=darwin
+ languageName: node
+ linkType: hard
+
"fsevents@npm:^2.3.2, fsevents@npm:^2.3.3, fsevents@npm:~2.3.2, fsevents@npm:~2.3.3":
version: 2.3.3
resolution: "fsevents@npm:2.3.3"
@@ -16360,6 +16527,15 @@ __metadata:
languageName: node
linkType: hard
+"fsevents@patch:fsevents@npm%3A2.3.2#optional!builtin":
+ version: 2.3.2
+ resolution: "fsevents@patch:fsevents@npm%3A2.3.2#optional!builtin::version=2.3.2&hash=df0bf1"
+ dependencies:
+ node-gyp: "npm:latest"
+ conditions: os=darwin
+ languageName: node
+ linkType: hard
+
"fsevents@patch:fsevents@npm%3A^2.3.2#optional!builtin, fsevents@patch:fsevents@npm%3A^2.3.3#optional!builtin, fsevents@patch:fsevents@npm%3A~2.3.2#optional!builtin, fsevents@patch:fsevents@npm%3A~2.3.3#optional!builtin":
version: 2.3.3
resolution: "fsevents@patch:fsevents@npm%3A2.3.3#optional!builtin::version=2.3.3&hash=df0bf1"
@@ -16518,12 +16694,13 @@ __metadata:
languageName: node
linkType: hard
-"get-stream@npm:^5.1.0":
- version: 5.2.0
- resolution: "get-stream@npm:5.2.0"
+"get-source@npm:^2.0.12":
+ version: 2.0.12
+ resolution: "get-source@npm:2.0.12"
dependencies:
- pump: "npm:^3.0.0"
- checksum: 10c0/43797ffd815fbb26685bf188c8cfebecb8af87b3925091dd7b9a9c915993293d78e3c9e1bce125928ff92f2d0796f3889b92b5ec6d58d1041b574682132e0a80
+ data-uri-to-buffer: "npm:^2.0.0"
+ source-map: "npm:^0.6.1"
+ checksum: 10c0/b1db46d28902344fd9407e1f0ed0b8f3a85cb4650f85ba8cee9c0b422fc75118172f12f735706e2c6e034617b13a2fbc5266e7fab617ecb184f0cee074b9dd3e
languageName: node
linkType: hard
@@ -16574,18 +16751,6 @@ __metadata:
languageName: node
linkType: hard
-"get-uri@npm:^6.0.1":
- version: 6.0.3
- resolution: "get-uri@npm:6.0.3"
- dependencies:
- basic-ftp: "npm:^5.0.2"
- data-uri-to-buffer: "npm:^6.0.2"
- debug: "npm:^4.3.4"
- fs-extra: "npm:^11.2.0"
- checksum: 10c0/8d801c462cd5b9c171d4d9e5f17afce3d9ebfbbfb006a88e3e768ce0071a8e2e59ee1ce822915fc43b9d6b83fde7b8d1c9648330ae89778fa41ad774df8ee0ac
- languageName: node
- linkType: hard
-
"glob-parent@npm:^5.1.2, glob-parent@npm:~5.1.2":
version: 5.1.2
resolution: "glob-parent@npm:5.1.2"
@@ -16604,7 +16769,7 @@ __metadata:
languageName: node
linkType: hard
-"glob-to-regexp@npm:^0.4.1":
+"glob-to-regexp@npm:0.4.1, glob-to-regexp@npm:^0.4.1":
version: 0.4.1
resolution: "glob-to-regexp@npm:0.4.1"
checksum: 10c0/0486925072d7a916f052842772b61c3e86247f0a80cc0deb9b5a3e8a1a9faad5b04fb6f58986a09f34d3e96cd2a22a24b7e9882fb1cf904c31e9a310de96c429
@@ -16658,7 +16823,7 @@ __metadata:
languageName: node
linkType: hard
-"glob@npm:^7.0.5, glob@npm:^7.1.0, glob@npm:^7.1.1, glob@npm:^7.1.2, glob@npm:^7.1.3, glob@npm:^7.1.4, glob@npm:^7.1.6, glob@npm:^7.1.7, glob@npm:^7.2.0":
+"glob@npm:^7.1.0, glob@npm:^7.1.1, glob@npm:^7.1.2, glob@npm:^7.1.3, glob@npm:^7.1.4, glob@npm:^7.1.6, glob@npm:^7.2.0":
version: 7.2.3
resolution: "glob@npm:7.2.3"
dependencies:
@@ -16785,7 +16950,7 @@ __metadata:
languageName: node
linkType: hard
-"graceful-fs@npm:^4.1.11, graceful-fs@npm:^4.1.15, graceful-fs@npm:^4.1.2, graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.1.9, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.10, graceful-fs@npm:^4.2.11, graceful-fs@npm:^4.2.4, graceful-fs@npm:^4.2.6, graceful-fs@npm:^4.2.9":
+"graceful-fs@npm:^4.1.11, graceful-fs@npm:^4.1.15, graceful-fs@npm:^4.1.2, graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.1.9, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.11, graceful-fs@npm:^4.2.4, graceful-fs@npm:^4.2.6, graceful-fs@npm:^4.2.9":
version: 4.2.11
resolution: "graceful-fs@npm:4.2.11"
checksum: 10c0/386d011a553e02bc594ac2ca0bd6d9e4c22d7fa8cfbfc448a6d148c59ea881b092db9dbe3547ae4b88e55f1b01f7c4a2ecc53b310c042793e63aa44cf6c257f2
@@ -17031,13 +17196,6 @@ __metadata:
languageName: node
linkType: hard
-"hat@npm:^0.0.3":
- version: 0.0.3
- resolution: "hat@npm:0.0.3"
- checksum: 10c0/9d502b26b612ed3e66491296873119574e61a4ef99dfc5501f7bf86115fde35d0f76b1167257c8224c88092eda04e40feda805ad5b86c3b90203f4e15fd99f53
- languageName: node
- linkType: hard
-
"he@npm:^1.2.0":
version: 1.2.0
resolution: "he@npm:1.2.0"
@@ -17246,7 +17404,7 @@ __metadata:
languageName: node
linkType: hard
-"http-proxy-agent@npm:^7.0.0, http-proxy-agent@npm:^7.0.1":
+"http-proxy-agent@npm:^7.0.0":
version: 7.0.2
resolution: "http-proxy-agent@npm:7.0.2"
dependencies:
@@ -17288,17 +17446,7 @@ __metadata:
languageName: node
linkType: hard
-"https-proxy-agent@npm:^2.2.1":
- version: 2.2.4
- resolution: "https-proxy-agent@npm:2.2.4"
- dependencies:
- agent-base: "npm:^4.3.0"
- debug: "npm:^3.1.0"
- checksum: 10c0/4bdde8fcd9ea0adc4a77282de2b4f9e27955e0441425af0f27f0fe01006946b80eaee6749e08e838d350c06ed2ebd5d11347d3beb88c45eacb0667e27276cdad
- languageName: node
- linkType: hard
-
-"https-proxy-agent@npm:^5.0.0, https-proxy-agent@npm:^5.0.1":
+"https-proxy-agent@npm:^5.0.0":
version: 5.0.1
resolution: "https-proxy-agent@npm:5.0.1"
dependencies:
@@ -17318,16 +17466,6 @@ __metadata:
languageName: node
linkType: hard
-"https-proxy-agent@npm:^7.0.6":
- version: 7.0.6
- resolution: "https-proxy-agent@npm:7.0.6"
- dependencies:
- agent-base: "npm:^7.1.2"
- debug: "npm:4"
- checksum: 10c0/f729219bc735edb621fa30e6e84e60ee5d00802b8247aac0d7b79b0bd6d4b3294737a337b93b86a0bd9e68099d031858a39260c976dc14cdbba238ba1f8779ac
- languageName: node
- linkType: hard
-
"human-signals@npm:^2.1.0":
version: 2.1.0
resolution: "human-signals@npm:2.1.0"
@@ -17552,13 +17690,6 @@ __metadata:
languageName: node
linkType: hard
-"ip-address@npm:^10.0.1":
- version: 10.1.0
- resolution: "ip-address@npm:10.1.0"
- checksum: 10c0/0103516cfa93f6433b3bd7333fa876eb21263912329bfa47010af5e16934eeeff86f3d2ae700a3744a137839ddfad62b900c7a445607884a49b5d1e32a3d7566
- languageName: node
- linkType: hard
-
"ip-address@npm:^9.0.5":
version: 9.0.5
resolution: "ip-address@npm:9.0.5"
@@ -17638,6 +17769,13 @@ __metadata:
languageName: node
linkType: hard
+"is-arrayish@npm:^0.3.1":
+ version: 0.3.4
+ resolution: "is-arrayish@npm:0.3.4"
+ checksum: 10c0/1fa672a2f0bedb74154440310f616c0b6e53a95cf0625522ae050f06626d1cabd1a3d8085c882dc45c61ad0e7df2529aff122810b3b4a552880bf170d6df94e0
+ languageName: node
+ linkType: hard
+
"is-async-function@npm:^2.0.0":
version: 2.0.0
resolution: "is-async-function@npm:2.0.0"
@@ -18122,13 +18260,6 @@ __metadata:
languageName: node
linkType: hard
-"is-running@npm:^2.1.0":
- version: 2.1.0
- resolution: "is-running@npm:2.1.0"
- checksum: 10c0/3caf610508336e7b4d3f63323138ea479f38b7f74c9318254c6c999e06cc9f9bc23727183bb103a3564d517c0b3b9ac057768b3a681c6a63a246089c3ac01c8b
- languageName: node
- linkType: hard
-
"is-set@npm:^2.0.3":
version: 2.0.3
resolution: "is-set@npm:2.0.3"
@@ -18297,13 +18428,6 @@ __metadata:
languageName: node
linkType: hard
-"isbinaryfile@npm:^4.0.8":
- version: 4.0.10
- resolution: "isbinaryfile@npm:4.0.10"
- checksum: 10c0/0703d8cfeb69ed79e6d173120f327450011a066755150a6bbf97ffecec1069a5f2092777868315b21359098c84b54984871cad1abce877ad9141fb2caf3dcabf
- languageName: node
- linkType: hard
-
"isbot@npm:^5.1.32":
version: 5.1.32
resolution: "isbot@npm:5.1.32"
@@ -19549,13 +19673,6 @@ __metadata:
languageName: node
linkType: hard
-"js-string-escape@npm:^1.0.0":
- version: 1.0.1
- resolution: "js-string-escape@npm:1.0.1"
- checksum: 10c0/2c33b9ff1ba6b84681c51ca0997e7d5a1639813c95d5b61cb7ad47e55cc28fa4a0b1935c3d218710d8e6bcee5d0cd8c44755231e3a4e45fc604534d9595a3628
- languageName: node
- linkType: hard
-
"js-stringify@npm:^1.0.1, js-stringify@npm:^1.0.2":
version: 1.0.2
resolution: "js-stringify@npm:1.0.2"
@@ -19858,145 +19975,6 @@ __metadata:
languageName: node
linkType: hard
-"karma-browserify@npm:^8.1.0":
- version: 8.1.0
- resolution: "karma-browserify@npm:8.1.0"
- dependencies:
- convert-source-map: "npm:^1.8.0"
- hat: "npm:^0.0.3"
- js-string-escape: "npm:^1.0.0"
- lodash: "npm:^4.17.21"
- minimatch: "npm:^3.0.0"
- os-shim: "npm:^0.1.3"
- peerDependencies:
- browserify: ">=10 <18"
- karma: ">=4.3.0"
- watchify: ">=3 <5"
- checksum: 10c0/2de3e52a8038a9768b9d69cffcad64d9ab212df8f2c095504261a856a71d08abde022967e55a8d50ca2062de35675f4ae9be5831c79da019c0fd053a1dde7c2b
- languageName: node
- linkType: hard
-
-"karma-browserstack-launcher@npm:^1.6.0":
- version: 1.6.0
- resolution: "karma-browserstack-launcher@npm:1.6.0"
- dependencies:
- browserstack: "npm:~1.5.1"
- browserstack-local: "npm:^1.3.7"
- q: "npm:~1.5.0"
- peerDependencies:
- karma: ">=0.9"
- checksum: 10c0/d3e326732157000710d3c7a3751e82611ba7b3fdb25cdc86e059a6441855446273094887854e67a68ded654d7a033142fa2355b457e416a074c17fc16795e2c9
- languageName: node
- linkType: hard
-
-"karma-chai@npm:^0.1.0":
- version: 0.1.0
- resolution: "karma-chai@npm:0.1.0"
- peerDependencies:
- chai: "*"
- karma: ">=0.10.9"
- checksum: 10c0/f4a8ff07d34523830a7ddfa220121ee9be32fbc44303ead9b064698acd60a0ab4db35e911a8ce74a96af8739b8ba34688670bf63f3054adf43bd45dc256cdcc2
- languageName: node
- linkType: hard
-
-"karma-chrome-launcher@npm:^3.2.0":
- version: 3.2.0
- resolution: "karma-chrome-launcher@npm:3.2.0"
- dependencies:
- which: "npm:^1.2.1"
- checksum: 10c0/0cec1ae7d922110dc29cee36389d597157c82f019c8917259f9fa93d1f5ee8e19141c2eb74bfe30797cdb3adbc51a6b65fd18a9ebc1527c725c4acf62cd46d04
- languageName: node
- linkType: hard
-
-"karma-cli@npm:^2.0.0":
- version: 2.0.0
- resolution: "karma-cli@npm:2.0.0"
- dependencies:
- resolve: "npm:^1.3.3"
- bin:
- karma: ./bin/karma
- checksum: 10c0/4066c22d172d7cbce6be7de5529aa2200203ba958e47359cfe0c45dc29c5970dd3dc1863aef0f3fb17c6b21a5ba938959b17da606241ed844a788a283f94282b
- languageName: node
- linkType: hard
-
-"karma-mocha-reporter@npm:^2.2.5":
- version: 2.2.5
- resolution: "karma-mocha-reporter@npm:2.2.5"
- dependencies:
- chalk: "npm:^2.1.0"
- log-symbols: "npm:^2.1.0"
- strip-ansi: "npm:^4.0.0"
- peerDependencies:
- karma: ">=0.13"
- checksum: 10c0/5a26ea58fb683a6d6a7f8b6f6e51f8678432adfa6425356fb125c9e8dba4489061385b819dfd19e943ffe8f3e0f86a529386b7793d3065cd59d4756517023aba
- languageName: node
- linkType: hard
-
-"karma-mocha@npm:^2.0.1":
- version: 2.0.1
- resolution: "karma-mocha@npm:2.0.1"
- dependencies:
- minimist: "npm:^1.2.3"
- checksum: 10c0/99ef62d863f6bf8cb11df0f4a9d47615369a0ce8a937d9a0cd7fb83fdbb0ef7420c7ea396de514be48500fac1563a00ab964b7d1adc4ee3f5a875ebf07eb012d
- languageName: node
- linkType: hard
-
-"karma-sourcemap-loader@npm:^0.4.0":
- version: 0.4.0
- resolution: "karma-sourcemap-loader@npm:0.4.0"
- dependencies:
- graceful-fs: "npm:^4.2.10"
- checksum: 10c0/8f77516330bc78d7c4d22469bdfd96b82acf7a285e2c19b8f30ae9d9bb21c7d817b0c32b9e5ea6ae002b16365e124afea121910c089c641320ce5595cafaadac
- languageName: node
- linkType: hard
-
-"karma-webpack@npm:5.0.1":
- version: 5.0.1
- resolution: "karma-webpack@npm:5.0.1"
- dependencies:
- glob: "npm:^7.1.3"
- minimatch: "npm:^9.0.3"
- webpack-merge: "npm:^4.1.5"
- peerDependencies:
- webpack: ^5.0.0
- checksum: 10c0/ef7208a6b2746819693c654d6da4a1c7794edb72690006181e1c2897ff8415644e6745ca46bdf170e30c2b82d4b9f16284af5e71fcae026b32de0a08adb14c7d
- languageName: node
- linkType: hard
-
-"karma@npm:^6.4.4":
- version: 6.4.4
- resolution: "karma@npm:6.4.4"
- dependencies:
- "@colors/colors": "npm:1.5.0"
- body-parser: "npm:^1.19.0"
- braces: "npm:^3.0.2"
- chokidar: "npm:^3.5.1"
- connect: "npm:^3.7.0"
- di: "npm:^0.0.1"
- dom-serialize: "npm:^2.2.1"
- glob: "npm:^7.1.7"
- graceful-fs: "npm:^4.2.6"
- http-proxy: "npm:^1.18.1"
- isbinaryfile: "npm:^4.0.8"
- lodash: "npm:^4.17.21"
- log4js: "npm:^6.4.1"
- mime: "npm:^2.5.2"
- minimatch: "npm:^3.0.4"
- mkdirp: "npm:^0.5.5"
- qjobs: "npm:^1.2.0"
- range-parser: "npm:^1.2.1"
- rimraf: "npm:^3.0.2"
- socket.io: "npm:^4.7.2"
- source-map: "npm:^0.6.1"
- tmp: "npm:^0.2.1"
- ua-parser-js: "npm:^0.7.30"
- yargs: "npm:^16.1.1"
- bin:
- karma: bin/karma
- checksum: 10c0/1658c4b7396c0edf6f048289182e075b561902e02992e1a3eb72f56f67090ff0c7ad7c91ab099e88a790c60f9500c5a6f974d75f1769e3ea2dfccda52876ec0b
- languageName: node
- linkType: hard
-
"keyv@npm:^4.5.3, keyv@npm:^4.5.4":
version: 4.5.4
resolution: "keyv@npm:4.5.4"
@@ -20426,15 +20404,6 @@ __metadata:
languageName: node
linkType: hard
-"log-symbols@npm:^2.1.0":
- version: 2.2.0
- resolution: "log-symbols@npm:2.2.0"
- dependencies:
- chalk: "npm:^2.0.1"
- checksum: 10c0/574eb4205f54f0605021aa67ebb372c30ca64e8ddd439efeb8507af83c776dce789e83614e80059014d9e48dcc94c4b60cef2e85f0dc944eea27c799cec62353
- languageName: node
- linkType: hard
-
"log-symbols@npm:^4.1.0":
version: 4.1.0
resolution: "log-symbols@npm:4.1.0"
@@ -20445,19 +20414,6 @@ __metadata:
languageName: node
linkType: hard
-"log4js@npm:^6.4.1":
- version: 6.9.1
- resolution: "log4js@npm:6.9.1"
- dependencies:
- date-format: "npm:^4.0.14"
- debug: "npm:^4.3.4"
- flatted: "npm:^3.2.7"
- rfdc: "npm:^1.3.0"
- streamroller: "npm:^3.1.5"
- checksum: 10c0/05846e48f72d662800c8189bd178c42b4aa2f0c574cfc90a1942cf90b76f621c44019e26796c8fd88da1b6f0fe8272cba607cbaad6ae6ede50a7a096b58197ea
- languageName: node
- linkType: hard
-
"longest-streak@npm:^3.0.0":
version: 3.1.0
resolution: "longest-streak@npm:3.1.0"
@@ -20541,7 +20497,7 @@ __metadata:
languageName: node
linkType: hard
-"lru-cache@npm:^7.14.1, lru-cache@npm:^7.4.4, lru-cache@npm:^7.5.1, lru-cache@npm:^7.7.1":
+"lru-cache@npm:^7.4.4, lru-cache@npm:^7.5.1, lru-cache@npm:^7.7.1":
version: 7.18.3
resolution: "lru-cache@npm:7.18.3"
checksum: 10c0/b3a452b491433db885beed95041eb104c157ef7794b9c9b4d647be503be91769d11206bb573849a16b4cc0d03cbd15ffd22df7960997788b74c1d399ac7a4fed
@@ -20566,7 +20522,7 @@ __metadata:
languageName: node
linkType: hard
-"magic-string@npm:^0.25.0, magic-string@npm:^0.25.7":
+"magic-string@npm:^0.25.0, magic-string@npm:^0.25.3, magic-string@npm:^0.25.7":
version: 0.25.9
resolution: "magic-string@npm:0.25.9"
dependencies:
@@ -20657,13 +20613,6 @@ __metadata:
languageName: node
linkType: hard
-"map-stream@npm:~0.1.0":
- version: 0.1.0
- resolution: "map-stream@npm:0.1.0"
- checksum: 10c0/7dd6debe511c1b55d9da75e1efa65a28b1252a2d8357938d2e49b412713c478efbaefb0cdf0ee0533540c3bf733e8f9f71e1a15aa0fe74bf71b64e75bf1576bd
- languageName: node
- linkType: hard
-
"markdown-extensions@npm:^1.0.0":
version: 1.1.1
resolution: "markdown-extensions@npm:1.1.1"
@@ -21415,7 +21364,7 @@ __metadata:
languageName: node
linkType: hard
-"mime@npm:2.6.0, mime@npm:^2.5.2":
+"mime@npm:2.6.0":
version: 2.6.0
resolution: "mime@npm:2.6.0"
bin:
@@ -21424,6 +21373,15 @@ __metadata:
languageName: node
linkType: hard
+"mime@npm:^3.0.0":
+ version: 3.0.0
+ resolution: "mime@npm:3.0.0"
+ bin:
+ mime: cli.js
+ checksum: 10c0/402e792a8df1b2cc41cb77f0dcc46472b7944b7ec29cb5bbcd398624b6b97096728f1239766d3fdeb20551dd8d94738344c195a6ea10c4f906eb0356323b0531
+ languageName: node
+ linkType: hard
+
"mimic-fn@npm:^2.1.0":
version: 2.1.0
resolution: "mimic-fn@npm:2.1.0"
@@ -21450,6 +21408,27 @@ __metadata:
languageName: node
linkType: hard
+"miniflare@npm:3.20250718.3":
+ version: 3.20250718.3
+ resolution: "miniflare@npm:3.20250718.3"
+ dependencies:
+ "@cspotcode/source-map-support": "npm:0.8.1"
+ acorn: "npm:8.14.0"
+ acorn-walk: "npm:8.3.2"
+ exit-hook: "npm:2.2.1"
+ glob-to-regexp: "npm:0.4.1"
+ stoppable: "npm:1.1.0"
+ undici: "npm:^5.28.5"
+ workerd: "npm:1.20250718.0"
+ ws: "npm:8.18.0"
+ youch: "npm:3.3.4"
+ zod: "npm:3.22.3"
+ bin:
+ miniflare: bootstrap.js
+ checksum: 10c0/ebabf4640c6d736589a91833eb5bd00c218175d8fc7ae938fff9014c0ec01d1fc80b11f961df79cd8cdef8d26c4d5ccdb63d5f618f671a1f0b59dc0f5a368ae5
+ languageName: node
+ linkType: hard
+
"minimalistic-assert@npm:^1.0.0, minimalistic-assert@npm:^1.0.1":
version: 1.0.1
resolution: "minimalistic-assert@npm:1.0.1"
@@ -21464,7 +21443,7 @@ __metadata:
languageName: node
linkType: hard
-"minimatch@npm:3.1.2, minimatch@npm:^3.0.0, minimatch@npm:^3.0.2, minimatch@npm:^3.0.4, minimatch@npm:^3.0.5, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2":
+"minimatch@npm:3.1.2, minimatch@npm:^3.0.2, minimatch@npm:^3.0.4, minimatch@npm:^3.0.5, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2":
version: 3.1.2
resolution: "minimatch@npm:3.1.2"
dependencies:
@@ -21500,7 +21479,7 @@ __metadata:
languageName: node
linkType: hard
-"minimatch@npm:^9.0.3, minimatch@npm:^9.0.4":
+"minimatch@npm:^9.0.4":
version: 9.0.4
resolution: "minimatch@npm:9.0.4"
dependencies:
@@ -21509,7 +21488,7 @@ __metadata:
languageName: node
linkType: hard
-"minimist@npm:^1.1.0, minimist@npm:^1.2.0, minimist@npm:^1.2.3, minimist@npm:^1.2.5, minimist@npm:^1.2.6":
+"minimist@npm:^1.1.0, minimist@npm:^1.2.0, minimist@npm:^1.2.5, minimist@npm:^1.2.6":
version: 1.2.8
resolution: "minimist@npm:1.2.8"
checksum: 10c0/19d3fcdca050087b84c2029841a093691a91259a47def2f18222f41e7645a0b7c44ef4b40e88a1e58a40c84d2ef0ee6047c55594d298146d0eb3f6b737c20ce6
@@ -21609,13 +21588,6 @@ __metadata:
languageName: node
linkType: hard
-"mitt@npm:^3.0.1":
- version: 3.0.1
- resolution: "mitt@npm:3.0.1"
- checksum: 10c0/3ab4fdecf3be8c5255536faa07064d05caa3dd332bd318ff02e04621f7b3069ca1de9106cfe8e7ced675abfc2bec2ce4c4ef321c4a1bb1fb29df8ae090741913
- languageName: node
- linkType: hard
-
"mkdirp-classic@npm:^0.5.2":
version: 0.5.3
resolution: "mkdirp-classic@npm:0.5.3"
@@ -21623,7 +21595,7 @@ __metadata:
languageName: node
linkType: hard
-"mkdirp@npm:^0.5.3, mkdirp@npm:^0.5.5, mkdirp@npm:^0.5.6, mkdirp@npm:~0.5.1":
+"mkdirp@npm:^0.5.3, mkdirp@npm:^0.5.6, mkdirp@npm:~0.5.1":
version: 0.5.6
resolution: "mkdirp@npm:0.5.6"
dependencies:
@@ -21817,6 +21789,15 @@ __metadata:
languageName: node
linkType: hard
+"mustache@npm:^4.2.0":
+ version: 4.2.0
+ resolution: "mustache@npm:4.2.0"
+ bin:
+ mustache: bin/mustache
+ checksum: 10c0/1f8197e8a19e63645a786581d58c41df7853da26702dbc005193e2437c98ca49b255345c173d50c08fe4b4dbb363e53cb655ecc570791f8deb09887248dd34a2
+ languageName: node
+ linkType: hard
+
"mute-stream@npm:^3.0.0":
version: 3.0.0
resolution: "mute-stream@npm:3.0.0"
@@ -21904,13 +21885,6 @@ __metadata:
languageName: node
linkType: hard
-"netmask@npm:^2.0.2":
- version: 2.0.2
- resolution: "netmask@npm:2.0.2"
- checksum: 10c0/cafd28388e698e1138ace947929f842944d0f1c0b87d3fa2601a61b38dc89397d33c0ce2c8e7b99e968584b91d15f6810b91bef3f3826adf71b1833b61d4bf4f
- languageName: node
- linkType: hard
-
"next@npm:16.0.1":
version: 16.0.1
resolution: "next@npm:16.0.1"
@@ -22400,6 +22374,13 @@ __metadata:
languageName: node
linkType: hard
+"ohash@npm:^2.0.10":
+ version: 2.0.11
+ resolution: "ohash@npm:2.0.11"
+ checksum: 10c0/d07c8d79cc26da082c1a7c8d5b56c399dd4ed3b2bd069fcae6bae78c99a9bcc3ad813b1e1f49ca2f335292846d689c6141a762cf078727d2302a33d414e69c79
+ languageName: node
+ linkType: hard
+
"on-finished@npm:2.4.1, on-finished@npm:^2.4.1":
version: 2.4.1
resolution: "on-finished@npm:2.4.1"
@@ -22513,13 +22494,6 @@ __metadata:
languageName: node
linkType: hard
-"os-shim@npm:^0.1.3":
- version: 0.1.3
- resolution: "os-shim@npm:0.1.3"
- checksum: 10c0/eaa09098c0f6a3115b2d0c027927cba9c2706e362b7767021b7ac83d159f18806ac1e95786b496d1912ce1aea8a6866e526d3f18f075c7c719eb08a0ffb9177f
- languageName: node
- linkType: hard
-
"ospec@npm:3.1.0":
version: 3.1.0
resolution: "ospec@npm:3.1.0"
@@ -22638,32 +22612,6 @@ __metadata:
languageName: node
linkType: hard
-"pac-proxy-agent@npm:^7.1.0":
- version: 7.2.0
- resolution: "pac-proxy-agent@npm:7.2.0"
- dependencies:
- "@tootallnate/quickjs-emscripten": "npm:^0.23.0"
- agent-base: "npm:^7.1.2"
- debug: "npm:^4.3.4"
- get-uri: "npm:^6.0.1"
- http-proxy-agent: "npm:^7.0.0"
- https-proxy-agent: "npm:^7.0.6"
- pac-resolver: "npm:^7.0.1"
- socks-proxy-agent: "npm:^8.0.5"
- checksum: 10c0/0265c17c9401c2ea735697931a6553a0c6d8b20c4d7d4e3b3a0506080ba69a8d5ad656e2a6be875411212e2b6ed7a4d9526dd3997e08581fdfb1cbcad454c296
- languageName: node
- linkType: hard
-
-"pac-resolver@npm:^7.0.1":
- version: 7.0.1
- resolution: "pac-resolver@npm:7.0.1"
- dependencies:
- degenerator: "npm:^5.0.0"
- netmask: "npm:^2.0.2"
- checksum: 10c0/5f3edd1dd10fded31e7d1f95776442c3ee51aa098c28b74ede4927d9677ebe7cebb2636750c24e945f5b84445e41ae39093d3a1014a994e5ceb9f0b1b88ebff5
- languageName: node
- linkType: hard
-
"package-hash@npm:^4.0.0":
version: 4.0.0
resolution: "package-hash@npm:4.0.0"
@@ -22909,15 +22857,6 @@ __metadata:
languageName: node
linkType: hard
-"pause-stream@npm:0.0.11":
- version: 0.0.11
- resolution: "pause-stream@npm:0.0.11"
- dependencies:
- through: "npm:~2.3"
- checksum: 10c0/86f12c64cdaaa8e45ebaca4e39a478e1442db8b4beabc280b545bfaf79c0e2f33c51efb554aace5c069cc441c7b924ba484837b345eaa4ba6fc940d62f826802
- languageName: node
- linkType: hard
-
"pbkdf2@npm:>=3.1.3":
version: 3.1.5
resolution: "pbkdf2@npm:3.1.5"
@@ -22943,13 +22882,6 @@ __metadata:
languageName: node
linkType: hard
-"pend@npm:~1.2.0":
- version: 1.2.0
- resolution: "pend@npm:1.2.0"
- checksum: 10c0/8a87e63f7a4afcfb0f9f77b39bb92374afc723418b9cb716ee4257689224171002e07768eeade4ecd0e86f1fa3d8f022994219fb45634f2dbd78c6803e452458
- languageName: node
- linkType: hard
-
"performance-now@npm:^2.1.0":
version: 2.1.0
resolution: "performance-now@npm:2.1.0"
@@ -23083,6 +23015,30 @@ __metadata:
languageName: node
linkType: hard
+"playwright-core@npm:1.59.1":
+ version: 1.59.1
+ resolution: "playwright-core@npm:1.59.1"
+ bin:
+ playwright-core: cli.js
+ checksum: 10c0/d41a74d9681ce3beb3d5239e9ed577710b4ad099a6ca2476219c6599d51e9cb4b80bd72ed82c528da6a5d929c18ae3b872cf02bb83f78fa1c2cb9199c501abee
+ languageName: node
+ linkType: hard
+
+"playwright@npm:1.59.1":
+ version: 1.59.1
+ resolution: "playwright@npm:1.59.1"
+ dependencies:
+ fsevents: "npm:2.3.2"
+ playwright-core: "npm:1.59.1"
+ dependenciesMeta:
+ fsevents:
+ optional: true
+ bin:
+ playwright: cli.js
+ checksum: 10c0/dfe38396e616e5c4f98825ce90037bb96e477c5a2bd9258a24854f8ce72a8a41427b19098863866f85aa0216e70287dd537c4438d761aca93995e31ae099c533
+ languageName: node
+ linkType: hard
+
"pluralize@npm:8.0.0":
version: 8.0.0
resolution: "pluralize@npm:8.0.0"
@@ -24145,6 +24101,13 @@ __metadata:
languageName: node
linkType: hard
+"printable-characters@npm:^1.0.42":
+ version: 1.0.42
+ resolution: "printable-characters@npm:1.0.42"
+ checksum: 10c0/7c94d94c6041a37c385af770c7402ad5a2e8a3429ca4d2505a9f19fde39bac9a8fd1edfbfa02f1eae5b4b0f3536b6b8ee6c84621f7c0fcb41476b2df6ee20e4b
+ languageName: node
+ linkType: hard
+
"private@npm:^0.1.8":
version: 0.1.8
resolution: "private@npm:0.1.8"
@@ -24189,13 +24152,6 @@ __metadata:
languageName: node
linkType: hard
-"progress@npm:^2.0.3":
- version: 2.0.3
- resolution: "progress@npm:2.0.3"
- checksum: 10c0/1697e07cb1068055dbe9fe858d242368ff5d2073639e652b75a7eb1f2a1a8d4afd404d719de23c7b48481a6aa0040686310e2dac2f53d776daa2176d3f96369c
- languageName: node
- linkType: hard
-
"promise-inflight@npm:^1.0.1":
version: 1.0.1
resolution: "promise-inflight@npm:1.0.1"
@@ -24269,40 +24225,6 @@ __metadata:
languageName: node
linkType: hard
-"proxy-agent@npm:^6.5.0":
- version: 6.5.0
- resolution: "proxy-agent@npm:6.5.0"
- dependencies:
- agent-base: "npm:^7.1.2"
- debug: "npm:^4.3.4"
- http-proxy-agent: "npm:^7.0.1"
- https-proxy-agent: "npm:^7.0.6"
- lru-cache: "npm:^7.14.1"
- pac-proxy-agent: "npm:^7.1.0"
- proxy-from-env: "npm:^1.1.0"
- socks-proxy-agent: "npm:^8.0.5"
- checksum: 10c0/7fd4e6f36bf17098a686d4aee3b8394abfc0b0537c2174ce96b0a4223198b9fafb16576c90108a3fcfc2af0168bd7747152bfa1f58e8fee91d3780e79aab7fd8
- languageName: node
- linkType: hard
-
-"proxy-from-env@npm:^1.1.0":
- version: 1.1.0
- resolution: "proxy-from-env@npm:1.1.0"
- checksum: 10c0/fe7dd8b1bdbbbea18d1459107729c3e4a2243ca870d26d34c2c1bcd3e4425b7bcc5112362df2d93cc7fb9746f6142b5e272fd1cc5c86ddf8580175186f6ad42b
- languageName: node
- linkType: hard
-
-"ps-tree@npm:=1.2.0":
- version: 1.2.0
- resolution: "ps-tree@npm:1.2.0"
- dependencies:
- event-stream: "npm:=3.3.4"
- bin:
- ps-tree: ./bin/ps-tree.js
- checksum: 10c0/9d1c159e0890db5aa05f84d125193c2190a6c4ecd457596fd25e7611f8f747292a846459dcc0244e27d45529d4cea6d1010c3a2a087fad02624d12fdb7d97c22
- languageName: node
- linkType: hard
-
"pseudomap@npm:^1.0.2":
version: 1.0.2
resolution: "pseudomap@npm:1.0.2"
@@ -24625,41 +24547,10 @@ __metadata:
languageName: node
linkType: hard
-"punycode@npm:^2.1.0, punycode@npm:^2.1.1":
- version: 2.3.1
- resolution: "punycode@npm:2.3.1"
- checksum: 10c0/14f76a8206bc3464f794fb2e3d3cc665ae416c01893ad7a02b23766eb07159144ee612ad67af5e84fa4479ccfe67678c4feb126b0485651b302babf66f04f9e9
- languageName: node
- linkType: hard
-
-"puppeteer-core@npm:24.29.1":
- version: 24.29.1
- resolution: "puppeteer-core@npm:24.29.1"
- dependencies:
- "@puppeteer/browsers": "npm:2.10.13"
- chromium-bidi: "npm:10.5.1"
- debug: "npm:^4.4.3"
- devtools-protocol: "npm:0.0.1521046"
- typed-query-selector: "npm:^2.12.0"
- webdriver-bidi-protocol: "npm:0.3.8"
- ws: "npm:^8.18.3"
- checksum: 10c0/dd767012045a497ba29f8367fa4d149a1cd75db00c01528b5082548d5920278f76b88314a820b470a22a103e9c87dc7b1f09852d81a4958fe97fdae5acc7288f
- languageName: node
- linkType: hard
-
-"puppeteer@npm:^24.29.1":
- version: 24.29.1
- resolution: "puppeteer@npm:24.29.1"
- dependencies:
- "@puppeteer/browsers": "npm:2.10.13"
- chromium-bidi: "npm:10.5.1"
- cosmiconfig: "npm:^9.0.0"
- devtools-protocol: "npm:0.0.1521046"
- puppeteer-core: "npm:24.29.1"
- typed-query-selector: "npm:^2.12.0"
- bin:
- puppeteer: lib/cjs/puppeteer/node/cli.js
- checksum: 10c0/2ca726f077929b190b50a96c8e968162194cd7b83af324005aa767f73862926223eb9cd60d00de81d71f435b74aad274103c644b1b773a39d804d47fefe687bb
+"punycode@npm:^2.1.0, punycode@npm:^2.1.1":
+ version: 2.3.1
+ resolution: "punycode@npm:2.3.1"
+ checksum: 10c0/14f76a8206bc3464f794fb2e3d3cc665ae416c01893ad7a02b23766eb07159144ee612ad67af5e84fa4479ccfe67678c4feb126b0485651b302babf66f04f9e9
languageName: node
linkType: hard
@@ -24670,20 +24561,13 @@ __metadata:
languageName: node
linkType: hard
-"q@npm:^1.1.2, q@npm:~1.5.0":
+"q@npm:^1.1.2":
version: 1.5.1
resolution: "q@npm:1.5.1"
checksum: 10c0/7855fbdba126cb7e92ef3a16b47ba998c0786ec7fface236e3eb0135b65df36429d91a86b1fff3ab0927b4ac4ee88a2c44527c7c3b8e2a37efbec9fe34803df4
languageName: node
linkType: hard
-"qjobs@npm:^1.2.0":
- version: 1.2.0
- resolution: "qjobs@npm:1.2.0"
- checksum: 10c0/772207772b856a3b1ec673b11a6cda074f1b82821644f2d042504b438ea3ea1fe918555547491e717e8694ec105379fe5139fc5ddd7937b21f7712bb648ed01d
- languageName: node
- linkType: hard
-
"qs@npm:6.11.0":
version: 6.11.0
resolution: "qs@npm:6.11.0"
@@ -24741,13 +24625,6 @@ __metadata:
languageName: node
linkType: hard
-"queue-tick@npm:^1.0.1":
- version: 1.0.1
- resolution: "queue-tick@npm:1.0.1"
- checksum: 10c0/0db998e2c9b15215317dbcf801e9b23e6bcde4044e115155dae34f8e7454b9a783f737c9a725528d677b7a66c775eb7a955cf144fe0b87f62b575ce5bfd515a9
- languageName: node
- linkType: hard
-
"raf@npm:^3.4.1":
version: 3.4.1
resolution: "raf@npm:3.4.1"
@@ -25667,7 +25544,7 @@ __metadata:
languageName: node
linkType: hard
-"resolve@npm:^1.1.4, resolve@npm:^1.1.6, resolve@npm:^1.1.7, resolve@npm:^1.10.0, resolve@npm:^1.14.2, resolve@npm:^1.15.1, resolve@npm:^1.17.0, resolve@npm:^1.19.0, resolve@npm:^1.20.0, resolve@npm:^1.22.1, resolve@npm:^1.22.2, resolve@npm:^1.22.4, resolve@npm:^1.3.2, resolve@npm:^1.3.3, resolve@npm:^1.4.0":
+"resolve@npm:^1.1.4, resolve@npm:^1.1.6, resolve@npm:^1.1.7, resolve@npm:^1.10.0, resolve@npm:^1.14.2, resolve@npm:^1.15.1, resolve@npm:^1.17.0, resolve@npm:^1.19.0, resolve@npm:^1.20.0, resolve@npm:^1.22.1, resolve@npm:^1.22.2, resolve@npm:^1.22.4, resolve@npm:^1.3.2, resolve@npm:^1.4.0":
version: 1.22.8
resolution: "resolve@npm:1.22.8"
dependencies:
@@ -25706,8 +25583,7 @@ __metadata:
languageName: node
linkType: hard
-? "resolve@patch:resolve@npm%3A^1.1.4#optional!builtin, resolve@patch:resolve@npm%3A^1.1.6#optional!builtin, resolve@patch:resolve@npm%3A^1.1.7#optional!builtin, resolve@patch:resolve@npm%3A^1.10.0#optional!builtin, resolve@patch:resolve@npm%3A^1.14.2#optional!builtin, resolve@patch:resolve@npm%3A^1.15.1#optional!builtin, resolve@patch:resolve@npm%3A^1.17.0#optional!builtin, resolve@patch:resolve@npm%3A^1.19.0#optional!builtin, resolve@patch:resolve@npm%3A^1.20.0#optional!builtin, resolve@patch:resolve@npm%3A^1.22.1#optional!builtin, resolve@patch:resolve@npm%3A^1.22.2#optional!builtin, resolve@patch:resolve@npm%3A^1.22.4#optional!builtin, resolve@patch:resolve@npm%3A^1.3.2#optional!builtin, resolve@patch:resolve@npm%3A^1.3.3#optional!builtin, resolve@patch:resolve@npm%3A^1.4.0#optional!builtin"
-:
+"resolve@patch:resolve@npm%3A^1.1.4#optional!builtin, resolve@patch:resolve@npm%3A^1.1.6#optional!builtin, resolve@patch:resolve@npm%3A^1.1.7#optional!builtin, resolve@patch:resolve@npm%3A^1.10.0#optional!builtin, resolve@patch:resolve@npm%3A^1.14.2#optional!builtin, resolve@patch:resolve@npm%3A^1.15.1#optional!builtin, resolve@patch:resolve@npm%3A^1.17.0#optional!builtin, resolve@patch:resolve@npm%3A^1.19.0#optional!builtin, resolve@patch:resolve@npm%3A^1.20.0#optional!builtin, resolve@patch:resolve@npm%3A^1.22.1#optional!builtin, resolve@patch:resolve@npm%3A^1.22.2#optional!builtin, resolve@patch:resolve@npm%3A^1.22.4#optional!builtin, resolve@patch:resolve@npm%3A^1.3.2#optional!builtin, resolve@patch:resolve@npm%3A^1.4.0#optional!builtin":
version: 1.22.8
resolution: "resolve@patch:resolve@npm%3A1.22.8#optional!builtin::version=1.22.8&hash=c3c19d"
dependencies:
@@ -25777,13 +25653,6 @@ __metadata:
languageName: node
linkType: hard
-"rfdc@npm:^1.3.0":
- version: 1.4.1
- resolution: "rfdc@npm:1.4.1"
- checksum: 10c0/4614e4292356cafade0b6031527eea9bc90f2372a22c012313be1dcc69a3b90c7338158b414539be863fa95bfcb2ddcd0587be696841af4e6679d85e62c060c7
- languageName: node
- linkType: hard
-
"right-align@npm:^0.1.1":
version: 0.1.3
resolution: "right-align@npm:0.1.3"
@@ -25804,17 +25673,6 @@ __metadata:
languageName: node
linkType: hard
-"rimraf@npm:~2.5.2":
- version: 2.5.4
- resolution: "rimraf@npm:2.5.4"
- dependencies:
- glob: "npm:^7.0.5"
- bin:
- rimraf: ./bin.js
- checksum: 10c0/02556efee08012469e358ed54f6e59e2a3589f07d4b15c6156ae57d391cb6983dd35d02a2a1b9c4c9d129d90fb00db980a5c44ea248ecff2737c246ed02686b1
- languageName: node
- linkType: hard
-
"ripemd160@npm:^2.0.0, ripemd160@npm:^2.0.1":
version: 2.0.2
resolution: "ripemd160@npm:2.0.2"
@@ -25876,6 +25734,17 @@ __metadata:
languageName: node
linkType: hard
+"rollup-plugin-inject@npm:^3.0.0":
+ version: 3.0.2
+ resolution: "rollup-plugin-inject@npm:3.0.2"
+ dependencies:
+ estree-walker: "npm:^0.6.1"
+ magic-string: "npm:^0.25.3"
+ rollup-pluginutils: "npm:^2.8.1"
+ checksum: 10c0/35b9d955039b56b43750a9e458bb51b7956b048b6d3ca57b1f03462aa5a0cb176d1b677d95e909b64eee4e9adf73c02f569ad8c0ab5aafdec818ff51700c114c
+ languageName: node
+ linkType: hard
+
"rollup-plugin-jsdoc@npm:^0.1.2":
version: 0.1.2
resolution: "rollup-plugin-jsdoc@npm:0.1.2"
@@ -25895,6 +25764,15 @@ __metadata:
languageName: node
linkType: hard
+"rollup-plugin-node-polyfills@npm:^0.2.1":
+ version: 0.2.1
+ resolution: "rollup-plugin-node-polyfills@npm:0.2.1"
+ dependencies:
+ rollup-plugin-inject: "npm:^3.0.0"
+ checksum: 10c0/30f9e09cbbf979b1212e0c455d74c3a061994fc19ddf160da4634b11377222cea5903a5ba05db66be849f550cde9ffc80ecbfcfb48544045d08bfc408501417d
+ languageName: node
+ linkType: hard
+
"rollup-plugin-terser@npm:^7.0.0":
version: 7.0.2
resolution: "rollup-plugin-terser@npm:7.0.2"
@@ -25925,6 +25803,15 @@ __metadata:
languageName: node
linkType: hard
+"rollup-pluginutils@npm:^2.8.1":
+ version: 2.8.2
+ resolution: "rollup-pluginutils@npm:2.8.2"
+ dependencies:
+ estree-walker: "npm:^0.6.1"
+ checksum: 10c0/20947bec5a5dd68b5c5c8423911e6e7c0ad834c451f1a929b1f4e2bc08836ad3f1a722ef2bfcbeca921870a0a283f13f064a317dc7a6768496e98c9a641ba290
+ languageName: node
+ linkType: hard
+
"rollup@npm:>=2.79.2":
version: 4.53.2
resolution: "rollup@npm:4.53.2"
@@ -26576,6 +26463,75 @@ __metadata:
languageName: node
linkType: hard
+"sharp@npm:^0.33.5":
+ version: 0.33.5
+ resolution: "sharp@npm:0.33.5"
+ dependencies:
+ "@img/sharp-darwin-arm64": "npm:0.33.5"
+ "@img/sharp-darwin-x64": "npm:0.33.5"
+ "@img/sharp-libvips-darwin-arm64": "npm:1.0.4"
+ "@img/sharp-libvips-darwin-x64": "npm:1.0.4"
+ "@img/sharp-libvips-linux-arm": "npm:1.0.5"
+ "@img/sharp-libvips-linux-arm64": "npm:1.0.4"
+ "@img/sharp-libvips-linux-s390x": "npm:1.0.4"
+ "@img/sharp-libvips-linux-x64": "npm:1.0.4"
+ "@img/sharp-libvips-linuxmusl-arm64": "npm:1.0.4"
+ "@img/sharp-libvips-linuxmusl-x64": "npm:1.0.4"
+ "@img/sharp-linux-arm": "npm:0.33.5"
+ "@img/sharp-linux-arm64": "npm:0.33.5"
+ "@img/sharp-linux-s390x": "npm:0.33.5"
+ "@img/sharp-linux-x64": "npm:0.33.5"
+ "@img/sharp-linuxmusl-arm64": "npm:0.33.5"
+ "@img/sharp-linuxmusl-x64": "npm:0.33.5"
+ "@img/sharp-wasm32": "npm:0.33.5"
+ "@img/sharp-win32-ia32": "npm:0.33.5"
+ "@img/sharp-win32-x64": "npm:0.33.5"
+ color: "npm:^4.2.3"
+ detect-libc: "npm:^2.0.3"
+ semver: "npm:^7.6.3"
+ dependenciesMeta:
+ "@img/sharp-darwin-arm64":
+ optional: true
+ "@img/sharp-darwin-x64":
+ optional: true
+ "@img/sharp-libvips-darwin-arm64":
+ optional: true
+ "@img/sharp-libvips-darwin-x64":
+ optional: true
+ "@img/sharp-libvips-linux-arm":
+ optional: true
+ "@img/sharp-libvips-linux-arm64":
+ optional: true
+ "@img/sharp-libvips-linux-s390x":
+ optional: true
+ "@img/sharp-libvips-linux-x64":
+ optional: true
+ "@img/sharp-libvips-linuxmusl-arm64":
+ optional: true
+ "@img/sharp-libvips-linuxmusl-x64":
+ optional: true
+ "@img/sharp-linux-arm":
+ optional: true
+ "@img/sharp-linux-arm64":
+ optional: true
+ "@img/sharp-linux-s390x":
+ optional: true
+ "@img/sharp-linux-x64":
+ optional: true
+ "@img/sharp-linuxmusl-arm64":
+ optional: true
+ "@img/sharp-linuxmusl-x64":
+ optional: true
+ "@img/sharp-wasm32":
+ optional: true
+ "@img/sharp-win32-ia32":
+ optional: true
+ "@img/sharp-win32-x64":
+ optional: true
+ checksum: 10c0/6b81421ddfe6ee524d8d77e325c5e147fef22884e1c7b1656dfd89a88d7025894115da02d5f984261bf2e6daa16f98cadd1721c4ba408b4212b1d2a60f233484
+ languageName: node
+ linkType: hard
+
"sharp@npm:^0.34.4":
version: 0.34.5
resolution: "sharp@npm:0.34.5"
@@ -26773,6 +26729,15 @@ __metadata:
languageName: node
linkType: hard
+"simple-swizzle@npm:^0.2.2":
+ version: 0.2.4
+ resolution: "simple-swizzle@npm:0.2.4"
+ dependencies:
+ is-arrayish: "npm:^0.3.1"
+ checksum: 10c0/846c3fdd1325318d5c71295cfbb99bfc9edc4c8dffdda5e6e9efe30482bbcd32cf360fc2806f46ac43ff7d09bcfaff20337bb79f826f0e6a8e366efd3cdd7868
+ languageName: node
+ linkType: hard
+
"sisteransi@npm:^1.0.5":
version: 1.0.5
resolution: "sisteransi@npm:1.0.5"
@@ -26815,41 +26780,6 @@ __metadata:
languageName: node
linkType: hard
-"socket.io-adapter@npm:~2.5.2":
- version: 2.5.5
- resolution: "socket.io-adapter@npm:2.5.5"
- dependencies:
- debug: "npm:~4.3.4"
- ws: "npm:~8.17.1"
- checksum: 10c0/04a5a2a9c4399d1b6597c2afc4492ab1e73430cc124ab02b09e948eabf341180b3866e2b61b5084cb899beb68a4db7c328c29bda5efb9207671b5cb0bc6de44e
- languageName: node
- linkType: hard
-
-"socket.io-parser@npm:~4.2.4":
- version: 4.2.4
- resolution: "socket.io-parser@npm:4.2.4"
- dependencies:
- "@socket.io/component-emitter": "npm:~3.1.0"
- debug: "npm:~4.3.1"
- checksum: 10c0/9383b30358fde4a801ea4ec5e6860915c0389a091321f1c1f41506618b5cf7cd685d0a31c587467a0c4ee99ef98c2b99fb87911f9dfb329716c43b587f29ca48
- languageName: node
- linkType: hard
-
-"socket.io@npm:^4.7.2":
- version: 4.7.5
- resolution: "socket.io@npm:4.7.5"
- dependencies:
- accepts: "npm:~1.3.4"
- base64id: "npm:~2.0.0"
- cors: "npm:~2.8.5"
- debug: "npm:~4.3.2"
- engine.io: "npm:~6.5.2"
- socket.io-adapter: "npm:~2.5.2"
- socket.io-parser: "npm:~4.2.4"
- checksum: 10c0/221a2cd25f6077d6672cb8b19921336e1acf06788d4bade74953dc96dbfd8b788a5f721b051341a34ee81ef8e1b2028d39ad5257516776400a3f8f3f01255c5e
- languageName: node
- linkType: hard
-
"sockjs@npm:^0.3.24":
version: 0.3.24
resolution: "sockjs@npm:0.3.24"
@@ -26872,17 +26802,6 @@ __metadata:
languageName: node
linkType: hard
-"socks-proxy-agent@npm:^8.0.5":
- version: 8.0.5
- resolution: "socks-proxy-agent@npm:8.0.5"
- dependencies:
- agent-base: "npm:^7.1.2"
- debug: "npm:^4.3.4"
- socks: "npm:^2.8.3"
- checksum: 10c0/5d2c6cecba6821389aabf18728325730504bf9bb1d9e342e7987a5d13badd7a98838cc9a55b8ed3cb866ad37cc23e1086f09c4d72d93105ce9dfe76330e9d2a6
- languageName: node
- linkType: hard
-
"socks@npm:^2.7.1":
version: 2.8.3
resolution: "socks@npm:2.8.3"
@@ -26893,16 +26812,6 @@ __metadata:
languageName: node
linkType: hard
-"socks@npm:^2.8.3":
- version: 2.8.7
- resolution: "socks@npm:2.8.7"
- dependencies:
- ip-address: "npm:^10.0.1"
- smart-buffer: "npm:^4.2.0"
- checksum: 10c0/2805a43a1c4bcf9ebf6e018268d87b32b32b06fbbc1f9282573583acc155860dc361500f89c73bfbb157caa1b4ac78059eac0ef15d1811eb0ca75e0bdadbc9d2
- languageName: node
- linkType: hard
-
"sort-keys@npm:^2.0.0":
version: 2.0.0
resolution: "sort-keys@npm:2.0.0"
@@ -27085,15 +26994,6 @@ __metadata:
languageName: node
linkType: hard
-"split@npm:0.3":
- version: 0.3.3
- resolution: "split@npm:0.3.3"
- dependencies:
- through: "npm:2"
- checksum: 10c0/88c09b1b4de84953bf5d6c153123a1fbb20addfea9381f70d27b4eb6b2bfbadf25d313f8f5d3fd727d5679b97bfe54da04766b91010f131635bf49e51d5db3fc
- languageName: node
- linkType: hard
-
"sprintf-js@npm:^1.1.3":
version: 1.1.3
resolution: "sprintf-js@npm:1.1.3"
@@ -27147,6 +27047,16 @@ __metadata:
languageName: node
linkType: hard
+"stacktracey@npm:^2.1.8":
+ version: 2.2.0
+ resolution: "stacktracey@npm:2.2.0"
+ dependencies:
+ as-table: "npm:^1.0.36"
+ get-source: "npm:^2.0.12"
+ checksum: 10c0/fc5d58a85e76a1a13ce1a2ecac4029c5e889a7c437259023f5514dfc3b107603de944c46faa6c930e4991fe13d91deb385e9537ef7f6deb1bd2d8188f69eec30
+ languageName: node
+ linkType: hard
+
"static-eval@npm:2.0.2":
version: 2.0.2
resolution: "static-eval@npm:2.0.2"
@@ -27163,7 +27073,7 @@ __metadata:
languageName: node
linkType: hard
-"statuses@npm:>= 1.4.0 < 2, statuses@npm:~1.5.0":
+"statuses@npm:>= 1.4.0 < 2":
version: 1.5.0
resolution: "statuses@npm:1.5.0"
checksum: 10c0/e433900956357b3efd79b1c547da4d291799ac836960c016d10a98f6a810b1b5c0dcc13b5a7aa609a58239b5190e1ea176ad9221c2157d2fd1c747393e6b2940
@@ -27187,6 +27097,13 @@ __metadata:
languageName: node
linkType: hard
+"stoppable@npm:1.1.0":
+ version: 1.1.0
+ resolution: "stoppable@npm:1.1.0"
+ checksum: 10c0/ba91b65e6442bf6f01ce837a727ece597a977ed92a05cb9aea6bf446c5e0dcbccc28f31b793afa8aedd8f34baaf3335398d35f903938d5493f7fbe386a1e090e
+ languageName: node
+ linkType: hard
+
"stream-browserify@npm:^3.0.0":
version: 3.0.0
resolution: "stream-browserify@npm:3.0.0"
@@ -27207,15 +27124,6 @@ __metadata:
languageName: node
linkType: hard
-"stream-combiner@npm:~0.0.4":
- version: 0.0.4
- resolution: "stream-combiner@npm:0.0.4"
- dependencies:
- duplexer: "npm:~0.1.1"
- checksum: 10c0/8075a94c0eb0f20450a8236cb99d4ce3ea6e6a4b36d8baa7440b1a08cde6ffd227debadffaecd80993bd334282875d0e927ab5b88484625e01970dd251004ff5
- languageName: node
- linkType: hard
-
"stream-http@npm:^3.0.0":
version: 3.2.0
resolution: "stream-http@npm:3.2.0"
@@ -27252,17 +27160,6 @@ __metadata:
languageName: node
linkType: hard
-"streamroller@npm:^3.1.5":
- version: 3.1.5
- resolution: "streamroller@npm:3.1.5"
- dependencies:
- date-format: "npm:^4.0.14"
- debug: "npm:^4.3.4"
- fs-extra: "npm:^8.1.0"
- checksum: 10c0/0bdeec34ad37487d959ba908f17067c938f544db88b5bb1669497a67a6b676413229ce5a6145c2812d06959ebeb8842e751076647d4b323ca06be612963b9099
- languageName: node
- linkType: hard
-
"streamsearch@npm:^1.1.0":
version: 1.1.0
resolution: "streamsearch@npm:1.1.0"
@@ -27270,32 +27167,6 @@ __metadata:
languageName: node
linkType: hard
-"streamx@npm:^2.15.0":
- version: 2.18.0
- resolution: "streamx@npm:2.18.0"
- dependencies:
- bare-events: "npm:^2.2.0"
- fast-fifo: "npm:^1.3.2"
- queue-tick: "npm:^1.0.1"
- text-decoder: "npm:^1.1.0"
- dependenciesMeta:
- bare-events:
- optional: true
- checksum: 10c0/ef50f419252a73dd35abcde72329eafbf5ad9cd2e27f0cc3abebeff6e0dbea124ac6d3e16acbdf081cce41b4125393ac22f9848fcfa19e640830734883e622ba
- languageName: node
- linkType: hard
-
-"streamx@npm:^2.21.0":
- version: 2.23.0
- resolution: "streamx@npm:2.23.0"
- dependencies:
- events-universal: "npm:^1.0.0"
- fast-fifo: "npm:^1.3.2"
- text-decoder: "npm:^1.1.0"
- checksum: 10c0/15708ce37818d588632fe1104e8febde573e33e8c0868bf583fce0703f3faf8d2a063c278e30df2270206811b69997f64eb78792099933a1fe757e786fbcbd44
- languageName: node
- linkType: hard
-
"string-hash@npm:^1.1.3":
version: 1.1.3
resolution: "string-hash@npm:1.1.3"
@@ -27523,15 +27394,6 @@ __metadata:
languageName: node
linkType: hard
-"strip-ansi@npm:^4.0.0":
- version: 4.0.0
- resolution: "strip-ansi@npm:4.0.0"
- dependencies:
- ansi-regex: "npm:^3.0.0"
- checksum: 10c0/d75d9681e0637ea316ddbd7d4d3be010b1895a17e885155e0ed6a39755ae0fd7ef46e14b22162e66a62db122d3a98ab7917794e255532ab461bb0a04feb03e7d
- languageName: node
- linkType: hard
-
"strip-ansi@npm:^7.0.1":
version: 7.1.0
resolution: "strip-ansi@npm:7.1.0"
@@ -27964,23 +27826,6 @@ __metadata:
languageName: node
linkType: hard
-"tar-fs@npm:^3.1.1":
- version: 3.1.1
- resolution: "tar-fs@npm:3.1.1"
- dependencies:
- bare-fs: "npm:^4.0.1"
- bare-path: "npm:^3.0.0"
- pump: "npm:^3.0.0"
- tar-stream: "npm:^3.1.5"
- dependenciesMeta:
- bare-fs:
- optional: true
- bare-path:
- optional: true
- checksum: 10c0/0c677d711c4aa41f94e1a712aa647022ba1910ff84430739e5d9e95a615e3ea1b7112dc93164fc8ce30dc715befcf9cfdc64da27d4e7958d73c59bda06aa0d8e
- languageName: node
- linkType: hard
-
"tar-stream@npm:^2.1.4":
version: 2.2.0
resolution: "tar-stream@npm:2.2.0"
@@ -27994,17 +27839,6 @@ __metadata:
languageName: node
linkType: hard
-"tar-stream@npm:^3.1.5":
- version: 3.1.7
- resolution: "tar-stream@npm:3.1.7"
- dependencies:
- b4a: "npm:^1.6.4"
- fast-fifo: "npm:^1.2.0"
- streamx: "npm:^2.15.0"
- checksum: 10c0/a09199d21f8714bd729993ac49b6c8efcb808b544b89f23378ad6ffff6d1cb540878614ba9d4cfec11a64ef39e1a6f009a5398371491eb1fda606ffc7f70f718
- languageName: node
- linkType: hard
-
"tar@npm:^6.1.11, tar@npm:^6.1.2":
version: 6.2.1
resolution: "tar@npm:6.2.1"
@@ -28026,15 +27860,6 @@ __metadata:
languageName: node
linkType: hard
-"temp-fs@npm:^0.9.9":
- version: 0.9.9
- resolution: "temp-fs@npm:0.9.9"
- dependencies:
- rimraf: "npm:~2.5.2"
- checksum: 10c0/6b5584a794a7a83c5618b025f4b7f7a4d01c1e6a696289fa7bba128193f781cffc6b044962775bea2a43418bf2731f994cb8444e1196b23dafe4e7bae04d9a7f
- languageName: node
- linkType: hard
-
"tempy@npm:^0.6.0":
version: 0.6.0
resolution: "tempy@npm:0.6.0"
@@ -28140,15 +27965,6 @@ __metadata:
languageName: node
linkType: hard
-"text-decoder@npm:^1.1.0":
- version: 1.1.0
- resolution: "text-decoder@npm:1.1.0"
- dependencies:
- b4a: "npm:^1.6.4"
- checksum: 10c0/623a6cfb5ee86c250fea31f369a0d40e4ef5c2c32ce8db43492648b51193858213e61bf47a6078f285053715dcc6342806ce6ea9a49d7847ffca282ca88ad7e8
- languageName: node
- linkType: hard
-
"text-table@npm:^0.2.0":
version: 0.2.0
resolution: "text-table@npm:0.2.0"
@@ -28200,7 +28016,7 @@ __metadata:
languageName: node
linkType: hard
-"through@npm:2, through@npm:>=2.2.7 <3, through@npm:~2.3, through@npm:~2.3.1":
+"through@npm:>=2.2.7 <3":
version: 2.3.8
resolution: "through@npm:2.3.8"
checksum: 10c0/4b09f3774099de0d4df26d95c5821a62faee32c7e96fb1f4ebd54a2d7c11c57fe88b0a0d49cf375de5fee5ae6bf4eb56dbbf29d07366864e2ee805349970d3cc
@@ -28233,13 +28049,6 @@ __metadata:
languageName: node
linkType: hard
-"tmp@npm:^0.2.1":
- version: 0.2.3
- resolution: "tmp@npm:0.2.3"
- checksum: 10c0/3e809d9c2f46817475b452725c2aaa5d11985cf18d32a7a970ff25b568438e2c076c2e8609224feef3b7923fa9749b74428e3e634f6b8e520c534eef2fd24125
- languageName: node
- linkType: hard
-
"tmpl@npm:1.0.5":
version: 1.0.5
resolution: "tmpl@npm:1.0.5"
@@ -28860,13 +28669,6 @@ __metadata:
languageName: node
linkType: hard
-"typed-query-selector@npm:^2.12.0":
- version: 2.12.0
- resolution: "typed-query-selector@npm:2.12.0"
- checksum: 10c0/069509887ecfff824a470f5f93d300cc9223cb059a36c47ac685f2812c4c9470340e07615893765e4264cef1678507532fa78f642fd52f276b589f7f5d791f79
- languageName: node
- linkType: hard
-
"typedarray-to-buffer@npm:^3.1.5":
version: 3.1.5
resolution: "typedarray-to-buffer@npm:3.1.5"
@@ -28998,13 +28800,6 @@ __metadata:
languageName: node
linkType: hard
-"ua-parser-js@npm:^0.7.30":
- version: 0.7.38
- resolution: "ua-parser-js@npm:0.7.38"
- checksum: 10c0/da963eae1618f0c60d0812851a4d478fb8bb127ee6e5c566b8dac27eeb25757d818d9ade2c312d73018f2bb3c3e629d26c066fcda3cb9d55a31289c9566198df
- languageName: node
- linkType: hard
-
"uc.micro@npm:^1.0.1, uc.micro@npm:^1.0.5":
version: 1.0.6
resolution: "uc.micro@npm:1.0.6"
@@ -29143,6 +28938,15 @@ __metadata:
languageName: node
linkType: hard
+"undici@npm:^5.28.5":
+ version: 5.29.0
+ resolution: "undici@npm:5.29.0"
+ dependencies:
+ "@fastify/busboy": "npm:^2.0.0"
+ checksum: 10c0/e4e4d631ca54ee0ad82d2e90e7798fa00a106e27e6c880687e445cc2f13b4bc87c5eba2a88c266c3eecffb18f26e227b778412da74a23acc374fca7caccec49b
+ languageName: node
+ linkType: hard
+
"undici@npm:^6.21.2":
version: 6.22.0
resolution: "undici@npm:6.22.0"
@@ -29150,6 +28954,19 @@ __metadata:
languageName: node
linkType: hard
+"unenv@npm:2.0.0-rc.14":
+ version: 2.0.0-rc.14
+ resolution: "unenv@npm:2.0.0-rc.14"
+ dependencies:
+ defu: "npm:^6.1.4"
+ exsolve: "npm:^1.0.1"
+ ohash: "npm:^2.0.10"
+ pathe: "npm:^2.0.3"
+ ufo: "npm:^1.5.4"
+ checksum: 10c0/85372028cafb1726dfbe4dbb34953580827936f527022f6b03eaaf1b947d9354cf39ed505203edb11e77791d01778cb2287b2db03f516ed4503de9182a821f94
+ languageName: node
+ linkType: hard
+
"unicode-canonical-property-names-ecmascript@npm:^2.0.0":
version: 2.0.0
resolution: "unicode-canonical-property-names-ecmascript@npm:2.0.0"
@@ -29803,7 +29620,7 @@ __metadata:
languageName: node
linkType: hard
-"void-elements@npm:^2.0.0, void-elements@npm:^2.0.1":
+"void-elements@npm:^2.0.1":
version: 2.0.1
resolution: "void-elements@npm:2.0.1"
checksum: 10c0/23b4f35bbeabcaa5c87a9f638ae80862a9313dccbaa8973b0eada81dbe97488ae11baf4d8aa2846bc397d31456afdfd8d791bb44c542f83735e6d04af6996f4d
@@ -29965,13 +29782,6 @@ __metadata:
languageName: node
linkType: hard
-"webdriver-bidi-protocol@npm:0.3.8":
- version: 0.3.8
- resolution: "webdriver-bidi-protocol@npm:0.3.8"
- checksum: 10c0/288134377635b9cd24cc73f9b715d169eea39eeb8d50afbafd90ca313379fa9b2964e666c90256d2b34a6089e3531cc1e17a0d289d3b8f9b224a2bba73fb03e3
- languageName: node
- linkType: hard
-
"webidl-conversions@npm:^4.0.2":
version: 4.0.2
resolution: "webidl-conversions@npm:4.0.2"
@@ -30067,15 +29877,6 @@ __metadata:
languageName: node
linkType: hard
-"webpack-merge@npm:^4.1.5":
- version: 4.2.2
- resolution: "webpack-merge@npm:4.2.2"
- dependencies:
- lodash: "npm:^4.17.15"
- checksum: 10c0/283cb4ffe4d4ae6de23d595154868780126835ded241748da0b070c6cca6974c229493ac0b6b7160c2c92950c950c8e5edf036a192da78e32e22a9c81593ad16
- languageName: node
- linkType: hard
-
"webpack-node-externals@npm:3.0.0":
version: 3.0.0
resolution: "webpack-node-externals@npm:3.0.0"
@@ -30407,7 +30208,7 @@ __metadata:
languageName: node
linkType: hard
-"which@npm:^1.2.1, which@npm:^1.3.1":
+"which@npm:^1.3.1":
version: 1.3.1
resolution: "which@npm:1.3.1"
dependencies:
@@ -30715,6 +30516,32 @@ __metadata:
languageName: node
linkType: hard
+"workerd@npm:1.20250718.0":
+ version: 1.20250718.0
+ resolution: "workerd@npm:1.20250718.0"
+ dependencies:
+ "@cloudflare/workerd-darwin-64": "npm:1.20250718.0"
+ "@cloudflare/workerd-darwin-arm64": "npm:1.20250718.0"
+ "@cloudflare/workerd-linux-64": "npm:1.20250718.0"
+ "@cloudflare/workerd-linux-arm64": "npm:1.20250718.0"
+ "@cloudflare/workerd-windows-64": "npm:1.20250718.0"
+ dependenciesMeta:
+ "@cloudflare/workerd-darwin-64":
+ optional: true
+ "@cloudflare/workerd-darwin-arm64":
+ optional: true
+ "@cloudflare/workerd-linux-64":
+ optional: true
+ "@cloudflare/workerd-linux-arm64":
+ optional: true
+ "@cloudflare/workerd-windows-64":
+ optional: true
+ bin:
+ workerd: bin/workerd
+ checksum: 10c0/94ac61da99310331ec21c5fb10072791af78a8080059153793ff81796a7c372ce2b40274614590982ceb2f4b1b395997f1d93b635c3c282583624a36eff8970d
+ languageName: node
+ linkType: hard
+
"workerpool@npm:^9.2.0":
version: 9.3.4
resolution: "workerpool@npm:9.3.4"
@@ -30722,6 +30549,39 @@ __metadata:
languageName: node
linkType: hard
+"wrangler@npm:^3.99.0":
+ version: 3.114.17
+ resolution: "wrangler@npm:3.114.17"
+ dependencies:
+ "@cloudflare/kv-asset-handler": "npm:0.3.4"
+ "@cloudflare/unenv-preset": "npm:2.0.2"
+ "@esbuild-plugins/node-globals-polyfill": "npm:0.2.3"
+ "@esbuild-plugins/node-modules-polyfill": "npm:0.2.2"
+ blake3-wasm: "npm:2.1.5"
+ esbuild: "npm:0.17.19"
+ fsevents: "npm:~2.3.2"
+ miniflare: "npm:3.20250718.3"
+ path-to-regexp: "npm:6.3.0"
+ sharp: "npm:^0.33.5"
+ unenv: "npm:2.0.0-rc.14"
+ workerd: "npm:1.20250718.0"
+ peerDependencies:
+ "@cloudflare/workers-types": ^4.20250408.0
+ dependenciesMeta:
+ fsevents:
+ optional: true
+ sharp:
+ optional: true
+ peerDependenciesMeta:
+ "@cloudflare/workers-types":
+ optional: true
+ bin:
+ wrangler: bin/wrangler.js
+ wrangler2: bin/wrangler.js
+ checksum: 10c0/83cedac5b95b1f78ee6213fe585be5a7f7cfa2885ac482b8e75ca3e13d3ba5b0746fae5aaf82c2652c704755fe74889b69e0e2b75b6db8bb095ff7cb42b9a167
+ languageName: node
+ linkType: hard
+
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0, wrap-ansi@npm:^7.0.0":
version: 7.0.0
resolution: "wrap-ansi@npm:7.0.0"
@@ -30820,39 +30680,39 @@ __metadata:
languageName: node
linkType: hard
-"ws@npm:^7.4.6, ws@npm:^7.5.10":
- version: 7.5.10
- resolution: "ws@npm:7.5.10"
+"ws@npm:8.18.0":
+ version: 8.18.0
+ resolution: "ws@npm:8.18.0"
peerDependencies:
bufferutil: ^4.0.1
- utf-8-validate: ^5.0.2
+ utf-8-validate: ">=5.0.2"
peerDependenciesMeta:
bufferutil:
optional: true
utf-8-validate:
optional: true
- checksum: 10c0/bd7d5f4aaf04fae7960c23dcb6c6375d525e00f795dd20b9385902bd008c40a94d3db3ce97d878acc7573df852056ca546328b27b39f47609f80fb22a0a9b61d
+ checksum: 10c0/25eb33aff17edcb90721ed6b0eb250976328533ad3cd1a28a274bd263682e7296a6591ff1436d6cbc50fa67463158b062f9d1122013b361cec99a05f84680e06
languageName: node
linkType: hard
-"ws@npm:^8.13.0, ws@npm:~8.17.1":
- version: 8.17.1
- resolution: "ws@npm:8.17.1"
+"ws@npm:^7.4.6, ws@npm:^7.5.10":
+ version: 7.5.10
+ resolution: "ws@npm:7.5.10"
peerDependencies:
bufferutil: ^4.0.1
- utf-8-validate: ">=5.0.2"
+ utf-8-validate: ^5.0.2
peerDependenciesMeta:
bufferutil:
optional: true
utf-8-validate:
optional: true
- checksum: 10c0/f4a49064afae4500be772abdc2211c8518f39e1c959640457dcee15d4488628620625c783902a52af2dd02f68558da2868fd06e6fd0e67ebcd09e6881b1b5bfe
+ checksum: 10c0/bd7d5f4aaf04fae7960c23dcb6c6375d525e00f795dd20b9385902bd008c40a94d3db3ce97d878acc7573df852056ca546328b27b39f47609f80fb22a0a9b61d
languageName: node
linkType: hard
-"ws@npm:^8.18.3":
- version: 8.18.3
- resolution: "ws@npm:8.18.3"
+"ws@npm:^8.13.0":
+ version: 8.17.1
+ resolution: "ws@npm:8.17.1"
peerDependencies:
bufferutil: ^4.0.1
utf-8-validate: ">=5.0.2"
@@ -30861,7 +30721,7 @@ __metadata:
optional: true
utf-8-validate:
optional: true
- checksum: 10c0/eac918213de265ef7cb3d4ca348b891a51a520d839aa51cdb8ca93d4fa7ff9f6ccb339ccee89e4075324097f0a55157c89fa3f7147bde9d8d7e90335dc087b53
+ checksum: 10c0/f4a49064afae4500be772abdc2211c8518f39e1c959640457dcee15d4488628620625c783902a52af2dd02f68558da2868fd06e6fd0e67ebcd09e6881b1b5bfe
languageName: node
linkType: hard
@@ -31009,7 +30869,7 @@ __metadata:
languageName: node
linkType: hard
-"yargs@npm:^16.1.1, yargs@npm:^16.2.0":
+"yargs@npm:^16.2.0":
version: 16.2.0
resolution: "yargs@npm:16.2.0"
dependencies:
@@ -31051,16 +30911,6 @@ __metadata:
languageName: node
linkType: hard
-"yauzl@npm:^2.10.0":
- version: 2.10.0
- resolution: "yauzl@npm:2.10.0"
- dependencies:
- buffer-crc32: "npm:~0.2.3"
- fd-slicer: "npm:~1.1.0"
- checksum: 10c0/f265002af7541b9ec3589a27f5fb8f11cf348b53cc15e2751272e3c062cd73f3e715bc72d43257de71bbaecae446c3f1b14af7559e8ab0261625375541816422
- languageName: node
- linkType: hard
-
"yn@npm:3.1.1":
version: 3.1.1
resolution: "yn@npm:3.1.1"
@@ -31082,6 +30932,17 @@ __metadata:
languageName: node
linkType: hard
+"youch@npm:3.3.4":
+ version: 3.3.4
+ resolution: "youch@npm:3.3.4"
+ dependencies:
+ cookie: "npm:^0.7.1"
+ mustache: "npm:^4.2.0"
+ stacktracey: "npm:^2.1.8"
+ checksum: 10c0/ab573c7dccebdaf2d6b084d262d5bfb22ad5c049fb1ad3e2d6a840af851042dd3a8a072665c5a5ee73c75bbc1618fbc08f1371ac896e54556bced0ddf996b026
+ languageName: node
+ linkType: hard
+
"zod-validation-error@npm:^3.5.0 || ^4.0.0":
version: 4.0.2
resolution: "zod-validation-error@npm:4.0.2"
@@ -31091,10 +30952,10 @@ __metadata:
languageName: node
linkType: hard
-"zod@npm:^3.24.1":
- version: 3.25.76
- resolution: "zod@npm:3.25.76"
- checksum: 10c0/5718ec35e3c40b600316c5b4c5e4976f7fee68151bc8f8d90ec18a469be9571f072e1bbaace10f1e85cf8892ea12d90821b200e980ab46916a6166a4260a983c
+"zod@npm:3.22.3":
+ version: 3.22.3
+ resolution: "zod@npm:3.22.3"
+ checksum: 10c0/cb4b24aed7dec98552eb9042e88cbd645455bf2830e5704174d2da96f554dabad4630e3b4f6623e1b6562b9eaa43535a37b7f2011f29b8d8e9eabe1ddf3b656b
languageName: node
linkType: hard