diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 850db7e8c0..b06e486f1d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -103,11 +103,11 @@ jobs: matrix: include: - name: Node 20 - NODE_VERSION: 20.18.0 + NODE_VERSION: 20.19.0 - name: Node 22 NODE_VERSION: 22.12.0 - name: Node 24 - NODE_VERSION: 24.0.0 + NODE_VERSION: 24.1.0 fail-fast: false name: ${{ matrix.name }} timeout-minutes: 15 diff --git a/Parse-Dashboard/app.js b/Parse-Dashboard/app.js index c22df1af93..8c2845d8ac 100644 --- a/Parse-Dashboard/app.js +++ b/Parse-Dashboard/app.js @@ -87,6 +87,32 @@ module.exports = function(config, options) { cookieSessionStore: options.cookieSessionStore }); + /** + * Checks whether a request is from localhost. + */ + function isLocalRequest(req) { + return req.connection.remoteAddress === '127.0.0.1' || + req.connection.remoteAddress === '::ffff:127.0.0.1' || + req.connection.remoteAddress === '::1'; + } + + /** + * Middleware that enforces remote access restrictions: + * - Requires HTTPS for remote requests (unless allowInsecureHTTP is set) + * - Requires users to be configured for remote access (unless dev mode is enabled) + */ + function enforceRemoteAccessRestrictions(req, res, next) { + if (!options.dev && !isLocalRequest(req)) { + if (!req.secure && !options.allowInsecureHTTP) { + return res.status(403).json({ error: 'Parse Dashboard can only be remotely accessed via HTTPS' }); + } + if (!users) { + return res.status(401).json({ error: 'Configure a user to access Parse Dashboard remotely' }); + } + } + next(); + } + // CSRF error handler app.use(function (err, req, res, next) { if (err.code !== 'EBADCSRFTOKEN') {return next(err)} @@ -109,13 +135,7 @@ module.exports = function(config, options) { agent: config.agent, }; - //Based on advice from Doug Wilson here: - //https://github.com/expressjs/express/issues/2518 - const requestIsLocal = - req.connection.remoteAddress === '127.0.0.1' || - req.connection.remoteAddress === '::ffff:127.0.0.1' || - req.connection.remoteAddress === '::1'; - if (!options.dev && !requestIsLocal) { + if (!options.dev && !isLocalRequest(req)) { if (!req.secure && !options.allowInsecureHTTP) { //Disallow HTTP requests except on localhost, to prevent the master key from being transmitted in cleartext return res.send({ success: false, error: 'Parse Dashboard can only be remotely accessed via HTTPS' }); @@ -179,7 +199,7 @@ module.exports = function(config, options) { //They didn't provide auth, and have configured the dashboard to not need auth //(ie. didn't supply usernames and passwords) - if (requestIsLocal || options.dev) { + if (isLocalRequest(req) || options.dev) { //Allow no-auth access on localhost only, if they have configured the dashboard to not need auth await Promise.all( response.apps.map(async (app) => { @@ -329,8 +349,9 @@ module.exports = function(config, options) { } } - // Agent API endpoint — middleware chain: auth check (401) → CSRF validation (403) → handler + // Agent API endpoint — middleware chain: remote access guard → auth check (401) → CSRF validation (403) → handler app.post('/apps/:appId/agent', + enforceRemoteAccessRestrictions, (req, res, next) => { if (users && (!req.user || !req.user.isAuthenticated)) { return res.status(401).json({ error: 'Unauthorized' }); diff --git a/README.md b/README.md index 37824289c8..7821464eea 100644 --- a/README.md +++ b/README.md @@ -92,6 +92,9 @@ Parse Dashboard is a standalone dashboard for managing your [Parse Server](https - [Response Fields](#response-fields) - [Form Elements](#form-elements) - [Drop-Down](#drop-down) + - [Checkbox](#checkbox) + - [Toggle](#toggle) + - [Text Input](#text-input) - [Graph](#graph) - [Calculated Values](#calculated-values) - [Formula Operator](#formula-operator) @@ -103,7 +106,8 @@ Parse Dashboard is a standalone dashboard for managing your [Parse Server](https - [Browse as User](#browse-as-user) - [Change Pointer Key](#change-pointer-key) - [Limitations](#limitations) - - [CSV Export](#csv-export) + - [Data Export](#data-export) + - [Data Import](#data-import) - [AI Agent](#ai-agent) - [Configuration](#configuration-1) - [Providers](#providers) @@ -1731,7 +1735,7 @@ This feature allows you to change how a pointer is represented in the browser. B > ⚠️ For each custom pointer key in each row, a server request is triggered to resolve the custom pointer key. For example, if the browser shows a class with 50 rows and each row contains 3 custom pointer keys, a total of 150 separate server requests are triggered. -### CSV Export +### Data Export ▶️ *Core > Browser > Export* @@ -1739,6 +1743,27 @@ This feature will take either selected rows or all rows of an individual class a > ⚠️ There is currently a 10,000 row limit when exporting all data. If more than 10,000 rows are present in the class, the CSV file will only contain 10,000 rows. +### Data Import + +▶️ *Core > Browser > Data > Import* + +Import data into a class from a JSON or CSV file. The file format is the same as the export format, so you can export data from one class and import it into another. + +- **JSON** — An array of objects, e.g. `[{ "name": "Alice", "score": 100 }, ...]`. Typed fields such as `Pointer`, `Date`, `GeoPoint`, and `File` are expected in Parse `_toFullJSON()` format. +- **CSV** — Comma-separated with a header row. Column types are reconstructed from the class schema. + +The import dialog provides the following options: + +| Option | Description | +|---|---| +| Preserve object IDs | Use `objectId` values from the file instead of generating new ones. Requires the server option `allowCustomObjectId`. | +| Preserve timestamps | Use `createdAt` / `updatedAt` from the file. Requires `apps[].maintenanceKey` in the dashboard config. | +| Duplicate handling | When preserving object IDs: overwrite, skip, or fail on duplicates. | +| Unknown columns | Auto-create new columns, ignore them, or fail on unknown columns. | +| Continue on errors | Skip failing rows and continue, or stop on the first error. | + +> ⚠️ Disabling *Preserve object IDs* means new object IDs are generated. Any `Pointer` or `Relation` fields that reference objects within the same import file will not resolve correctly. + ## AI Agent The Parse Dashboard includes an AI agent that can help manage your Parse Server data through natural language commands. The agent can perform operations like creating classes, adding data, querying records, and more. diff --git a/changelogs/CHANGELOG_alpha.md b/changelogs/CHANGELOG_alpha.md index d0b6656969..34a5fe67bf 100644 --- a/changelogs/CHANGELOG_alpha.md +++ b/changelogs/CHANGELOG_alpha.md @@ -1,3 +1,129 @@ +# [9.1.0-alpha.11](https://github.com/parse-community/parse-dashboard/compare/9.1.0-alpha.10...9.1.0-alpha.11) (2026-03-25) + + +### Bug Fixes + +* Cell content not selected on double clicking data browser cell ([#3271](https://github.com/parse-community/parse-dashboard/issues/3271)) ([9df3beb](https://github.com/parse-community/parse-dashboard/commit/9df3bebd961b8ddc20074523de04ee39e07c378e)) + +# [9.1.0-alpha.10](https://github.com/parse-community/parse-dashboard/compare/9.1.0-alpha.9...9.1.0-alpha.10) (2026-03-25) + + +### Features + +* Highlight row of selected cell in data browser ([#3270](https://github.com/parse-community/parse-dashboard/issues/3270)) ([298ae63](https://github.com/parse-community/parse-dashboard/commit/298ae6328b61381577c51349405f81bfd9e7a1bc)) + +# [9.1.0-alpha.9](https://github.com/parse-community/parse-dashboard/compare/9.1.0-alpha.8...9.1.0-alpha.9) (2026-03-14) + + +### Bug Fixes + +* Security upgrade undici ([#3265](https://github.com/parse-community/parse-dashboard/issues/3265)) ([df23ef8](https://github.com/parse-community/parse-dashboard/commit/df23ef816c146aeeae1dd7269fa64c14f8923778)) + +# [9.1.0-alpha.8](https://github.com/parse-community/parse-dashboard/compare/9.1.0-alpha.7...9.1.0-alpha.8) (2026-03-06) + + +### Features + +* Enforce remote access restrictions on `agent` endpoint ([#3255](https://github.com/parse-community/parse-dashboard/issues/3255)) ([edef824](https://github.com/parse-community/parse-dashboard/commit/edef824d2243bf1930d07466bf7909d88c490786)) + +# [9.1.0-alpha.7](https://github.com/parse-community/parse-dashboard/compare/9.1.0-alpha.6...9.1.0-alpha.7) (2026-03-02) + + +### Features + +* Add confirmation dialog when closing Cloud Config edit parameter dialog without saving changes ([#3247](https://github.com/parse-community/parse-dashboard/issues/3247)) ([9ec03e0](https://github.com/parse-community/parse-dashboard/commit/9ec03e09f40c0af2380fa841b902c99119e31ea6)) + +# [9.1.0-alpha.6](https://github.com/parse-community/parse-dashboard/compare/9.1.0-alpha.5...9.1.0-alpha.6) (2026-03-02) + + +### Bug Fixes + +* Column resizing mouse cursor in data browser not visible in Safari browser ([#3246](https://github.com/parse-community/parse-dashboard/issues/3246)) ([e6fb4d7](https://github.com/parse-community/parse-dashboard/commit/e6fb4d7b85452e93368299bcd8f73418eaee5da5)) + +# [9.1.0-alpha.5](https://github.com/parse-community/parse-dashboard/compare/9.1.0-alpha.4...9.1.0-alpha.5) (2026-03-02) + + +### Bug Fixes + +* Edit icon does not disappear when hovering out of saved filter name in data browser sidebar ([#3245](https://github.com/parse-community/parse-dashboard/issues/3245)) ([d3dcfce](https://github.com/parse-community/parse-dashboard/commit/d3dcfce23c1ad7876604aa2018d1ba3efe2cf8e6)) + +# [9.1.0-alpha.4](https://github.com/parse-community/parse-dashboard/compare/9.1.0-alpha.3...9.1.0-alpha.4) (2026-03-02) + + +### Features + +* Add support for data import in data browser ([#3244](https://github.com/parse-community/parse-dashboard/issues/3244)) ([16f60f4](https://github.com/parse-community/parse-dashboard/commit/16f60f45b00ad98d95178efe7601f283c57d0a07)) + +# [9.1.0-alpha.3](https://github.com/parse-community/parse-dashboard/compare/9.1.0-alpha.2...9.1.0-alpha.3) (2026-03-01) + + +### Bug Fixes + +* Date value cannot be pasted into date field in data browser ([#3243](https://github.com/parse-community/parse-dashboard/issues/3243)) ([e902bea](https://github.com/parse-community/parse-dashboard/commit/e902bea4302d025898dce44aedcc904617f7ee74)) + +# [9.1.0-alpha.2](https://github.com/parse-community/parse-dashboard/compare/9.1.0-alpha.1...9.1.0-alpha.2) (2026-02-27) + + +### Bug Fixes + +* Layout issues when resizing Cloud Config parameter dialog ([#3241](https://github.com/parse-community/parse-dashboard/issues/3241)) ([c6e95d9](https://github.com/parse-community/parse-dashboard/commit/c6e95d9e1f3ac8f5e68cd1cc2c70664abc670dd0)) + +# [9.1.0-alpha.1](https://github.com/parse-community/parse-dashboard/compare/9.0.1-alpha.7...9.1.0-alpha.1) (2026-02-27) + + +### Features + +* Add diff view to Cloud Config parameter dialog for better conflict handling ([#3239](https://github.com/parse-community/parse-dashboard/issues/3239)) ([f007a68](https://github.com/parse-community/parse-dashboard/commit/f007a6836a5477c014b2139600fda03073bde4be)) + +## [9.0.1-alpha.7](https://github.com/parse-community/parse-dashboard/compare/9.0.1-alpha.6...9.0.1-alpha.7) (2026-02-20) + + +### Bug Fixes + +* Security removal dependency svg-prep ([#3236](https://github.com/parse-community/parse-dashboard/issues/3236)) ([abb08c6](https://github.com/parse-community/parse-dashboard/commit/abb08c63b3a5b2c0102560ca21353bc7885cc63e)) + +## [9.0.1-alpha.6](https://github.com/parse-community/parse-dashboard/compare/9.0.1-alpha.5...9.0.1-alpha.6) (2026-02-20) + + +### Bug Fixes + +* Security upgrade transitive dependency ajv ([#3231](https://github.com/parse-community/parse-dashboard/issues/3231)) ([d1e5e41](https://github.com/parse-community/parse-dashboard/commit/d1e5e4156f5b0485afe8021e9525565922530d36)) + +## [9.0.1-alpha.5](https://github.com/parse-community/parse-dashboard/compare/9.0.1-alpha.4...9.0.1-alpha.5) (2026-02-20) + + +### Bug Fixes + +* Security removal dependency null-loader ([#3230](https://github.com/parse-community/parse-dashboard/issues/3230)) ([5e1b1fa](https://github.com/parse-community/parse-dashboard/commit/5e1b1fa0912c48a5698dc80819a27b85627ef0f3)) + +## [9.0.1-alpha.4](https://github.com/parse-community/parse-dashboard/compare/9.0.1-alpha.3...9.0.1-alpha.4) (2026-02-20) + + +### Bug Fixes + +* Security upgrade transitive dependency undici ([#3229](https://github.com/parse-community/parse-dashboard/issues/3229)) ([8e1be1f](https://github.com/parse-community/parse-dashboard/commit/8e1be1f8bee5aef85e4a2ed686b5007d9d814f7e)) + +## [9.0.1-alpha.3](https://github.com/parse-community/parse-dashboard/compare/9.0.1-alpha.2...9.0.1-alpha.3) (2026-02-19) + + +### Bug Fixes + +* Security upgrade transitive dependency qs ([#3228](https://github.com/parse-community/parse-dashboard/issues/3228)) ([225c710](https://github.com/parse-community/parse-dashboard/commit/225c71047eedb57cb4134ac618adf629b2ab07a2)) + +## [9.0.1-alpha.2](https://github.com/parse-community/parse-dashboard/compare/9.0.1-alpha.1...9.0.1-alpha.2) (2026-02-19) + + +### Bug Fixes + +* Remove unused dependencies ([#3227](https://github.com/parse-community/parse-dashboard/issues/3227)) ([3ba250d](https://github.com/parse-community/parse-dashboard/commit/3ba250df8421166b00eb906b191c147e237a3606)) + +## [9.0.1-alpha.1](https://github.com/parse-community/parse-dashboard/compare/9.0.0...9.0.1-alpha.1) (2026-02-19) + + +### Bug Fixes + +* Bump fast-xml-parser from 5.3.5 to 5.3.6 ([#3223](https://github.com/parse-community/parse-dashboard/issues/3223)) ([aee458b](https://github.com/parse-community/parse-dashboard/commit/aee458b36a88ee28bc9e551bbe994d964261895b)) + # [9.0.0-alpha.8](https://github.com/parse-community/parse-dashboard/compare/9.0.0-alpha.7...9.0.0-alpha.8) (2026-02-19) diff --git a/ci/CiVersionCheck.js b/ci/CiVersionCheck.mjs similarity index 98% rename from ci/CiVersionCheck.js rename to ci/CiVersionCheck.mjs index 098dee59d3..3e34ad6f55 100644 --- a/ci/CiVersionCheck.js +++ b/ci/CiVersionCheck.mjs @@ -1,7 +1,7 @@ -const core = require('@actions/core'); -const semver = require('semver'); -const yaml = require('yaml'); -const fs = require('fs').promises; +import * as core from '@actions/core'; +import semver from 'semver'; +import yaml from 'yaml'; +import fs from 'fs/promises'; /** * This checks the CI version of an environment variable in a YAML file @@ -287,4 +287,4 @@ class CiVersionCheck { } } -module.exports = CiVersionCheck; +export default CiVersionCheck; diff --git a/ci/ciCheck.js b/ci/ciCheck.mjs similarity index 88% rename from ci/ciCheck.js rename to ci/ciCheck.mjs index 492ab04ee6..1e3a0b938b 100644 --- a/ci/ciCheck.js +++ b/ci/ciCheck.mjs @@ -1,7 +1,5 @@ -'use strict' - -const CiVersionCheck = require('./CiVersionCheck'); -const allNodeVersions = require('all-node-versions'); +import CiVersionCheck from './CiVersionCheck.mjs'; +import allNodeVersions from 'all-node-versions'; async function check() { // Run checks diff --git a/ci/nodeEngineCheck.js b/ci/nodeEngineCheck.mjs similarity index 96% rename from ci/nodeEngineCheck.js rename to ci/nodeEngineCheck.mjs index 9af1544237..e7bbd2ae9a 100644 --- a/ci/nodeEngineCheck.js +++ b/ci/nodeEngineCheck.mjs @@ -1,7 +1,10 @@ -const core = require('@actions/core'); -const semver = require('semver'); -const fs = require('fs').promises; -const path = require('path'); +import * as core from '@actions/core'; +import semver from 'semver'; +import fs from 'fs/promises'; +import path from 'path'; +import { fileURLToPath } from 'url'; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); /** * This checks whether any package dependency requires a minimum node engine diff --git a/eslint.config.js b/eslint.config.js index af542474a3..1f4fbe8f0f 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -15,7 +15,7 @@ module.exports = defineConfig([ js.configs.recommended, reactPlugin.configs.flat.recommended, { - files: ['**/*.js', '**/*.jsx', '**/*.ts', '**/*.tsx'], + files: ['**/*.js', '**/*.jsx', '**/*.mjs', '**/*.ts', '**/*.tsx'], languageOptions: { parser: babelParser, parserOptions: { diff --git a/package-lock.json b/package-lock.json index b70123aae0..4f4c6c9892 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,16 +1,16 @@ { "name": "parse-dashboard", - "version": "9.0.0", + "version": "9.1.0-alpha.11", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "parse-dashboard", - "version": "9.0.0", + "version": "9.1.0-alpha.11", "license": "SEE LICENSE IN LICENSE", "dependencies": { - "@babel/runtime": "7.28.6", - "@babel/runtime-corejs3": "7.29.0", + "@babel/runtime": "7.29.2", + "@babel/runtime-corejs3": "7.29.2", "bcryptjs": "3.0.3", "body-parser": "2.2.2", "chart.js": "4.5.1", @@ -19,20 +19,21 @@ "copy-to-clipboard": "3.3.3", "core-js": "3.48.0", "csrf-sync": "4.2.1", - "expr-eval-fork": "3.0.1", + "diff": "8.0.3", + "expr-eval-fork": "3.0.3", "express": "5.2.1", "express-session": "1.18.2", "fast-deep-equal": "3.1.3", "graphiql": "2.0.8", "graphql": "16.12.0", - "immutable": "5.1.4", + "immutable": "5.1.5", "immutable-devtools": "0.1.5", "inquirer": "13.2.2", "js-beautify": "1.15.4", "node-fetch": "3.3.2", "otpauth": "8.0.3", "package-json": "7.0.0", - "parse": "7.1.2", + "parse": "8.5.0", "passport": "0.7.0", "passport-local": "1.0.0", "prismjs": "1.30.0", @@ -57,7 +58,7 @@ "parse-dashboard": "bin/parse-dashboard" }, "devDependencies": { - "@actions/core": "2.0.1", + "@actions/core": "3.0.0", "@babel/core": "7.29.0", "@babel/eslint-parser": "7.28.6", "@babel/plugin-proposal-decorators": "7.29.0", @@ -69,38 +70,34 @@ "@semantic-release/changelog": "6.0.3", "@semantic-release/commit-analyzer": "13.0.1", "@semantic-release/git": "10.0.1", - "@semantic-release/github": "12.0.3", + "@semantic-release/github": "12.0.6", "@semantic-release/npm": "13.1.4", "@semantic-release/release-notes-generator": "14.1.0", "@types/jest": "30.0.0", "all-node-versions": "13.0.1", - "babel-loader": "10.0.0", - "css-loader": "6.7.3", + "babel-loader": "10.1.1", + "css-loader": "7.1.4", "eslint": "9.39.2", - "eslint-plugin-jest": "29.5.0", + "eslint-plugin-jest": "29.15.0", "eslint-plugin-react": "7.37.5", - "get-port": "7.1.0", + "get-port": "7.2.0", "globals": "17.3.0", "http-server": "14.1.1", "husky": "9.1.7", "jest": "30.0.4", "jest-environment-jsdom": "30.0.5", "madge": "8.0.0", - "marked": "15.0.12", + "marked": "17.0.3", "mongodb-runner": "^6.6.0", - "null-loader": "4.0.1", - "parse-server": "9.2.0", + "parse-server": "9.7.0", "prettier": "3.8.1", "puppeteer": "24.37.2", "react-test-renderer": "16.13.1", - "request": "2.88.2", - "request-promise": "4.2.6", "sass": "1.97.3", "sass-loader": "16.0.7", "semantic-release": "25.0.3", - "semver": "7.7.3", + "semver": "7.7.4", "style-loader": "3.3.1", - "svg-prep": "1.0.4", "typescript": "5.9.3", "webpack": "5.105.1", "webpack-cli": "6.0.1", @@ -108,45 +105,45 @@ "yaml": "2.8.2" }, "engines": { - "node": ">=20.18.0 <21.0.0 || >=22.12.0 <23.0.0 || >=24.0.0 <25.0.0" + "node": ">=20.19.0 <21.0.0 || >=22.12.0 <23.0.0 || >=24.1.0 <25.0.0" } }, "node_modules/@actions/core": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@actions/core/-/core-2.0.1.tgz", - "integrity": "sha512-oBfqT3GwkvLlo1fjvhQLQxuwZCGTarTE5OuZ2Wg10hvhBj7LRIlF611WT4aZS6fDhO5ZKlY7lCAZTlpmyaHaeg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@actions/core/-/core-3.0.0.tgz", + "integrity": "sha512-zYt6cz+ivnTmiT/ksRVriMBOiuoUpDCJJlZ5KPl2/FRdvwU3f7MPh9qftvbkXJThragzUZieit2nyHUyw53Seg==", "dev": true, "license": "MIT", "dependencies": { - "@actions/exec": "^2.0.0", - "@actions/http-client": "^3.0.0" + "@actions/exec": "^3.0.0", + "@actions/http-client": "^4.0.0" } }, "node_modules/@actions/exec": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@actions/exec/-/exec-2.0.0.tgz", - "integrity": "sha512-k8ngrX2voJ/RIN6r9xB82NVqKpnMRtxDoiO+g3olkIUpQNqjArXrCQceduQZCQj3P3xm32pChRLqRrtXTlqhIw==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@actions/exec/-/exec-3.0.0.tgz", + "integrity": "sha512-6xH/puSoNBXb72VPlZVm7vQ+svQpFyA96qdDBvhB8eNZOE8LtPf9L4oAsfzK/crCL8YZ+19fKYVnM63Sl+Xzlw==", "dev": true, "license": "MIT", "dependencies": { - "@actions/io": "^2.0.0" + "@actions/io": "^3.0.2" } }, "node_modules/@actions/http-client": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-3.0.0.tgz", - "integrity": "sha512-1s3tXAfVMSz9a4ZEBkXXRQD4QhY3+GAsWSbaYpeknPOKEeyRiU3lH+bHiLMZdo2x/fIeQ/hscL1wCkDLVM2DZQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-4.0.0.tgz", + "integrity": "sha512-QuwPsgVMsD6qaPD57GLZi9sqzAZCtiJT8kVBCDpLtxhL5MydQ4gS+DrejtZZPdIYyB1e95uCK9Luyds7ybHI3g==", "dev": true, "license": "MIT", "dependencies": { "tunnel": "^0.0.6", - "undici": "^5.28.5" + "undici": "^6.23.0" } }, "node_modules/@actions/io": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@actions/io/-/io-2.0.0.tgz", - "integrity": "sha512-Jv33IN09XLO+0HS79aaODsvIRyduiF7NY/F6LYeK5oeUmrsz7aFdRphQjFoESF4jS7lMauDOttKALcpapVDIAg==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@actions/io/-/io-3.0.2.tgz", + "integrity": "sha512-nRBchcMM+QK1pdjO7/idu86rbJI5YHUKCvKs0KxnSYbVe3F51UfGxuZX4Qy/fWlp6l7gWFwIkrOzN+oUK03kfw==", "dev": true, "license": "MIT" }, @@ -187,9 +184,9 @@ } }, "node_modules/@apollo/server": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@apollo/server/-/server-5.4.0.tgz", - "integrity": "sha512-E0/2C5Rqp7bWCjaDh4NzYuEPDZ+dltTf2c0FI6GCKJA6GBetVferX3h1//1rS4+NxD36wrJsGGJK+xyT/M3ysg==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@apollo/server/-/server-5.5.0.tgz", + "integrity": "sha512-vWtodBOK/SZwBTJzItECOmLfL8E8pn/IdvP7pnxN5g2tny9iW4+9sxdajE798wV1H2+PYp/rRcl/soSHIBKMPw==", "dev": true, "license": "MIT", "dependencies": { @@ -205,7 +202,7 @@ "@apollo/utils.withrequired": "^3.0.0", "@graphql-tools/schema": "^10.0.0", "async-retry": "^1.2.1", - "body-parser": "2.2.2", + "body-parser": "^2.2.2", "content-type": "^1.0.5", "cors": "^2.8.5", "finalhandler": "^2.1.0", @@ -248,20 +245,6 @@ "node": "20 || >=22" } }, - "node_modules/@apollo/server/node_modules/uuid": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz", - "integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==", - "dev": true, - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], - "license": "MIT", - "bin": { - "uuid": "dist/esm/bin/uuid" - } - }, "node_modules/@apollo/usage-reporting-protobuf": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/@apollo/usage-reporting-protobuf/-/usage-reporting-protobuf-4.1.1.tgz", @@ -2390,18 +2373,18 @@ } }, "node_modules/@babel/runtime": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.6.tgz", - "integrity": "sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==", + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.2.tgz", + "integrity": "sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==", "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/runtime-corejs3": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.29.0.tgz", - "integrity": "sha512-TgUkdp71C9pIbBcHudc+gXZnihEDOjUAmXO1VO4HHGES7QLZcShR0stfKIxLSNIYx2fqhmJChOjm/wkF8wv4gA==", + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.29.2.tgz", + "integrity": "sha512-Lc94FOD5+0aXhdb0Tdg3RUtqT6yWbI/BbFWvlaSJ3gAb9Ks+99nHRDKADVqC37er4eCB0fHyWT+y+K3QOvJKbw==", "license": "MIT", "dependencies": { "core-js-pure": "^3.48.0" @@ -2906,14 +2889,11 @@ } }, "node_modules/@fastify/busboy": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz", - "integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-3.2.0.tgz", + "integrity": "sha512-m9FVDXU3GT2ITSe0UaMA5rU3QkfC/UXtCU8y0gSN/GugTqtVldOBWIB5V6V3sbmenVZUIpU6f+mPEO2+m5iTaA==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=14" - } + "license": "MIT" }, "node_modules/@firebase/app-check-interop-types": { "version": "0.3.3", @@ -2937,13 +2917,13 @@ "license": "Apache-2.0" }, "node_modules/@firebase/component": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.7.0.tgz", - "integrity": "sha512-wR9En2A+WESUHexjmRHkqtaVH94WLNKt6rmeqZhSLBybg4Wyf0Umk04SZsS6sBq4102ZsDBFwoqMqJYj2IoDSg==", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.7.2.tgz", + "integrity": "sha512-iyVDGc6Vjx7Rm0cAdccLH/NG6fADsgJak/XW9IA2lPf8AjIlsemOpFGKczYyPHxm4rnKdR8z6sK4+KEC7NwmEg==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@firebase/util": "1.13.0", + "@firebase/util": "1.15.0", "tslib": "^2.1.0" }, "engines": { @@ -2951,17 +2931,17 @@ } }, "node_modules/@firebase/database": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@firebase/database/-/database-1.1.0.tgz", - "integrity": "sha512-gM6MJFae3pTyNLoc9VcJNuaUDej0ctdjn3cVtILo3D5lpp0dmUHHLFN/pUKe7ImyeB1KAvRlEYxvIHNF04Filg==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@firebase/database/-/database-1.1.2.tgz", + "integrity": "sha512-lP96CMjMPy/+d1d9qaaHjHHdzdwvEOuyyLq9ehX89e2XMKwS1jHNzYBO+42bdSumuj5ukPbmnFtViZu8YOMT+w==", "dev": true, "license": "Apache-2.0", "dependencies": { "@firebase/app-check-interop-types": "0.3.3", "@firebase/auth-interop-types": "0.2.4", - "@firebase/component": "0.7.0", + "@firebase/component": "0.7.2", "@firebase/logger": "0.5.0", - "@firebase/util": "1.13.0", + "@firebase/util": "1.15.0", "faye-websocket": "0.11.4", "tslib": "^2.1.0" }, @@ -2970,17 +2950,17 @@ } }, "node_modules/@firebase/database-compat": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-2.1.0.tgz", - "integrity": "sha512-8nYc43RqxScsePVd1qe1xxvWNf0OBnbwHxmXJ7MHSuuTVYFO3eLyLW3PiCKJ9fHnmIz4p4LbieXwz+qtr9PZDg==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-2.1.2.tgz", + "integrity": "sha512-j4A6IhVZbgxAzT6gJJC2PfOxYCK9SrDrUO7nTM4EscTYtKkAkzsbKoCnDdjFapQfnsncvPWjqVTr/0PffUwg3g==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@firebase/component": "0.7.0", - "@firebase/database": "1.1.0", - "@firebase/database-types": "1.0.16", + "@firebase/component": "0.7.2", + "@firebase/database": "1.1.2", + "@firebase/database-types": "1.0.18", "@firebase/logger": "0.5.0", - "@firebase/util": "1.13.0", + "@firebase/util": "1.15.0", "tslib": "^2.1.0" }, "engines": { @@ -2988,14 +2968,14 @@ } }, "node_modules/@firebase/database-types": { - "version": "1.0.16", - "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-1.0.16.tgz", - "integrity": "sha512-xkQLQfU5De7+SPhEGAXFBnDryUWhhlFXelEg2YeZOQMCdoe7dL64DDAd77SQsR+6uoXIZY5MB4y/inCs4GTfcw==", + "version": "1.0.18", + "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-1.0.18.tgz", + "integrity": "sha512-yOY8IC2go9lfbVDMiy2ATun4EB2AFwocPaQADwMN/RHRUAZSM4rlAV7PGbWPSG/YhkJ2A9xQAiAENgSua9G5Fg==", "dev": true, "license": "Apache-2.0", "dependencies": { "@firebase/app-types": "0.9.3", - "@firebase/util": "1.13.0" + "@firebase/util": "1.15.0" } }, "node_modules/@firebase/logger": { @@ -3012,9 +2992,9 @@ } }, "node_modules/@firebase/util": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.13.0.tgz", - "integrity": "sha512-0AZUyYUfpMNcztR5l09izHwXkZpghLgCUaAGjtMwXnCg3bj4ml5VgiwqOMOxJ+Nw4qN/zJAaOQBcJ7KGkWStqQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.15.0.tgz", + "integrity": "sha512-AmWf3cHAOMbrCPG4xdPKQaj5iHnyYfyLKZxwz+Xf55bqKbpAmcYifB4jQinT2W9XhDRHISOoPyBOariJpCG6FA==", "dev": true, "hasInstallScript": true, "license": "Apache-2.0", @@ -3905,6 +3885,19 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/@isaacs/fs-minipass": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", + "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.4" + }, + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -4239,9 +4232,9 @@ } }, "node_modules/@jest/environment-jsdom-abstract/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "dev": true, "license": "MIT", "engines": { @@ -4408,10 +4401,11 @@ } }, "node_modules/@jest/reporters/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.3.tgz", + "integrity": "sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } @@ -4840,18 +4834,18 @@ } }, "node_modules/@mongodb-js/mongodb-downloader": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/@mongodb-js/mongodb-downloader/-/mongodb-downloader-1.1.7.tgz", - "integrity": "sha512-5CbL5lybUKrtvKdBqyAMn9+bwrdeTxOoql+5l5OlGLKcF/pjwu54mGdC1pU/mTyeux9hLqMOozw4fNNJFccHnw==", + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@mongodb-js/mongodb-downloader/-/mongodb-downloader-1.1.9.tgz", + "integrity": "sha512-YUHqAX9cTMLGCQ0r26geG+GInCTDzDx0qS8nRSvRGSVIkY/YJEf8y7HVYk/vvcMx4d3NZqkPWMwJYKjTHIqiqw==", "dev": true, "license": "Apache-2.0", "dependencies": { "debug": "^4.4.0", "decompress": "^4.2.1", - "mongodb-download-url": "^1.8.7", + "mongodb-download-url": "^1.8.8", "node-fetch": "^2.7.0", "proper-lockfile": "^4.1.2", - "tar": "^6.1.15" + "tar": "^7.5.11" } }, "node_modules/@mongodb-js/mongodb-downloader/node_modules/node-fetch": { @@ -5540,9 +5534,9 @@ "integrity": "sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==" }, "node_modules/@opentelemetry/api": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", - "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.1.tgz", + "integrity": "sha512-gLyJlPHPZYdAk1JENA9LeHejZe1Ti77/pTeFm/nMXmQH/HFZlcS/O2XJB+L8fkbrNSqhdtlvjBVjxwUYanNH5Q==", "dev": true, "license": "Apache-2.0", "optional": true, @@ -5868,14 +5862,14 @@ "license": "MIT" }, "node_modules/@parse/node-apn": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/@parse/node-apn/-/node-apn-7.0.1.tgz", - "integrity": "sha512-2xBiaznvupLOoXFaxWxcWcqCGlRn9rvqeAQnv8ogL8hZPe1Rd0es+F8ppE7g4QIy5DPJv0R4fruB8amGM6K/qA==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@parse/node-apn/-/node-apn-7.1.0.tgz", + "integrity": "sha512-a40P5nScLDi9Pf7koKKkbwI73px0q+iLaKYNrr7kyKJebq/4duGOy3mMevZS0zltn171k3jB5BWCC27dPGsMmw==", "dev": true, "license": "MIT", "dependencies": { "debug": "4.4.3", - "jsonwebtoken": "9.0.2", + "jsonwebtoken": "9.0.3", "node-forge": "1.3.2", "verror": "1.10.1" }, @@ -5890,6 +5884,29 @@ "dev": true, "license": "MIT" }, + "node_modules/@parse/node-apn/node_modules/jsonwebtoken": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.3.tgz", + "integrity": "sha512-MT/xP0CrubFRNLNKvxJ2BYfy53Zkm++5bX9dtuPbqAeQpTVe0MQTFhao8+Cp//EmJp244xt6Drw/GVEGCUj40g==", + "dev": true, + "license": "MIT", + "dependencies": { + "jws": "^4.0.1", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=12", + "npm": ">=6" + } + }, "node_modules/@parse/node-apn/node_modules/verror": { "version": "1.10.1", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.1.tgz", @@ -5906,45 +5923,55 @@ } }, "node_modules/@parse/push-adapter": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/@parse/push-adapter/-/push-adapter-8.2.0.tgz", - "integrity": "sha512-z5RB1TwNELNSvummTVP1fgncOT424j13HeKxsGHpAftUmjE+hUtSsIeG49chD0gac22Zmrk+7flYjRwQpUs6+w==", + "version": "8.3.1", + "resolved": "https://registry.npmjs.org/@parse/push-adapter/-/push-adapter-8.3.1.tgz", + "integrity": "sha512-UOkL0bTOtUx4R866XtBwGGYvkNLQrQPrPWC4uzpbd9vR8tbfYIQQvBDT7eg58GryLb4EG+NOP8enm/VkhbwMVw==", "dev": true, "license": "MIT", "dependencies": { - "@parse/node-apn": "7.0.1", - "expo-server-sdk": "4.0.0", - "firebase-admin": "13.6.0", + "@parse/node-apn": "7.1.0", + "expo-server-sdk": "5.0.0", + "firebase-admin": "13.6.1", "npmlog": "7.0.1", - "parse": "8.0.3", + "parse": "8.2.0", "web-push": "3.6.7" }, "engines": { "node": "20 || 22 || 24" } }, - "node_modules/@parse/push-adapter/node_modules/@babel/runtime-corejs3": { + "node_modules/@parse/push-adapter/node_modules/@babel/runtime": { "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.28.6.tgz", - "integrity": "sha512-kz2fAQ5UzjV7X7D3ySxmj3vRq89dTpqOZWv76Z6pNPztkwb/0Yj1Mtx1xFrYj6mbIHysxtBot8J4o0JLCblcFw==", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.6.tgz", + "integrity": "sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@parse/push-adapter/node_modules/@babel/runtime-corejs3": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.29.0.tgz", + "integrity": "sha512-TgUkdp71C9pIbBcHudc+gXZnihEDOjUAmXO1VO4HHGES7QLZcShR0stfKIxLSNIYx2fqhmJChOjm/wkF8wv4gA==", "dev": true, "license": "MIT", "dependencies": { - "core-js-pure": "^3.43.0" + "core-js-pure": "^3.48.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@parse/push-adapter/node_modules/parse": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/parse/-/parse-8.0.3.tgz", - "integrity": "sha512-WQPrnfnXy6/p25OFD6qOAVK9hIhhU882Nw1AW5RjAJbO2G7YqChJxBgL94aexsaTnP9ajVzjGISSQ+mESrkMIA==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/parse/-/parse-8.2.0.tgz", + "integrity": "sha512-jSx4zIqCja6O2HKhkzZ6JTm4fBUQS6sQpvFCAsqzaU4XlEhoRLm9mM1tZeYhvxTVA6zymvj/EJZ4YDOXCTRbmA==", "dev": true, "license": "Apache-2.0", "dependencies": { "@babel/runtime": "7.28.6", - "@babel/runtime-corejs3": "7.28.6", + "@babel/runtime-corejs3": "7.29.0", "crypto-js": "4.2.0", "idb-keyval": "6.2.2", "react-native-crypto-js": "1.0.0", @@ -6520,22 +6547,22 @@ "integrity": "sha512-Pc/AFTdwZwEKJxFJvlxrSmGe/di+aAOBn60sremrpLo6VI/6cmiUYNNwlI5KNYttg7uypzA3ILPMPgxB2GYZEg==" }, "node_modules/@redis/bloom": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/@redis/bloom/-/bloom-5.10.0.tgz", - "integrity": "sha512-doIF37ob+l47n0rkpRNgU8n4iacBlKM9xLiP1LtTZTvz8TloJB8qx/MgvhMhKdYG+CvCY2aPBnN2706izFn/4A==", + "version": "5.11.0", + "resolved": "https://registry.npmjs.org/@redis/bloom/-/bloom-5.11.0.tgz", + "integrity": "sha512-KYiVilAhAFN3057afUb/tfYJpsEyTkQB+tQcn5gVVA7DgcNOAj8lLxe4j8ov8BF6I9C1Fe/kwlbuAICcTMX8Lw==", "dev": true, "license": "MIT", "engines": { "node": ">= 18" }, "peerDependencies": { - "@redis/client": "^5.10.0" + "@redis/client": "^5.11.0" } }, "node_modules/@redis/client": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/@redis/client/-/client-5.10.0.tgz", - "integrity": "sha512-JXmM4XCoso6C75Mr3lhKA3eNxSzkYi3nCzxDIKY+YOszYsJjuKbFgVtguVPbLMOttN4iu2fXoc2BGhdnYhIOxA==", + "version": "5.11.0", + "resolved": "https://registry.npmjs.org/@redis/client/-/client-5.11.0.tgz", + "integrity": "sha512-GHoprlNQD51Xq2Ztd94HHV94MdFZQ3CVrpA04Fz8MVoHM0B7SlbmPEVIjwTbcv58z8QyjnrOuikS0rWF03k5dQ==", "dev": true, "license": "MIT", "dependencies": { @@ -6543,45 +6570,53 @@ }, "engines": { "node": ">= 18" + }, + "peerDependencies": { + "@node-rs/xxhash": "^1.1.0" + }, + "peerDependenciesMeta": { + "@node-rs/xxhash": { + "optional": true + } } }, "node_modules/@redis/json": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/@redis/json/-/json-5.10.0.tgz", - "integrity": "sha512-B2G8XlOmTPUuZtD44EMGbtoepQG34RCDXLZbjrtON1Djet0t5Ri7/YPXvL9aomXqP8lLTreaprtyLKF4tmXEEA==", + "version": "5.11.0", + "resolved": "https://registry.npmjs.org/@redis/json/-/json-5.11.0.tgz", + "integrity": "sha512-1iAy9kAtcD0quB21RbPTbUqqy+T2Uu2JxucwE+B4A+VaDbIRvpZR6DMqV8Iqaws2YxJYB3GC5JVNzPYio2ErUg==", "dev": true, "license": "MIT", "engines": { "node": ">= 18" }, "peerDependencies": { - "@redis/client": "^5.10.0" + "@redis/client": "^5.11.0" } }, "node_modules/@redis/search": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/@redis/search/-/search-5.10.0.tgz", - "integrity": "sha512-3SVcPswoSfp2HnmWbAGUzlbUPn7fOohVu2weUQ0S+EMiQi8jwjL+aN2p6V3TI65eNfVsJ8vyPvqWklm6H6esmg==", + "version": "5.11.0", + "resolved": "https://registry.npmjs.org/@redis/search/-/search-5.11.0.tgz", + "integrity": "sha512-g1l7f3Rnyk/xI99oGHIgWHSKFl45Re5YTIcO8j/JE8olz389yUFyz2+A6nqVy/Zi031VgPDWscbbgOk8hlhZ3g==", "dev": true, "license": "MIT", "engines": { "node": ">= 18" }, "peerDependencies": { - "@redis/client": "^5.10.0" + "@redis/client": "^5.11.0" } }, "node_modules/@redis/time-series": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-5.10.0.tgz", - "integrity": "sha512-cPkpddXH5kc/SdRhF0YG0qtjL+noqFT0AcHbQ6axhsPsO7iqPi1cjxgdkE9TNeKiBUUdCaU1DbqkR/LzbzPBhg==", + "version": "5.11.0", + "resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-5.11.0.tgz", + "integrity": "sha512-TWFeOcU4xkj0DkndnOyhtxvX1KWD+78UHT3XX3x3XRBUGWeQrKo3jqzDsZwxbggUgf9yLJr/akFHXru66X5UQA==", "dev": true, "license": "MIT", "engines": { "node": ">= 18" }, "peerDependencies": { - "@redis/client": "^5.10.0" + "@redis/client": "^5.11.0" } }, "node_modules/@remix-run/router": { @@ -7566,22 +7601,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/supports-hyperlinks": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.2.0.tgz", - "integrity": "sha512-zFObLMyZeEwzAoKCyu1B91U79K2t7ApXuQfo8OuxwXLDgcKxuwM+YvcbIhm6QWqz7mHUH1TVytR1PwVVjEuMig==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0", - "supports-color": "^7.0.0" - }, - "engines": { - "node": ">=14.18" - }, - "funding": { - "url": "https://github.com/chalk/supports-hyperlinks?sponsor=1" - } - }, "node_modules/@saithodev/semantic-release-backmerge/node_modules/unicorn-magic": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz", @@ -7687,9 +7706,9 @@ } }, "node_modules/@semantic-release/github": { - "version": "12.0.3", - "resolved": "https://registry.npmjs.org/@semantic-release/github/-/github-12.0.3.tgz", - "integrity": "sha512-pod3AVGVVVk2rUczMBL4+gfY7hP7A9YYOwjpxVFSusF+pDbFOYBzFRQcHjv1H3IntQyB/Noxzx8LUZ/iwAQQeQ==", + "version": "12.0.6", + "resolved": "https://registry.npmjs.org/@semantic-release/github/-/github-12.0.6.tgz", + "integrity": "sha512-aYYFkwHW3c6YtHwQF0t0+lAjlU+87NFOZuH2CvWFD0Ylivc7MwhZMiHOJ0FMpIgPpCVib/VUAcOwvrW0KnxQtA==", "dev": true, "license": "MIT", "dependencies": { @@ -7798,9 +7817,9 @@ } }, "node_modules/@semantic-release/github/node_modules/undici": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-7.16.0.tgz", - "integrity": "sha512-QEg3HPMll0o3t2ourKwOeUAZ159Kn9mx5pnzHRQO8+Wixmh88YdZRiIwat0iNzNNXn0yoEtXJqFpyW7eM8BV7g==", + "version": "7.24.2", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.24.2.tgz", + "integrity": "sha512-P9J1HWYV/ajFr8uCqk5QixwiRKmB1wOamgS0e+o2Z4A44Ej2+thFVRLG/eA7qprx88XXhnV5Bl8LHXTURpzB3Q==", "dev": true, "license": "MIT", "engines": { @@ -7846,45 +7865,6 @@ "semantic-release": ">=20.1.0" } }, - "node_modules/@semantic-release/npm/node_modules/@actions/core": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@actions/core/-/core-3.0.0.tgz", - "integrity": "sha512-zYt6cz+ivnTmiT/ksRVriMBOiuoUpDCJJlZ5KPl2/FRdvwU3f7MPh9qftvbkXJThragzUZieit2nyHUyw53Seg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@actions/exec": "^3.0.0", - "@actions/http-client": "^4.0.0" - } - }, - "node_modules/@semantic-release/npm/node_modules/@actions/exec": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@actions/exec/-/exec-3.0.0.tgz", - "integrity": "sha512-6xH/puSoNBXb72VPlZVm7vQ+svQpFyA96qdDBvhB8eNZOE8LtPf9L4oAsfzK/crCL8YZ+19fKYVnM63Sl+Xzlw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@actions/io": "^3.0.2" - } - }, - "node_modules/@semantic-release/npm/node_modules/@actions/http-client": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-4.0.0.tgz", - "integrity": "sha512-QuwPsgVMsD6qaPD57GLZi9sqzAZCtiJT8kVBCDpLtxhL5MydQ4gS+DrejtZZPdIYyB1e95uCK9Luyds7ybHI3g==", - "dev": true, - "license": "MIT", - "dependencies": { - "tunnel": "^0.0.6", - "undici": "^6.23.0" - } - }, - "node_modules/@semantic-release/npm/node_modules/@actions/io": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@actions/io/-/io-3.0.2.tgz", - "integrity": "sha512-nRBchcMM+QK1pdjO7/idu86rbJI5YHUKCvKs0KxnSYbVe3F51UfGxuZX4Qy/fWlp6l7gWFwIkrOzN+oUK03kfw==", - "dev": true, - "license": "MIT" - }, "node_modules/@semantic-release/npm/node_modules/@semantic-release/error": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-4.0.0.tgz", @@ -8075,9 +8055,9 @@ } }, "node_modules/@semantic-release/npm/node_modules/npm": { - "version": "11.9.0", - "resolved": "https://registry.npmjs.org/npm/-/npm-11.9.0.tgz", - "integrity": "sha512-BBZoU926FCypj4b7V7ElinxsWcy4Kss88UG3ejFYmKyq7Uc5XnT34Me2nEhgCOaL5qY4HvGu5aI92C4OYd7NaA==", + "version": "11.12.1", + "resolved": "https://registry.npmjs.org/npm/-/npm-11.12.1.tgz", + "integrity": "sha512-zcoUuF1kezGSAo0CqtvoLXX3mkRqzuqYdL6Y5tdo8g69NVV3CkjQ6ZBhBgB4d7vGkPcV6TcvLi3GRKPDFX+xTA==", "bundleDependencies": [ "@isaacs/string-locale-compare", "@npmcli/arborist", @@ -8095,7 +8075,6 @@ "cacache", "chalk", "ci-info", - "cli-columns", "fastest-levenshtein", "fs-minipass", "glob", @@ -8157,44 +8136,43 @@ ], "dependencies": { "@isaacs/string-locale-compare": "^1.1.0", - "@npmcli/arborist": "^9.2.0", - "@npmcli/config": "^10.6.0", + "@npmcli/arborist": "^9.4.2", + "@npmcli/config": "^10.8.1", "@npmcli/fs": "^5.0.0", "@npmcli/map-workspaces": "^5.0.3", "@npmcli/metavuln-calculator": "^9.0.3", - "@npmcli/package-json": "^7.0.4", + "@npmcli/package-json": "^7.0.5", "@npmcli/promise-spawn": "^9.0.1", "@npmcli/redact": "^4.0.0", - "@npmcli/run-script": "^10.0.3", - "@sigstore/tuf": "^4.0.1", + "@npmcli/run-script": "^10.0.4", + "@sigstore/tuf": "^4.0.2", "abbrev": "^4.0.0", "archy": "~1.0.0", - "cacache": "^20.0.3", + "cacache": "^20.0.4", "chalk": "^5.6.2", "ci-info": "^4.4.0", - "cli-columns": "^4.0.0", "fastest-levenshtein": "^1.0.16", "fs-minipass": "^3.0.3", - "glob": "^13.0.0", + "glob": "^13.0.6", "graceful-fs": "^4.2.11", "hosted-git-info": "^9.0.2", "ini": "^6.0.0", - "init-package-json": "^8.2.4", - "is-cidr": "^6.0.1", + "init-package-json": "^8.2.5", + "is-cidr": "^6.0.3", "json-parse-even-better-errors": "^5.0.0", "libnpmaccess": "^10.0.3", - "libnpmdiff": "^8.1.0", - "libnpmexec": "^10.2.0", - "libnpmfund": "^7.0.14", + "libnpmdiff": "^8.1.5", + "libnpmexec": "^10.2.5", + "libnpmfund": "^7.0.19", "libnpmorg": "^8.0.1", - "libnpmpack": "^9.1.0", + "libnpmpack": "^9.1.5", "libnpmpublish": "^11.1.3", "libnpmsearch": "^9.0.1", "libnpmteam": "^8.0.2", "libnpmversion": "^8.0.3", - "make-fetch-happen": "^15.0.3", - "minimatch": "^10.1.1", - "minipass": "^7.1.1", + "make-fetch-happen": "^15.0.5", + "minimatch": "^10.2.4", + "minipass": "^7.1.3", "minipass-pipeline": "^1.2.4", "ms": "^2.1.2", "node-gyp": "^12.2.0", @@ -8207,21 +8185,21 @@ "npm-registry-fetch": "^19.1.1", "npm-user-validate": "^4.0.0", "p-map": "^7.0.4", - "pacote": "^21.1.0", + "pacote": "^21.5.0", "parse-conflict-json": "^5.0.1", "proc-log": "^6.1.0", "qrcode-terminal": "^0.12.0", "read": "^5.0.1", - "semver": "^7.7.3", + "semver": "^7.7.4", "spdx-expression-parse": "^4.0.0", - "ssri": "^13.0.0", + "ssri": "^13.0.1", "supports-color": "^10.2.2", - "tar": "^7.5.7", + "tar": "^7.5.11", "text-table": "~0.2.0", "tiny-relative-date": "^2.0.2", "treeverse": "^3.0.0", "validate-npm-package-name": "^7.0.2", - "which": "^6.0.0" + "which": "^6.0.1" }, "bin": { "npm": "bin/npm-cli.js", @@ -8247,25 +8225,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@semantic-release/npm/node_modules/npm/node_modules/@isaacs/balanced-match": { - "version": "4.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": "20 || >=22" - } - }, - "node_modules/@semantic-release/npm/node_modules/npm/node_modules/@isaacs/brace-expansion": { - "version": "5.0.1", + "node_modules/@semantic-release/npm/node_modules/npm/node_modules/@gar/promise-retry": { + "version": "1.0.3", "dev": true, "inBundle": true, "license": "MIT", - "dependencies": { - "@isaacs/balanced-match": "^4.0.1" - }, "engines": { - "node": "20 || >=22" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/@semantic-release/npm/node_modules/npm/node_modules/@isaacs/fs-minipass": { @@ -8303,11 +8269,12 @@ } }, "node_modules/@semantic-release/npm/node_modules/npm/node_modules/@npmcli/arborist": { - "version": "9.2.0", + "version": "9.4.2", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { + "@gar/promise-retry": "^1.0.0", "@isaacs/string-locale-compare": "^1.1.0", "@npmcli/fs": "^5.0.0", "@npmcli/installed-package-contents": "^4.0.0", @@ -8350,7 +8317,7 @@ } }, "node_modules/@semantic-release/npm/node_modules/npm/node_modules/@npmcli/config": { - "version": "10.6.0", + "version": "10.8.1", "dev": true, "inBundle": true, "license": "ISC", @@ -8381,17 +8348,17 @@ } }, "node_modules/@semantic-release/npm/node_modules/npm/node_modules/@npmcli/git": { - "version": "7.0.1", + "version": "7.0.2", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { + "@gar/promise-retry": "^1.0.0", "@npmcli/promise-spawn": "^9.0.0", "ini": "^6.0.0", "lru-cache": "^11.2.1", "npm-pick-manifest": "^11.0.1", "proc-log": "^6.0.0", - "promise-retry": "^2.0.1", "semver": "^7.3.5", "which": "^6.0.0" }, @@ -8465,7 +8432,7 @@ } }, "node_modules/@semantic-release/npm/node_modules/npm/node_modules/@npmcli/package-json": { - "version": "7.0.4", + "version": "7.0.5", "dev": true, "inBundle": true, "license": "ISC", @@ -8476,7 +8443,7 @@ "json-parse-even-better-errors": "^5.0.0", "proc-log": "^6.0.0", "semver": "^7.5.3", - "validate-npm-package-license": "^3.0.4" + "spdx-expression-parse": "^4.0.0" }, "engines": { "node": "^20.17.0 || >=22.9.0" @@ -8516,7 +8483,7 @@ } }, "node_modules/@semantic-release/npm/node_modules/npm/node_modules/@npmcli/run-script": { - "version": "10.0.3", + "version": "10.0.4", "dev": true, "inBundle": true, "license": "ISC", @@ -8525,8 +8492,7 @@ "@npmcli/package-json": "^7.0.0", "@npmcli/promise-spawn": "^9.0.0", "node-gyp": "^12.1.0", - "proc-log": "^6.0.0", - "which": "^6.0.0" + "proc-log": "^6.0.0" }, "engines": { "node": "^20.17.0 || >=22.9.0" @@ -8545,7 +8511,7 @@ } }, "node_modules/@semantic-release/npm/node_modules/npm/node_modules/@sigstore/core": { - "version": "3.1.0", + "version": "3.2.0", "dev": true, "inBundle": true, "license": "Apache-2.0", @@ -8563,24 +8529,24 @@ } }, "node_modules/@semantic-release/npm/node_modules/npm/node_modules/@sigstore/sign": { - "version": "4.1.0", + "version": "4.1.1", "dev": true, "inBundle": true, "license": "Apache-2.0", "dependencies": { + "@gar/promise-retry": "^1.0.2", "@sigstore/bundle": "^4.0.0", - "@sigstore/core": "^3.1.0", + "@sigstore/core": "^3.2.0", "@sigstore/protobuf-specs": "^0.5.0", - "make-fetch-happen": "^15.0.3", - "proc-log": "^6.1.0", - "promise-retry": "^2.0.1" + "make-fetch-happen": "^15.0.4", + "proc-log": "^6.1.0" }, "engines": { "node": "^20.17.0 || >=22.9.0" } }, "node_modules/@semantic-release/npm/node_modules/npm/node_modules/@sigstore/tuf": { - "version": "4.0.1", + "version": "4.0.2", "dev": true, "inBundle": true, "license": "Apache-2.0", @@ -8646,15 +8612,6 @@ "node": ">= 14" } }, - "node_modules/@semantic-release/npm/node_modules/npm/node_modules/ansi-regex": { - "version": "5.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/@semantic-release/npm/node_modules/npm/node_modules/aproba": { "version": "2.1.0", "dev": true, @@ -8667,6 +8624,15 @@ "inBundle": true, "license": "MIT" }, + "node_modules/@semantic-release/npm/node_modules/npm/node_modules/balanced-match": { + "version": "4.0.4", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, "node_modules/@semantic-release/npm/node_modules/npm/node_modules/bin-links": { "version": "6.0.0", "dev": true, @@ -8695,8 +8661,20 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@semantic-release/npm/node_modules/npm/node_modules/brace-expansion": { + "version": "5.0.4", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, "node_modules/@semantic-release/npm/node_modules/npm/node_modules/cacache": { - "version": "20.0.3", + "version": "20.0.4", "dev": true, "inBundle": true, "license": "ISC", @@ -8710,8 +8688,7 @@ "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", "p-map": "^7.0.2", - "ssri": "^13.0.0", - "unique-filename": "^5.0.0" + "ssri": "^13.0.0" }, "engines": { "node": "^20.17.0 || >=22.9.0" @@ -8754,37 +8731,21 @@ } }, "node_modules/@semantic-release/npm/node_modules/npm/node_modules/cidr-regex": { - "version": "5.0.1", + "version": "5.0.3", "dev": true, "inBundle": true, "license": "BSD-2-Clause", - "dependencies": { - "ip-regex": "5.0.0" - }, "engines": { "node": ">=20" } }, - "node_modules/@semantic-release/npm/node_modules/npm/node_modules/cli-columns": { - "version": "4.0.0", + "node_modules/@semantic-release/npm/node_modules/npm/node_modules/cmd-shim": { + "version": "8.0.0", "dev": true, "inBundle": true, - "license": "MIT", - "dependencies": { - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" - }, + "license": "ISC", "engines": { - "node": ">= 10" - } - }, - "node_modules/@semantic-release/npm/node_modules/npm/node_modules/cmd-shim": { - "version": "8.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^20.17.0 || >=22.9.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/@semantic-release/npm/node_modules/npm/node_modules/common-ancestor-path": { @@ -8834,22 +8795,6 @@ "node": ">=0.3.1" } }, - "node_modules/@semantic-release/npm/node_modules/npm/node_modules/emoji-regex": { - "version": "8.0.0", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/@semantic-release/npm/node_modules/npm/node_modules/encoding": { - "version": "0.1.13", - "dev": true, - "inBundle": true, - "license": "MIT", - "optional": true, - "dependencies": { - "iconv-lite": "^0.6.2" - } - }, "node_modules/@semantic-release/npm/node_modules/npm/node_modules/env-paths": { "version": "2.2.1", "dev": true, @@ -8859,12 +8804,6 @@ "node": ">=6" } }, - "node_modules/@semantic-release/npm/node_modules/npm/node_modules/err-code": { - "version": "2.0.3", - "dev": true, - "inBundle": true, - "license": "MIT" - }, "node_modules/@semantic-release/npm/node_modules/npm/node_modules/exponential-backoff": { "version": "3.1.3", "dev": true, @@ -8893,17 +8832,17 @@ } }, "node_modules/@semantic-release/npm/node_modules/npm/node_modules/glob": { - "version": "13.0.1", + "version": "13.0.6", "dev": true, "inBundle": true, "license": "BlueOak-1.0.0", "dependencies": { - "minimatch": "^10.1.2", - "minipass": "^7.1.2", - "path-scurry": "^2.0.0" + "minimatch": "^10.2.2", + "minipass": "^7.1.3", + "path-scurry": "^2.0.2" }, "engines": { - "node": "20 || >=22" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -8960,7 +8899,7 @@ } }, "node_modules/@semantic-release/npm/node_modules/npm/node_modules/iconv-lite": { - "version": "0.6.3", + "version": "0.7.2", "dev": true, "inBundle": true, "license": "MIT", @@ -8970,6 +8909,10 @@ }, "engines": { "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/@semantic-release/npm/node_modules/npm/node_modules/ignore-walk": { @@ -8984,15 +8927,6 @@ "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/@semantic-release/npm/node_modules/npm/node_modules/imurmurhash": { - "version": "0.1.4", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.8.19" - } - }, "node_modules/@semantic-release/npm/node_modules/npm/node_modules/ini": { "version": "6.0.0", "dev": true, @@ -9003,7 +8937,7 @@ } }, "node_modules/@semantic-release/npm/node_modules/npm/node_modules/init-package-json": { - "version": "8.2.4", + "version": "8.2.5", "dev": true, "inBundle": true, "license": "ISC", @@ -9013,7 +8947,6 @@ "promzard": "^3.0.1", "read": "^5.0.1", "semver": "^7.7.2", - "validate-npm-package-license": "^3.0.4", "validate-npm-package-name": "^7.0.0" }, "engines": { @@ -9029,20 +8962,8 @@ "node": ">= 12" } }, - "node_modules/@semantic-release/npm/node_modules/npm/node_modules/ip-regex": { - "version": "5.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@semantic-release/npm/node_modules/npm/node_modules/is-cidr": { - "version": "6.0.2", + "version": "6.0.3", "dev": true, "inBundle": true, "license": "BSD-2-Clause", @@ -9053,22 +8974,13 @@ "node": ">=20" } }, - "node_modules/@semantic-release/npm/node_modules/npm/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/@semantic-release/npm/node_modules/npm/node_modules/isexe": { - "version": "3.1.1", + "version": "4.0.0", "dev": true, "inBundle": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "engines": { - "node": ">=16" + "node": ">=20" } }, "node_modules/@semantic-release/npm/node_modules/npm/node_modules/json-parse-even-better-errors": { @@ -9124,12 +9036,12 @@ } }, "node_modules/@semantic-release/npm/node_modules/npm/node_modules/libnpmdiff": { - "version": "8.1.0", + "version": "8.1.5", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/arborist": "^9.2.0", + "@npmcli/arborist": "^9.4.2", "@npmcli/installed-package-contents": "^4.0.0", "binary-extensions": "^3.0.0", "diff": "^8.0.2", @@ -9143,19 +9055,19 @@ } }, "node_modules/@semantic-release/npm/node_modules/npm/node_modules/libnpmexec": { - "version": "10.2.0", + "version": "10.2.5", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/arborist": "^9.2.0", + "@gar/promise-retry": "^1.0.0", + "@npmcli/arborist": "^9.4.2", "@npmcli/package-json": "^7.0.0", "@npmcli/run-script": "^10.0.0", "ci-info": "^4.0.0", "npm-package-arg": "^13.0.0", "pacote": "^21.0.2", "proc-log": "^6.0.0", - "promise-retry": "^2.0.1", "read": "^5.0.1", "semver": "^7.3.7", "signal-exit": "^4.1.0", @@ -9166,12 +9078,12 @@ } }, "node_modules/@semantic-release/npm/node_modules/npm/node_modules/libnpmfund": { - "version": "7.0.14", + "version": "7.0.19", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/arborist": "^9.2.0" + "@npmcli/arborist": "^9.4.2" }, "engines": { "node": "^20.17.0 || >=22.9.0" @@ -9191,12 +9103,12 @@ } }, "node_modules/@semantic-release/npm/node_modules/npm/node_modules/libnpmpack": { - "version": "9.1.0", + "version": "9.1.5", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/arborist": "^9.2.0", + "@npmcli/arborist": "^9.4.2", "@npmcli/run-script": "^10.0.0", "npm-package-arg": "^13.0.0", "pacote": "^21.0.2" @@ -9266,7 +9178,7 @@ } }, "node_modules/@semantic-release/npm/node_modules/npm/node_modules/lru-cache": { - "version": "11.2.5", + "version": "11.2.7", "dev": true, "inBundle": true, "license": "BlueOak-1.0.0", @@ -9275,12 +9187,14 @@ } }, "node_modules/@semantic-release/npm/node_modules/npm/node_modules/make-fetch-happen": { - "version": "15.0.3", + "version": "15.0.5", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { + "@gar/promise-retry": "^1.0.0", "@npmcli/agent": "^4.0.0", + "@npmcli/redact": "^4.0.0", "cacache": "^20.0.1", "http-cache-semantics": "^4.1.1", "minipass": "^7.0.2", @@ -9289,7 +9203,6 @@ "minipass-pipeline": "^1.2.4", "negotiator": "^1.0.0", "proc-log": "^6.0.0", - "promise-retry": "^2.0.1", "ssri": "^13.0.0" }, "engines": { @@ -9297,25 +9210,25 @@ } }, "node_modules/@semantic-release/npm/node_modules/npm/node_modules/minimatch": { - "version": "10.1.2", + "version": "10.2.4", "dev": true, "inBundle": true, "license": "BlueOak-1.0.0", "dependencies": { - "@isaacs/brace-expansion": "^5.0.1" + "brace-expansion": "^5.0.2" }, "engines": { - "node": "20 || >=22" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/@semantic-release/npm/node_modules/npm/node_modules/minipass": { - "version": "7.1.2", + "version": "7.1.3", "dev": true, "inBundle": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "engines": { "node": ">=16 || 14 >=14.17" } @@ -9333,7 +9246,7 @@ } }, "node_modules/@semantic-release/npm/node_modules/npm/node_modules/minipass-fetch": { - "version": "5.0.1", + "version": "5.0.2", "dev": true, "inBundle": true, "license": "MIT", @@ -9346,7 +9259,7 @@ "node": "^20.17.0 || >=22.9.0" }, "optionalDependencies": { - "encoding": "^0.1.13" + "iconv-lite": "^0.7.2" } }, "node_modules/@semantic-release/npm/node_modules/npm/node_modules/minipass-flush": { @@ -9373,6 +9286,12 @@ "node": ">=8" } }, + "node_modules/@semantic-release/npm/node_modules/npm/node_modules/minipass-flush/node_modules/yallist": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, "node_modules/@semantic-release/npm/node_modules/npm/node_modules/minipass-pipeline": { "version": "1.2.4", "dev": true, @@ -9397,6 +9316,12 @@ "node": ">=8" } }, + "node_modules/@semantic-release/npm/node_modules/npm/node_modules/minipass-pipeline/node_modules/yallist": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, "node_modules/@semantic-release/npm/node_modules/npm/node_modules/minipass-sized": { "version": "2.0.0", "dev": true, @@ -9542,7 +9467,7 @@ } }, "node_modules/@semantic-release/npm/node_modules/npm/node_modules/npm-packlist": { - "version": "10.0.3", + "version": "10.0.4", "dev": true, "inBundle": true, "license": "ISC", @@ -9623,11 +9548,12 @@ } }, "node_modules/@semantic-release/npm/node_modules/npm/node_modules/pacote": { - "version": "21.1.0", + "version": "21.5.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { + "@gar/promise-retry": "^1.0.0", "@npmcli/git": "^7.0.0", "@npmcli/installed-package-contents": "^4.0.0", "@npmcli/package-json": "^7.0.0", @@ -9641,7 +9567,6 @@ "npm-pick-manifest": "^11.0.1", "npm-registry-fetch": "^19.0.0", "proc-log": "^6.0.0", - "promise-retry": "^2.0.1", "sigstore": "^4.0.0", "ssri": "^13.0.0", "tar": "^7.4.3" @@ -9668,7 +9593,7 @@ } }, "node_modules/@semantic-release/npm/node_modules/npm/node_modules/path-scurry": { - "version": "2.0.1", + "version": "2.0.2", "dev": true, "inBundle": true, "license": "BlueOak-1.0.0", @@ -9677,7 +9602,7 @@ "minipass": "^7.1.2" }, "engines": { - "node": "20 || >=22" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -9732,19 +9657,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@semantic-release/npm/node_modules/npm/node_modules/promise-retry": { - "version": "2.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "err-code": "^2.0.2", - "retry": "^0.12.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@semantic-release/npm/node_modules/npm/node_modules/promzard": { "version": "3.0.1", "dev": true, @@ -9786,15 +9698,6 @@ "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/@semantic-release/npm/node_modules/npm/node_modules/retry": { - "version": "0.12.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, "node_modules/@semantic-release/npm/node_modules/npm/node_modules/safer-buffer": { "version": "2.1.2", "dev": true, @@ -9803,7 +9706,7 @@ "optional": true }, "node_modules/@semantic-release/npm/node_modules/npm/node_modules/semver": { - "version": "7.7.3", + "version": "7.7.4", "dev": true, "inBundle": true, "license": "ISC", @@ -9881,26 +9784,6 @@ "node": ">= 14" } }, - "node_modules/@semantic-release/npm/node_modules/npm/node_modules/spdx-correct": { - "version": "3.2.0", - "dev": true, - "inBundle": true, - "license": "Apache-2.0", - "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/@semantic-release/npm/node_modules/npm/node_modules/spdx-correct/node_modules/spdx-expression-parse": { - "version": "3.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, "node_modules/@semantic-release/npm/node_modules/npm/node_modules/spdx-exceptions": { "version": "2.5.0", "dev": true, @@ -9918,13 +9801,13 @@ } }, "node_modules/@semantic-release/npm/node_modules/npm/node_modules/spdx-license-ids": { - "version": "3.0.22", + "version": "3.0.23", "dev": true, "inBundle": true, "license": "CC0-1.0" }, "node_modules/@semantic-release/npm/node_modules/npm/node_modules/ssri": { - "version": "13.0.0", + "version": "13.0.1", "dev": true, "inBundle": true, "license": "ISC", @@ -9935,32 +9818,6 @@ "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/@semantic-release/npm/node_modules/npm/node_modules/string-width": { - "version": "4.2.3", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@semantic-release/npm/node_modules/npm/node_modules/strip-ansi": { - "version": "6.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/@semantic-release/npm/node_modules/npm/node_modules/supports-color": { "version": "10.2.2", "dev": true, @@ -9974,7 +9831,7 @@ } }, "node_modules/@semantic-release/npm/node_modules/npm/node_modules/tar": { - "version": "7.5.7", + "version": "7.5.11", "dev": true, "inBundle": true, "license": "BlueOak-1.0.0", @@ -9989,15 +9846,6 @@ "node": ">=18" } }, - "node_modules/@semantic-release/npm/node_modules/npm/node_modules/tar/node_modules/yallist": { - "version": "5.0.0", - "dev": true, - "inBundle": true, - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=18" - } - }, "node_modules/@semantic-release/npm/node_modules/npm/node_modules/text-table": { "version": "0.2.0", "dev": true, @@ -10078,56 +9926,12 @@ "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/@semantic-release/npm/node_modules/npm/node_modules/unique-filename": { - "version": "5.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "unique-slug": "^6.0.0" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/@semantic-release/npm/node_modules/npm/node_modules/unique-slug": { - "version": "6.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "imurmurhash": "^0.1.4" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, "node_modules/@semantic-release/npm/node_modules/npm/node_modules/util-deprecate": { "version": "1.0.2", "dev": true, "inBundle": true, "license": "MIT" }, - "node_modules/@semantic-release/npm/node_modules/npm/node_modules/validate-npm-package-license": { - "version": "3.0.4", - "dev": true, - "inBundle": true, - "license": "Apache-2.0", - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "node_modules/@semantic-release/npm/node_modules/npm/node_modules/validate-npm-package-license/node_modules/spdx-expression-parse": { - "version": "3.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, "node_modules/@semantic-release/npm/node_modules/npm/node_modules/validate-npm-package-name": { "version": "7.0.2", "dev": true, @@ -10147,12 +9951,12 @@ } }, "node_modules/@semantic-release/npm/node_modules/npm/node_modules/which": { - "version": "6.0.0", + "version": "6.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "isexe": "^3.1.1" + "isexe": "^4.0.0" }, "bin": { "node-which": "bin/which.js" @@ -10162,12 +9966,11 @@ } }, "node_modules/@semantic-release/npm/node_modules/npm/node_modules/write-file-atomic": { - "version": "7.0.0", + "version": "7.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "imurmurhash": "^0.1.4", "signal-exit": "^4.0.1" }, "engines": { @@ -10175,10 +9978,13 @@ } }, "node_modules/@semantic-release/npm/node_modules/npm/node_modules/yallist": { - "version": "4.0.0", + "version": "5.0.0", "dev": true, "inBundle": true, - "license": "ISC" + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } }, "node_modules/@semantic-release/npm/node_modules/parse-json": { "version": "8.3.0", @@ -10322,16 +10128,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@semantic-release/npm/node_modules/undici": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-6.23.0.tgz", - "integrity": "sha512-VfQPToRA5FZs/qJxLIinmU59u0r7LXqoJkCzinq3ckNJp3vKEh7jTWN589YQ5+aoAC/TGRLyJLCPKcLQbM8r9g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18.17" - } - }, "node_modules/@semantic-release/npm/node_modules/unicorn-magic": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz", @@ -10893,53 +10689,12 @@ "form-data": "^2.5.5" } }, - "node_modules/@types/request/node_modules/form-data": { - "version": "2.5.5", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.5.tgz", - "integrity": "sha512-jqdObeR2rxZZbPSGL+3VckHMYtu+f9//KXBsVny6JSX/pa38Fy+bGjuG8eW/H6USNQWhLi8Num++cU2yOCNz4A==", - "dev": true, - "license": "MIT", - "optional": true, + "node_modules/@types/responselike": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", + "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "es-set-tostringtag": "^2.1.0", - "hasown": "^2.0.2", - "mime-types": "^2.1.35", - "safe-buffer": "^5.2.1" - }, - "engines": { - "node": ">= 0.12" - } - }, - "node_modules/@types/request/node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "optional": true - }, - "node_modules/@types/responselike": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", - "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", - "dependencies": { - "@types/node": "*" + "@types/node": "*" } }, "node_modules/@types/scheduler": { @@ -11184,9 +10939,9 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.3.tgz", + "integrity": "sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==", "dev": true, "license": "MIT", "dependencies": { @@ -11978,9 +11733,9 @@ } }, "node_modules/ajv-formats/node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", "dev": true, "license": "MIT", "dependencies": { @@ -12001,15 +11756,6 @@ "dev": true, "license": "MIT" }, - "node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true, - "peerDependencies": { - "ajv": "^6.9.1" - } - }, "node_modules/all-node-versions": { "version": "13.0.1", "resolved": "https://registry.npmjs.org/all-node-versions/-/all-node-versions-13.0.1.tgz", @@ -12308,15 +12054,6 @@ "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" }, - "node_modules/asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "dev": true, - "dependencies": { - "safer-buffer": "~2.1.0" - } - }, "node_modules/asn1.js": { "version": "5.4.1", "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", @@ -12418,8 +12155,10 @@ "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true, + "license": "MIT", + "optional": true }, "node_modules/available-typed-arrays": { "version": "1.0.7", @@ -12436,21 +12175,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/aws4": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", - "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", - "dev": true - }, "node_modules/babel-jest": { "version": "30.0.4", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-30.0.4.tgz", @@ -12489,9 +12213,9 @@ } }, "node_modules/babel-loader": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-10.0.0.tgz", - "integrity": "sha512-z8jt+EdS61AMw22nSfoNJAZ0vrtmhPRVi6ghL3rCeRZI8cdNYFiV5xeV3HbE7rlZZNmGH8BVccwWt8/ED0QOHA==", + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-10.1.1.tgz", + "integrity": "sha512-JwKSzk2kjIe7mgPK+/lyZ2QAaJcpahNAdM+hgR2HI8D0OJVkdj8Rl6J3kaLYki9pwF7P2iWnD8qVv80Lq1ABtg==", "dev": true, "license": "MIT", "dependencies": { @@ -12501,8 +12225,17 @@ "node": "^18.20.0 || ^20.10.0 || >=22.0.0" }, "peerDependencies": { - "@babel/core": "^7.12.0", + "@babel/core": "^7.12.0 || ^8.0.0-beta.1", + "@rspack/core": "^1.0.0 || ^2.0.0-0", "webpack": ">=5.61.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } } }, "node_modules/babel-loader/node_modules/find-up": { @@ -12694,13 +12427,6 @@ "@babel/core": "^7.11.0" } }, - "node_modules/backo2": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", - "integrity": "sha512-zj6Z6M7Eq+PBZ7PQxl5NT665MvJdAkzp0f60nAJ+sLaSCBPMwVak5ZegFbgVCzFcCJTKFoMizvM5Ld7+JrRJHA==", - "dev": true, - "license": "MIT" - }, "node_modules/backoff": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/backoff/-/backoff-2.5.0.tgz", @@ -12864,24 +12590,15 @@ } }, "node_modules/basic-ftp": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.1.0.tgz", - "integrity": "sha512-RkaJzeJKDbaDWTIPiJwubyljaEPwpVWkm9Rt5h9Nd6h7tEXTJ3VB4qxdZBioV7JO5yLUaOKwz7vDOzlncUsegw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.2.0.tgz", + "integrity": "sha512-VoMINM2rqJwJgfdHq6RiUudKt2BV+FY5ZFezP/ypmwayk68+NzzAQy4XXLlqsGD4MCzq3DrmNFD/uUmBJuGoXw==", "dev": true, "license": "MIT", "engines": { "node": ">=10.0.0" } }, - "node_modules/bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "dev": true, - "dependencies": { - "tweetnacl": "^0.14.3" - } - }, "node_modules/bcryptjs": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-3.0.3.tgz", @@ -12898,15 +12615,6 @@ "dev": true, "license": "Apache-2.0" }, - "node_modules/big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "dev": true, - "engines": { - "node": "*" - } - }, "node_modules/bignumber.js": { "version": "9.3.1", "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.3.1.tgz", @@ -12928,16 +12636,10 @@ "readable-stream": "^3.4.0" } }, - "node_modules/bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, "node_modules/bn.js": { - "version": "4.12.2", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz", - "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==", + "version": "4.12.3", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.3.tgz", + "integrity": "sha512-fGTi3gxV/23FTYdAoUtLYp6qySe2KE3teyZitipKNRuVYcBkoP/bB3guXN/XVKUe9mxCHXnc9C4ocyz8OmgN0g==", "dev": true, "license": "MIT" }, @@ -12972,9 +12674,9 @@ "dev": true }, "node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", + "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", "dev": true, "license": "MIT", "dependencies": { @@ -13273,12 +12975,6 @@ "cdl": "bin/cdl.js" } }, - "node_modules/caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", - "dev": true - }, "node_modules/chalk": { "version": "5.4.1", "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz", @@ -13335,13 +13031,13 @@ } }, "node_modules/chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", "dev": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "engines": { - "node": ">=10" + "node": ">=18" } }, "node_modules/chrome-trace-event": { @@ -13414,6 +13110,7 @@ "resolved": "https://registry.npmjs.org/cli-highlight/-/cli-highlight-2.1.11.tgz", "integrity": "sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg==", "dev": true, + "license": "ISC", "dependencies": { "chalk": "^4.0.0", "highlight.js": "^10.7.1", @@ -13435,6 +13132,7 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -13450,13 +13148,15 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/cli-highlight/node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true, + "license": "ISC", "engines": { "node": ">=10" } @@ -13466,6 +13166,7 @@ "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, + "license": "MIT", "dependencies": { "cliui": "^7.0.2", "escalade": "^3.1.1", @@ -13533,6 +13234,7 @@ "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, + "license": "ISC", "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", @@ -13735,6 +13437,8 @@ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "dev": true, + "license": "MIT", + "optional": true, "dependencies": { "delayed-stream": "~1.0.0" }, @@ -14065,29 +13769,39 @@ } }, "node_modules/css-loader": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.7.3.tgz", - "integrity": "sha512-qhOH1KlBMnZP8FzRO6YCH9UHXQhVMcEGLyNdb7Hv2cpcmJbW0YrddO+tG1ab5nT41KpHIYGsbeHqxB9xPu1pKQ==", + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-7.1.4.tgz", + "integrity": "sha512-vv3J9tlOl04WjiMvHQI/9tmIrCxVrj6PFbHemBB1iihpeRbi/I4h033eoFIhwxBBqLhI0KYFS7yvynBFhIZfTw==", "dev": true, + "license": "MIT", "dependencies": { "icss-utils": "^5.1.0", - "postcss": "^8.4.19", - "postcss-modules-extract-imports": "^3.0.0", - "postcss-modules-local-by-default": "^4.0.0", - "postcss-modules-scope": "^3.0.0", + "postcss": "^8.4.40", + "postcss-modules-extract-imports": "^3.1.0", + "postcss-modules-local-by-default": "^4.0.5", + "postcss-modules-scope": "^3.2.0", "postcss-modules-values": "^4.0.0", "postcss-value-parser": "^4.2.0", - "semver": "^7.3.8" + "semver": "^7.6.3" }, "engines": { - "node": ">= 12.13.0" + "node": ">= 18.12.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" }, "peerDependencies": { - "webpack": "^5.0.0" + "@rspack/core": "0.x || ^1.0.0 || ^2.0.0-0", + "webpack": "^5.27.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } } }, "node_modules/cssesc": { @@ -14095,6 +13809,7 @@ "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", "dev": true, + "license": "MIT", "bin": { "cssesc": "bin/cssesc" }, @@ -14121,18 +13836,6 @@ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.9.tgz", "integrity": "sha512-rpw6JPxK6Rfg1zLOYCSwle2GFOOsnjmDYDaBwEcwoOg4qlsIVCN789VkBZDJAGi4T07gI4YSutR43t9Zz4Lzuw==" }, - "node_modules/dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "dev": true, - "dependencies": { - "assert-plus": "^1.0.0" - }, - "engines": { - "node": ">=0.10" - } - }, "node_modules/data-uri-to-buffer": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", @@ -14566,17 +14269,6 @@ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, - "node_modules/deepcopy": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/deepcopy/-/deepcopy-2.1.0.tgz", - "integrity": "sha512-8cZeTb1ZKC3bdSCP6XOM1IsTczIO73fdqtwa2B0N15eAz7gmyhQo+mc5gnFuulsgN3vIQYmTgbmQVKalH1dKvQ==", - "deprecated": "No longer maintained. Use structuredClone instead.", - "dev": true, - "license": "MIT", - "dependencies": { - "type-detect": "^4.0.8" - } - }, "node_modules/deepmerge": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", @@ -14656,8 +14348,10 @@ "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "dev": true, + "license": "MIT", + "optional": true, "engines": { "node": ">=0.4.0" } @@ -14873,6 +14567,15 @@ "dev": true, "license": "BSD-3-Clause" }, + "node_modules/diff": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/diff/-/diff-8.0.3.tgz", + "integrity": "sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, "node_modules/diff-match-patch": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/diff-match-patch/-/diff-match-patch-1.0.5.tgz", @@ -14984,16 +14687,6 @@ "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", "license": "MIT" }, - "node_modules/ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "dev": true, - "dependencies": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, "node_modules/ecdsa-sig-formatter": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", @@ -15064,15 +14757,6 @@ "integrity": "sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==", "dev": true }, - "node_modules/emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, "node_modules/enabled": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz", @@ -15294,6 +14978,7 @@ "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=18" }, @@ -15603,9 +15288,9 @@ } }, "node_modules/eslint-plugin-jest": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-29.5.0.tgz", - "integrity": "sha512-DAi9H8xN/TUuNOt+xDP1RqpCJLsSxBb5u1zXSpCyp0VAWGL8MBAg5t7/Dk+76iX7d1LhWu4DDH77IQNUolLDyg==", + "version": "29.15.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-29.15.0.tgz", + "integrity": "sha512-ZCGr7vTH2WSo2hrK5oM2RULFmMruQ7W3cX7YfwoTiPfzTGTFBMmrVIz45jZHd++cGKj/kWf02li/RhTGcANJSA==", "dev": true, "license": "MIT", "dependencies": { @@ -15616,8 +15301,9 @@ }, "peerDependencies": { "@typescript-eslint/eslint-plugin": "^8.0.0", - "eslint": "^8.57.0 || ^9.0.0", - "jest": "*" + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "jest": "*", + "typescript": ">=4.8.4 <6.0.0" }, "peerDependenciesMeta": { "@typescript-eslint/eslint-plugin": { @@ -15625,6 +15311,9 @@ }, "jest": { "optional": true + }, + "typescript": { + "optional": true } } }, @@ -15708,9 +15397,9 @@ } }, "node_modules/eslint-plugin-jest/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.3.tgz", + "integrity": "sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==", "dev": true, "license": "MIT", "dependencies": { @@ -16244,45 +15933,34 @@ } }, "node_modules/expo-server-sdk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/expo-server-sdk/-/expo-server-sdk-4.0.0.tgz", - "integrity": "sha512-zi83XtG2pqyP3gyn1JIRYkydo2i6HU3CYaWo/VvhZG/F29U+QIDv6LBEUsWf4ddZlVE7c9WN1N8Be49rHgO8OQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/expo-server-sdk/-/expo-server-sdk-5.0.0.tgz", + "integrity": "sha512-GEp1XYLU80iS/hdRo3c2n092E8TgTXcHSuw6Lw68dSoWaAgiLPI2R+e5hp5+hGF1TtJZOi2nxtJX63+XA3iz9g==", "dev": true, "license": "MIT", "dependencies": { - "node-fetch": "^2.6.0", "promise-limit": "^2.7.0", - "promise-retry": "^2.0.1" + "promise-retry": "^2.0.1", + "undici": "^7.2.0" }, "engines": { "node": ">=20" } }, - "node_modules/expo-server-sdk/node_modules/node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "node_modules/expo-server-sdk/node_modules/undici": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.24.6.tgz", + "integrity": "sha512-Xi4agocCbRzt0yYMZGMA6ApD7gvtUFaxm4ZmeacWI4cZxaF6C+8I8QfofC20NAePiB/IcvZmzkJ7XPa471AEtA==", "dev": true, "license": "MIT", - "dependencies": { - "whatwg-url": "^5.0.0" - }, "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } + "node": ">=20.18.1" } }, "node_modules/expr-eval-fork": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/expr-eval-fork/-/expr-eval-fork-3.0.1.tgz", - "integrity": "sha512-JRex9aykIt6AqhcQK+u1bFcBy2f+muwJoGCtAZmOC0yrktaCegtH42sLnZdNsD2/Ko9j+3pLWi4nIkNQez02bg==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/expr-eval-fork/-/expr-eval-fork-3.0.3.tgz", + "integrity": "sha512-BhC+hbc5lIVjygr840n5DEkW3MQq7H9o+mc1/N7Z5uIiCFVyESLL5DIE7LNq4CYUNxy+XjA+3jRrL/h0Kt2xcg==", "license": "MIT", "engines": { "node": ">=16.9.0" @@ -16332,11 +16010,14 @@ } }, "node_modules/express-rate-limit": { - "version": "7.5.1", - "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.5.1.tgz", - "integrity": "sha512-7iN8iPMDzOMHPUYllBEsQdWVB6fPDMPqwjBaFrgr4Jgr/+okjvzAy+UHlYYL/Vs0OsOrMkwS6PJDkFlJwoxUnw==", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.3.0.tgz", + "integrity": "sha512-KJzBawY6fB9FiZGdE/0aftepZ91YlaGIrV8vgblRM3J8X+dHx/aiowJWwkx6LIGyuqGiANsjSwwrbb8mifOJ4Q==", "dev": true, "license": "MIT", + "dependencies": { + "ip-address": "10.1.0" + }, "engines": { "node": ">= 16" }, @@ -16347,6 +16028,16 @@ "express": ">= 4.11" } }, + "node_modules/express-rate-limit/node_modules/ip-address": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz", + "integrity": "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, "node_modules/express-session": { "version": "1.18.2", "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.18.2.tgz", @@ -16489,7 +16180,8 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/extract-zip": { "version": "2.0.1", @@ -16605,10 +16297,27 @@ ], "license": "BSD-3-Clause" }, + "node_modules/fast-xml-builder": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.1.4.tgz", + "integrity": "sha512-f2jhpN4Eccy0/Uz9csxh3Nu6q4ErKxf0XIsasomfOihuSUa3/xw6w8dnOtCDgEItQFJG8KyXPzQXzcODDrrbOg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "path-expression-matcher": "^1.1.3" + } + }, "node_modules/fast-xml-parser": { - "version": "5.3.5", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.3.5.tgz", - "integrity": "sha512-JeaA2Vm9ffQKp9VjvfzObuMCjUYAp5WDYhRYL5LrBPY/jUDlUtOvDfot0vKSkB9tuX885BDHjtw4fZadD95wnA==", + "version": "5.5.9", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.5.9.tgz", + "integrity": "sha512-jldvxr1MC6rtiZKgrFnDSvT8xuH+eJqxqOBThUVjYrxssYTo1avZLGql5l0a0BAERR01CadYzZ83kVEkbyDg+g==", "dev": true, "funding": [ { @@ -16619,7 +16328,9 @@ "license": "MIT", "optional": true, "dependencies": { - "strnum": "^2.1.2" + "fast-xml-builder": "^1.1.4", + "path-expression-matcher": "^1.2.0", + "strnum": "^2.2.2" }, "bin": { "fxparser": "src/cli/cli.js" @@ -17104,9 +16815,9 @@ } }, "node_modules/firebase-admin": { - "version": "13.6.0", - "resolved": "https://registry.npmjs.org/firebase-admin/-/firebase-admin-13.6.0.tgz", - "integrity": "sha512-GdPA/t0+Cq8p1JnjFRBmxRxAGvF/kl2yfdhALl38PrRp325YxyQ5aNaHui0XmaKcKiGRFIJ/EgBNWFoDP0onjw==", + "version": "13.6.1", + "resolved": "https://registry.npmjs.org/firebase-admin/-/firebase-admin-13.6.1.tgz", + "integrity": "sha512-Zgc6yPtmPxAZo+FoK6LMG6zpSEsoSK8ifIR+IqF4oWuC3uWZU40OjxgfLTSFcsRlj/k/wD66zNv2UiTRreCNSw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -17130,27 +16841,6 @@ "@google-cloud/storage": "^7.14.0" } }, - "node_modules/firebase-admin/node_modules/@fastify/busboy": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-3.2.0.tgz", - "integrity": "sha512-m9FVDXU3GT2ITSe0UaMA5rU3QkfC/UXtCU8y0gSN/GugTqtVldOBWIB5V6V3sbmenVZUIpU6f+mPEO2+m5iTaA==", - "dev": true, - "license": "MIT" - }, - "node_modules/firebase-admin/node_modules/uuid": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz", - "integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==", - "dev": true, - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], - "license": "MIT", - "bin": { - "uuid": "dist/esm/bin/uuid" - } - }, "node_modules/flat": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", @@ -17175,10 +16865,11 @@ } }, "node_modules/flatted": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", - "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", - "dev": true + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", + "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", + "dev": true, + "license": "ISC" }, "node_modules/flux": { "version": "4.0.1", @@ -17211,9 +16902,9 @@ } }, "node_modules/follow-redirects": { - "version": "1.15.9", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", - "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", "dev": true, "funding": [ { @@ -17274,24 +16965,20 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "dev": true, - "engines": { - "node": "*" - } - }, "node_modules/form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.5.tgz", + "integrity": "sha512-jqdObeR2rxZZbPSGL+3VckHMYtu+f9//KXBsVny6JSX/pa38Fy+bGjuG8eW/H6USNQWhLi8Num++cU2yOCNz4A==", "dev": true, + "license": "MIT", + "optional": true, "dependencies": { "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.35", + "safe-buffer": "^5.2.1" }, "engines": { "node": ">= 0.12" @@ -17307,19 +16994,41 @@ "node": ">= 14.17" } }, - "node_modules/formdata-polyfill": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", - "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", - "dependencies": { - "fetch-blob": "^3.1.2" - }, - "engines": { - "node": ">=12.20.0" - } - }, - "node_modules/forwarded": { - "version": "0.2.0", + "node_modules/form-data/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "optional": true + }, + "node_modules/formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "dependencies": { + "fetch-blob": "^3.1.2" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", "engines": { @@ -17391,32 +17100,6 @@ "node": ">=14.14" } }, - "node_modules/fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "dev": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/fs-minipass/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -17672,9 +17355,9 @@ } }, "node_modules/get-port": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/get-port/-/get-port-7.1.0.tgz", - "integrity": "sha512-QB9NKEeDg3xxVwCCwJQ9+xycaz6pBB6iQ76wiWMl1927n0Kir6alPiP+yuiICLLU4jpMe08dXfpebuQppFA2zw==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-7.2.0.tgz", + "integrity": "sha512-afP4W205ONCuMoPBqcR6PSXnzX35KTcJygfJfcp+QY+uwm3p20p1YczWXhlICIzGMCxYBQcySEcOgsJcrkyobg==", "dev": true, "license": "MIT", "engines": { @@ -17742,15 +17425,6 @@ "node": ">= 14" } }, - "node_modules/getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "dev": true, - "dependencies": { - "assert-plus": "^1.0.0" - } - }, "node_modules/git-log-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/git-log-parser/-/git-log-parser-1.2.1.tgz", @@ -18153,10 +17827,11 @@ } }, "node_modules/handlebars": { - "version": "4.7.8", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", - "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", + "version": "4.7.9", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.9.tgz", + "integrity": "sha512-4E71E0rpOaQuJR2A3xDZ+GM1HyWYv1clR58tC8emQNeQe3RH7MAzSbat+V0wG78LQBo6m6bzSG/L4pBuCsgnUQ==", "dev": true, + "license": "MIT", "dependencies": { "minimist": "^1.2.5", "neo-async": "^2.6.2", @@ -18173,29 +17848,6 @@ "uglify-js": "^3.1.4" } }, - "node_modules/har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "deprecated": "this library is no longer supported", - "dev": true, - "dependencies": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/has-bigints": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", @@ -18304,6 +17956,7 @@ "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": "*" } @@ -18520,21 +18173,6 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "dev": true, - "dependencies": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - }, - "engines": { - "node": ">=0.8", - "npm": ">=1.3.7" - } - }, "node_modules/http2-wrapper": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", @@ -18649,9 +18287,9 @@ } }, "node_modules/immutable": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.4.tgz", - "integrity": "sha512-p6u1bG3YSnINT5RQmx/yRZBpenIl30kVxkTLDyHLIMk0gict704Q9n+thfDI7lTRm9vXdDYutVzXhzcThxTnXA==", + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.5.tgz", + "integrity": "sha512-t7xcm2siw+hlUM68I+UEOK+z84RzmN59as9DZ7P1l0994DKUWV7UXBMQZVxaoMSRQ+PBZbHCOoBt7a2wxOMt+A==", "license": "MIT" }, "node_modules/immutable-devtools": { @@ -19331,12 +18969,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true - }, "node_modules/is-unicode-supported": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", @@ -19431,12 +19063,6 @@ "node": ">=0.10.0" } }, - "node_modules/isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", - "dev": true - }, "node_modules/issue-parser": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/issue-parser/-/issue-parser-7.0.1.tgz", @@ -19519,13 +19145,6 @@ "node": ">=8" } }, - "node_modules/iterall": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/iterall/-/iterall-1.3.0.tgz", - "integrity": "sha512-QZ9qOMdF+QLHxy1QIpUHUU1D5pS2CG2P69LF6L6CPjPYA/XMOmKV3PZpawHoAjHNyB0swdVTRxdYT4tbBbxqwg==", - "dev": true, - "license": "MIT" - }, "node_modules/iterator.prototype": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.5.tgz", @@ -19784,10 +19403,11 @@ } }, "node_modules/jest-config/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.3.tgz", + "integrity": "sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } @@ -20081,9 +19701,9 @@ } }, "node_modules/jest-environment-jsdom/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "dev": true, "license": "MIT", "engines": { @@ -20446,10 +20066,11 @@ } }, "node_modules/jest-runtime/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.3.tgz", + "integrity": "sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } @@ -20596,10 +20217,11 @@ } }, "node_modules/jest-util/node_modules/picomatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", - "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -20750,9 +20372,9 @@ } }, "node_modules/js-beautify/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.3.tgz", + "integrity": "sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==", "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" @@ -20820,12 +20442,6 @@ "js-yaml": "bin/js-yaml.js" } }, - "node_modules/jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "dev": true - }, "node_modules/jsdom": { "version": "26.1.0", "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-26.1.0.tgz", @@ -20995,12 +20611,6 @@ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "dev": true }, - "node_modules/json-schema": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", - "dev": true - }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -21114,21 +20724,6 @@ "safe-buffer": "^5.0.1" } }, - "node_modules/jsprim": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", - "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", - "dev": true, - "dependencies": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.4.0", - "verror": "1.10.0" - }, - "engines": { - "node": ">=0.6.0" - } - }, "node_modules/jssha": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/jssha/-/jssha-3.2.0.tgz", @@ -21346,20 +20941,6 @@ "url": "https://opencollective.com/webpack" } }, - "node_modules/loader-utils": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", - "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", - "dev": true, - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - }, - "engines": { - "node": ">=8.9.0" - } - }, "node_modules/locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -21756,80 +21337,16 @@ } }, "node_modules/marked": { - "version": "15.0.12", - "resolved": "https://registry.npmjs.org/marked/-/marked-15.0.12.tgz", - "integrity": "sha512-8dD6FusOQSrpv9Z1rdNMdlSgQOIP880DHqnohobOmYLElGEqAL/JvxvuxZO16r4HtjTlfPRDC1hbvxC9dPN2nA==", + "version": "17.0.3", + "resolved": "https://registry.npmjs.org/marked/-/marked-17.0.3.tgz", + "integrity": "sha512-jt1v2ObpyOKR8p4XaUJVk3YWRJ5n+i4+rjQopxvV32rSndTJXvIzuUdWWIy/1pFQMkQmvTXawzDNqOH/CUmx6A==", "dev": true, "license": "MIT", "bin": { "marked": "bin/marked.js" }, "engines": { - "node": ">= 18" - } - }, - "node_modules/marked-terminal": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/marked-terminal/-/marked-terminal-7.3.0.tgz", - "integrity": "sha512-t4rBvPsHc57uE/2nJOLmMbZCQ4tgAccAED3ngXQqW6g+TxA488JzJ+FK3lQkzBQOI1mRV/r/Kq+1ZlJ4D0owQw==", - "dev": true, - "dependencies": { - "ansi-escapes": "^7.0.0", - "ansi-regex": "^6.1.0", - "chalk": "^5.4.1", - "cli-highlight": "^2.1.11", - "cli-table3": "^0.6.5", - "node-emoji": "^2.2.0", - "supports-hyperlinks": "^3.1.0" - }, - "engines": { - "node": ">=16.0.0" - }, - "peerDependencies": { - "marked": ">=1 <16" - } - }, - "node_modules/marked-terminal/node_modules/ansi-escapes": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.0.0.tgz", - "integrity": "sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw==", - "dev": true, - "dependencies": { - "environment": "^1.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/marked-terminal/node_modules/ansi-regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/marked-terminal/node_modules/supports-hyperlinks": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.2.0.tgz", - "integrity": "sha512-zFObLMyZeEwzAoKCyu1B91U79K2t7ApXuQfo8OuxwXLDgcKxuwM+YvcbIhm6QWqz7mHUH1TVytR1PwVVjEuMig==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0", - "supports-color": "^7.0.0" - }, - "engines": { - "node": ">=14.18" - }, - "funding": { - "url": "https://github.com/chalk/supports-hyperlinks?sponsor=1" + "node": ">= 20" } }, "node_modules/math-intrinsics": { @@ -22003,9 +21520,9 @@ } }, "node_modules/minimatch/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.3.tgz", + "integrity": "sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==", "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" @@ -22030,30 +21547,16 @@ } }, "node_modules/minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz", + "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==", "dev": true, "license": "MIT", "dependencies": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/minizlib/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" + "minipass": "^7.1.2" }, "engines": { - "node": ">=8" + "node": ">= 18" } }, "node_modules/mitt": { @@ -22132,14 +21635,14 @@ } }, "node_modules/mongodb": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-7.0.0.tgz", - "integrity": "sha512-vG/A5cQrvGGvZm2mTnCSz1LUcbOPl83hfB6bxULKQ8oFZauyox/2xbZOoGNl+64m8VBrETkdGCDBdOsCr3F3jg==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-7.1.0.tgz", + "integrity": "sha512-kMfnKunbolQYwCIyrkxNJFB4Ypy91pYqua5NargS/f8ODNSJxT03ZU3n1JqL4mCzbSih8tvmMEMLpKTT7x5gCg==", "dev": true, "license": "Apache-2.0", "dependencies": { "@mongodb-js/saslprep": "^1.3.0", - "bson": "^7.0.0", + "bson": "^7.1.1", "mongodb-connection-string-url": "^7.0.0" }, "engines": { @@ -22230,9 +21733,9 @@ } }, "node_modules/mongodb-download-url": { - "version": "1.8.7", - "resolved": "https://registry.npmjs.org/mongodb-download-url/-/mongodb-download-url-1.8.7.tgz", - "integrity": "sha512-BYQtlrz5vsSDyi2eO8q/CM32YzxLmQDW50IU4XSN50s5lvFE141qEw/8nzZZr/K6RWkpoY1tUWCK59pHRNscLw==", + "version": "1.8.8", + "resolved": "https://registry.npmjs.org/mongodb-download-url/-/mongodb-download-url-1.8.8.tgz", + "integrity": "sha512-Mwcx/JogIo39HLDWrhpVwktdz5RwesUWNBuZDVHU5C2d03yIT4Y+Mv5MsqEsupxOLdGxCLMnnTJ3vOGU2A8p4w==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -22267,9 +21770,9 @@ } }, "node_modules/mongodb-runner": { - "version": "6.6.1", - "resolved": "https://registry.npmjs.org/mongodb-runner/-/mongodb-runner-6.6.1.tgz", - "integrity": "sha512-drm5qGWERJEgX6sh+F3h9TcNw8VLCzMx8JjxyD8NaL8Chsy0DWOfUekqe3s/fqgImZ0kX2CC2p+9T0uqAhHBow==", + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/mongodb-runner/-/mongodb-runner-6.7.1.tgz", + "integrity": "sha512-bYCk1EC0wp4boNyZYJ0Prk6Ye5Mq4ibANzL2RrI2vglSCunjaMfaMIFVJl7isyABwAqJah2RT8va/q8QKa26qQ==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -22315,6 +21818,7 @@ "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", "dev": true, + "license": "MIT", "dependencies": { "any-promise": "^1.0.0", "object-assign": "^4.0.1", @@ -22545,9 +22049,9 @@ } }, "node_modules/npm": { - "version": "10.9.3", - "resolved": "https://registry.npmjs.org/npm/-/npm-10.9.3.tgz", - "integrity": "sha512-6Eh1u5Q+kIVXeA8e7l2c/HpnFFcwrkt37xDMujD5be1gloWa9p6j3Fsv3mByXXmqJHy+2cElRMML8opNT7xIJQ==", + "version": "10.9.8", + "resolved": "https://registry.npmjs.org/npm/-/npm-10.9.8.tgz", + "integrity": "sha512-fYwb6ODSmHkqrJQQaCxY3M2lPf/mpgC7ik0HSzzIwG5CGtabRp4bNqikatvCoT42b5INQSqudVH0R7yVmC9hVg==", "bundleDependencies": [ "@isaacs/string-locale-compare", "@npmcli/arborist", @@ -22629,24 +22133,24 @@ ], "dependencies": { "@isaacs/string-locale-compare": "^1.1.0", - "@npmcli/arborist": "^8.0.1", + "@npmcli/arborist": "^8.0.5", "@npmcli/config": "^9.0.0", "@npmcli/fs": "^4.0.0", "@npmcli/map-workspaces": "^4.0.2", "@npmcli/package-json": "^6.2.0", - "@npmcli/promise-spawn": "^8.0.2", + "@npmcli/promise-spawn": "^8.0.3", "@npmcli/redact": "^3.2.2", "@npmcli/run-script": "^9.1.0", "@sigstore/tuf": "^3.1.1", "abbrev": "^3.0.1", "archy": "~1.0.0", "cacache": "^19.0.1", - "chalk": "^5.4.1", - "ci-info": "^4.2.0", + "chalk": "^5.6.2", + "ci-info": "^4.4.0", "cli-columns": "^4.0.0", "fastest-levenshtein": "^1.0.16", "fs-minipass": "^3.0.3", - "glob": "^10.4.5", + "glob": "^10.5.0", "graceful-fs": "^4.2.11", "hosted-git-info": "^8.1.0", "ini": "^5.0.0", @@ -22654,46 +22158,46 @@ "is-cidr": "^5.1.1", "json-parse-even-better-errors": "^4.0.0", "libnpmaccess": "^9.0.0", - "libnpmdiff": "^7.0.1", - "libnpmexec": "^9.0.1", - "libnpmfund": "^6.0.1", + "libnpmdiff": "^7.0.5", + "libnpmexec": "^9.0.5", + "libnpmfund": "^6.0.5", "libnpmhook": "^11.0.0", "libnpmorg": "^7.0.0", - "libnpmpack": "^8.0.1", - "libnpmpublish": "^10.0.1", + "libnpmpack": "^8.0.5", + "libnpmpublish": "^10.0.2", "libnpmsearch": "^8.0.0", "libnpmteam": "^7.0.0", "libnpmversion": "^7.0.0", "make-fetch-happen": "^14.0.3", - "minimatch": "^9.0.5", - "minipass": "^7.1.1", + "minimatch": "^9.0.9", + "minipass": "^7.1.3", "minipass-pipeline": "^1.2.4", "ms": "^2.1.2", - "node-gyp": "^11.2.0", + "node-gyp": "^11.5.0", "nopt": "^8.1.0", - "normalize-package-data": "^7.0.0", + "normalize-package-data": "^7.0.1", "npm-audit-report": "^6.0.0", - "npm-install-checks": "^7.1.1", + "npm-install-checks": "^7.1.2", "npm-package-arg": "^12.0.2", "npm-pick-manifest": "^10.0.0", "npm-profile": "^11.0.1", "npm-registry-fetch": "^18.0.2", "npm-user-validate": "^3.0.0", - "p-map": "^7.0.3", + "p-map": "^7.0.4", "pacote": "^19.0.1", "parse-conflict-json": "^4.0.0", "proc-log": "^5.0.0", "qrcode-terminal": "^0.12.0", "read": "^4.1.0", - "semver": "^7.7.2", + "semver": "^7.7.4", "spdx-expression-parse": "^4.0.0", "ssri": "^12.0.0", "supports-color": "^9.4.0", - "tar": "^6.2.1", + "tar": "^7.5.11", "text-table": "~0.2.0", "tiny-relative-date": "^1.3.0", "treeverse": "^3.0.0", - "validate-npm-package-name": "^6.0.1", + "validate-npm-package-name": "^6.0.2", "which": "^5.0.0", "write-file-atomic": "^6.0.0" }, @@ -22735,7 +22239,7 @@ } }, "node_modules/npm/node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.1.0", + "version": "6.2.2", "dev": true, "inBundle": true, "license": "MIT", @@ -22770,12 +22274,12 @@ } }, "node_modules/npm/node_modules/@isaacs/cliui/node_modules/strip-ansi": { - "version": "7.1.0", + "version": "7.2.0", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "ansi-regex": "^6.0.1" + "ansi-regex": "^6.2.2" }, "engines": { "node": ">=12" @@ -22819,7 +22323,7 @@ } }, "node_modules/npm/node_modules/@npmcli/arborist": { - "version": "8.0.1", + "version": "8.0.5", "dev": true, "inBundle": true, "license": "ISC", @@ -22854,6 +22358,7 @@ "proggy": "^3.0.0", "promise-all-reject-late": "^1.0.0", "promise-call-limit": "^3.0.1", + "promise-retry": "^2.0.1", "read-package-json-fast": "^4.0.0", "semver": "^7.3.7", "ssri": "^12.0.0", @@ -22965,7 +22470,7 @@ } }, "node_modules/npm/node_modules/@npmcli/metavuln-calculator/node_modules/pacote": { - "version": "20.0.0", + "version": "20.0.1", "dev": true, "inBundle": true, "license": "ISC", @@ -22986,7 +22491,7 @@ "promise-retry": "^2.0.1", "sigstore": "^3.0.0", "ssri": "^12.0.0", - "tar": "^6.1.11" + "tar": "^7.5.10" }, "bin": { "pacote": "bin/index.js" @@ -23032,7 +22537,7 @@ } }, "node_modules/npm/node_modules/@npmcli/promise-spawn": { - "version": "8.0.2", + "version": "8.0.3", "dev": true, "inBundle": true, "license": "ISC", @@ -23091,39 +22596,91 @@ "node": ">=14" } }, - "node_modules/npm/node_modules/@sigstore/protobuf-specs": { - "version": "0.4.3", + "node_modules/npm/node_modules/@sigstore/bundle": { + "version": "3.1.0", "dev": true, "inBundle": true, "license": "Apache-2.0", + "dependencies": { + "@sigstore/protobuf-specs": "^0.4.0" + }, "engines": { "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/npm/node_modules/@sigstore/tuf": { - "version": "3.1.1", + "node_modules/npm/node_modules/@sigstore/core": { + "version": "2.0.0", "dev": true, "inBundle": true, "license": "Apache-2.0", - "dependencies": { - "@sigstore/protobuf-specs": "^0.4.1", - "tuf-js": "^3.0.1" - }, "engines": { "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/npm/node_modules/@tufjs/canonical-json": { - "version": "2.0.0", + "node_modules/npm/node_modules/@sigstore/protobuf-specs": { + "version": "0.4.3", "dev": true, "inBundle": true, - "license": "MIT", + "license": "Apache-2.0", "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/npm/node_modules/abbrev": { - "version": "3.0.1", + "node_modules/npm/node_modules/@sigstore/sign": { + "version": "3.1.0", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/bundle": "^3.1.0", + "@sigstore/core": "^2.0.0", + "@sigstore/protobuf-specs": "^0.4.0", + "make-fetch-happen": "^14.0.2", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/@sigstore/tuf": { + "version": "3.1.1", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/protobuf-specs": "^0.4.1", + "tuf-js": "^3.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/@sigstore/verify": { + "version": "2.1.1", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/bundle": "^3.1.0", + "@sigstore/core": "^2.0.0", + "@sigstore/protobuf-specs": "^0.4.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/@tufjs/canonical-json": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/abbrev": { + "version": "3.0.1", "dev": true, "inBundle": true, "license": "ISC", @@ -23132,7 +22689,7 @@ } }, "node_modules/npm/node_modules/agent-base": { - "version": "7.1.3", + "version": "7.1.4", "dev": true, "inBundle": true, "license": "MIT", @@ -23150,7 +22707,7 @@ } }, "node_modules/npm/node_modules/ansi-styles": { - "version": "6.2.1", + "version": "6.2.3", "dev": true, "inBundle": true, "license": "MIT", @@ -23162,7 +22719,7 @@ } }, "node_modules/npm/node_modules/aproba": { - "version": "2.0.0", + "version": "2.1.0", "dev": true, "inBundle": true, "license": "ISC" @@ -23239,58 +22796,8 @@ "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/npm/node_modules/cacache/node_modules/chownr": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=18" - } - }, - "node_modules/npm/node_modules/cacache/node_modules/mkdirp": { - "version": "3.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "bin": { - "mkdirp": "dist/cjs/src/bin.js" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/npm/node_modules/cacache/node_modules/tar": { - "version": "7.4.3", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@isaacs/fs-minipass": "^4.0.0", - "chownr": "^3.0.0", - "minipass": "^7.1.2", - "minizlib": "^3.0.1", - "mkdirp": "^3.0.1", - "yallist": "^5.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/npm/node_modules/cacache/node_modules/yallist": { - "version": "5.0.0", - "dev": true, - "inBundle": true, - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=18" - } - }, "node_modules/npm/node_modules/chalk": { - "version": "5.4.1", + "version": "5.6.2", "dev": true, "inBundle": true, "license": "MIT", @@ -23302,16 +22809,16 @@ } }, "node_modules/npm/node_modules/chownr": { - "version": "2.0.0", + "version": "3.0.0", "dev": true, "inBundle": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "engines": { - "node": ">=10" + "node": ">=18" } }, "node_modules/npm/node_modules/ci-info": { - "version": "4.2.0", + "version": "4.4.0", "dev": true, "funding": [ { @@ -23425,7 +22932,7 @@ } }, "node_modules/npm/node_modules/debug": { - "version": "4.4.1", + "version": "4.4.3", "dev": true, "inBundle": true, "license": "MIT", @@ -23442,7 +22949,7 @@ } }, "node_modules/npm/node_modules/diff": { - "version": "5.2.0", + "version": "5.2.2", "dev": true, "inBundle": true, "license": "BSD-3-Clause", @@ -23488,7 +22995,7 @@ "license": "MIT" }, "node_modules/npm/node_modules/exponential-backoff": { - "version": "3.1.2", + "version": "3.1.3", "dev": true, "inBundle": true, "license": "Apache-2.0" @@ -23502,6 +23009,23 @@ "node": ">= 4.9.1" } }, + "node_modules/npm/node_modules/fdir": { + "version": "6.5.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, "node_modules/npm/node_modules/foreground-child": { "version": "3.3.1", "dev": true, @@ -23531,7 +23055,7 @@ } }, "node_modules/npm/node_modules/glob": { - "version": "10.4.5", + "version": "10.5.0", "dev": true, "inBundle": true, "license": "ISC", @@ -23662,14 +23186,10 @@ } }, "node_modules/npm/node_modules/ip-address": { - "version": "9.0.5", + "version": "10.1.0", "dev": true, "inBundle": true, "license": "MIT", - "dependencies": { - "jsbn": "1.1.0", - "sprintf-js": "^1.1.3" - }, "engines": { "node": ">= 12" } @@ -23728,12 +23248,6 @@ "@pkgjs/parseargs": "^0.11.0" } }, - "node_modules/npm/node_modules/jsbn": { - "version": "1.1.0", - "dev": true, - "inBundle": true, - "license": "MIT" - }, "node_modules/npm/node_modules/json-parse-even-better-errors": { "version": "4.0.0", "dev": true, @@ -23787,31 +23301,31 @@ } }, "node_modules/npm/node_modules/libnpmdiff": { - "version": "7.0.1", + "version": "7.0.5", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/arborist": "^8.0.1", + "@npmcli/arborist": "^8.0.5", "@npmcli/installed-package-contents": "^3.0.0", "binary-extensions": "^2.3.0", "diff": "^5.1.0", "minimatch": "^9.0.4", "npm-package-arg": "^12.0.0", "pacote": "^19.0.0", - "tar": "^6.2.1" + "tar": "^7.5.11" }, "engines": { "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/libnpmexec": { - "version": "9.0.1", + "version": "9.0.5", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/arborist": "^8.0.1", + "@npmcli/arborist": "^8.0.5", "@npmcli/run-script": "^9.0.1", "ci-info": "^4.0.0", "npm-package-arg": "^12.0.0", @@ -23827,12 +23341,12 @@ } }, "node_modules/npm/node_modules/libnpmfund": { - "version": "6.0.1", + "version": "6.0.5", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/arborist": "^8.0.1" + "@npmcli/arborist": "^8.0.5" }, "engines": { "node": "^18.17.0 || >=20.5.0" @@ -23865,12 +23379,12 @@ } }, "node_modules/npm/node_modules/libnpmpack": { - "version": "8.0.1", + "version": "8.0.5", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/arborist": "^8.0.1", + "@npmcli/arborist": "^8.0.5", "@npmcli/run-script": "^9.0.1", "npm-package-arg": "^12.0.0", "pacote": "^19.0.0" @@ -23880,7 +23394,7 @@ } }, "node_modules/npm/node_modules/libnpmpublish": { - "version": "10.0.1", + "version": "10.0.2", "dev": true, "inBundle": true, "license": "ISC", @@ -23967,22 +23481,13 @@ "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/npm/node_modules/make-fetch-happen/node_modules/negotiator": { - "version": "1.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, "node_modules/npm/node_modules/minimatch": { - "version": "9.0.5", + "version": "9.0.9", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^2.0.2" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -23992,10 +23497,10 @@ } }, "node_modules/npm/node_modules/minipass": { - "version": "7.1.2", + "version": "7.1.3", "dev": true, "inBundle": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "engines": { "node": ">=16 || 14 >=14.17" } @@ -24053,6 +23558,12 @@ "node": ">=8" } }, + "node_modules/npm/node_modules/minipass-flush/node_modules/yallist": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, "node_modules/npm/node_modules/minipass-pipeline": { "version": "1.2.4", "dev": true, @@ -24077,6 +23588,12 @@ "node": ">=8" } }, + "node_modules/npm/node_modules/minipass-pipeline/node_modules/yallist": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, "node_modules/npm/node_modules/minipass-sized": { "version": "1.0.3", "dev": true, @@ -24101,8 +23618,14 @@ "node": ">=8" } }, + "node_modules/npm/node_modules/minipass-sized/node_modules/yallist": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, "node_modules/npm/node_modules/minizlib": { - "version": "3.0.2", + "version": "3.1.0", "dev": true, "inBundle": true, "license": "MIT", @@ -24113,18 +23636,6 @@ "node": ">= 18" } }, - "node_modules/npm/node_modules/mkdirp": { - "version": "1.0.4", - "dev": true, - "inBundle": true, - "license": "MIT", - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/npm/node_modules/ms": { "version": "2.1.3", "dev": true, @@ -24140,8 +23651,17 @@ "node": "^18.17.0 || >=20.5.0" } }, + "node_modules/npm/node_modules/negotiator": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/npm/node_modules/node-gyp": { - "version": "11.2.0", + "version": "11.5.0", "dev": true, "inBundle": true, "license": "MIT", @@ -24164,56 +23684,6 @@ "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/npm/node_modules/node-gyp/node_modules/chownr": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=18" - } - }, - "node_modules/npm/node_modules/node-gyp/node_modules/mkdirp": { - "version": "3.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "bin": { - "mkdirp": "dist/cjs/src/bin.js" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/npm/node_modules/node-gyp/node_modules/tar": { - "version": "7.4.3", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@isaacs/fs-minipass": "^4.0.0", - "chownr": "^3.0.0", - "minipass": "^7.1.2", - "minizlib": "^3.0.1", - "mkdirp": "^3.0.1", - "yallist": "^5.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/npm/node_modules/node-gyp/node_modules/yallist": { - "version": "5.0.0", - "dev": true, - "inBundle": true, - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=18" - } - }, "node_modules/npm/node_modules/nopt": { "version": "8.1.0", "dev": true, @@ -24230,7 +23700,7 @@ } }, "node_modules/npm/node_modules/normalize-package-data": { - "version": "7.0.0", + "version": "7.0.1", "dev": true, "inBundle": true, "license": "BSD-2-Clause", @@ -24265,7 +23735,7 @@ } }, "node_modules/npm/node_modules/npm-install-checks": { - "version": "7.1.1", + "version": "7.1.2", "dev": true, "inBundle": true, "license": "BSD-2-Clause", @@ -24369,7 +23839,7 @@ } }, "node_modules/npm/node_modules/p-map": { - "version": "7.0.3", + "version": "7.0.4", "dev": true, "inBundle": true, "license": "MIT", @@ -24387,7 +23857,7 @@ "license": "BlueOak-1.0.0" }, "node_modules/npm/node_modules/pacote": { - "version": "19.0.1", + "version": "19.0.2", "dev": true, "inBundle": true, "license": "ISC", @@ -24408,7 +23878,7 @@ "promise-retry": "^2.0.1", "sigstore": "^3.0.0", "ssri": "^12.0.0", - "tar": "^6.1.11" + "tar": "^7.5.10" }, "bin": { "pacote": "bin/index.js" @@ -24456,8 +23926,20 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/npm/node_modules/picomatch": { + "version": "4.0.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/npm/node_modules/postcss-selector-parser": { - "version": "7.1.0", + "version": "7.1.1", "dev": true, "inBundle": true, "license": "MIT", @@ -24589,7 +24071,7 @@ "optional": true }, "node_modules/npm/node_modules/semver": { - "version": "7.7.2", + "version": "7.7.4", "dev": true, "inBundle": true, "license": "ISC", @@ -24650,58 +24132,6 @@ "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/npm/node_modules/sigstore/node_modules/@sigstore/bundle": { - "version": "3.1.0", - "dev": true, - "inBundle": true, - "license": "Apache-2.0", - "dependencies": { - "@sigstore/protobuf-specs": "^0.4.0" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/sigstore/node_modules/@sigstore/core": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "Apache-2.0", - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/sigstore/node_modules/@sigstore/sign": { - "version": "3.1.0", - "dev": true, - "inBundle": true, - "license": "Apache-2.0", - "dependencies": { - "@sigstore/bundle": "^3.1.0", - "@sigstore/core": "^2.0.0", - "@sigstore/protobuf-specs": "^0.4.0", - "make-fetch-happen": "^14.0.2", - "proc-log": "^5.0.0", - "promise-retry": "^2.0.1" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/sigstore/node_modules/@sigstore/verify": { - "version": "2.1.1", - "dev": true, - "inBundle": true, - "license": "Apache-2.0", - "dependencies": { - "@sigstore/bundle": "^3.1.0", - "@sigstore/core": "^2.0.0", - "@sigstore/protobuf-specs": "^0.4.1" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, "node_modules/npm/node_modules/smart-buffer": { "version": "4.2.0", "dev": true, @@ -24713,12 +24143,12 @@ } }, "node_modules/npm/node_modules/socks": { - "version": "2.8.5", + "version": "2.8.7", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "ip-address": "^9.0.5", + "ip-address": "^10.0.1", "smart-buffer": "^4.2.0" }, "engines": { @@ -24777,17 +24207,11 @@ } }, "node_modules/npm/node_modules/spdx-license-ids": { - "version": "3.0.21", + "version": "3.0.23", "dev": true, "inBundle": true, "license": "CC0-1.0" }, - "node_modules/npm/node_modules/sprintf-js": { - "version": "1.1.3", - "dev": true, - "inBundle": true, - "license": "BSD-3-Clause" - }, "node_modules/npm/node_modules/ssri": { "version": "12.0.0", "dev": true, @@ -24866,79 +24290,20 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/npm/node_modules/tar": { - "version": "6.2.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^5.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/npm/node_modules/tar/node_modules/fs-minipass": { - "version": "2.1.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/npm/node_modules/tar/node_modules/fs-minipass/node_modules/minipass": { - "version": "3.3.6", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/tar/node_modules/minipass": { - "version": "5.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/tar/node_modules/minizlib": { - "version": "2.1.2", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/npm/node_modules/tar/node_modules/minizlib/node_modules/minipass": { - "version": "3.3.6", + "node_modules/npm/node_modules/tar": { + "version": "7.5.11", "dev": true, "inBundle": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "dependencies": { - "yallist": "^4.0.0" + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.1.0", + "yallist": "^5.0.0" }, "engines": { - "node": ">=8" + "node": ">=18" } }, "node_modules/npm/node_modules/text-table": { @@ -24954,13 +24319,13 @@ "license": "MIT" }, "node_modules/npm/node_modules/tinyglobby": { - "version": "0.2.14", + "version": "0.2.15", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "fdir": "^6.4.4", - "picomatch": "^4.0.2" + "fdir": "^6.5.0", + "picomatch": "^4.0.3" }, "engines": { "node": ">=12.0.0" @@ -24969,32 +24334,6 @@ "url": "https://github.com/sponsors/SuperchupuDev" } }, - "node_modules/npm/node_modules/tinyglobby/node_modules/fdir": { - "version": "6.4.6", - "dev": true, - "inBundle": true, - "license": "MIT", - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } - } - }, - "node_modules/npm/node_modules/tinyglobby/node_modules/picomatch": { - "version": "4.0.2", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/npm/node_modules/treeverse": { "version": "3.0.0", "dev": true, @@ -25005,14 +24344,14 @@ } }, "node_modules/npm/node_modules/tuf-js": { - "version": "3.0.1", + "version": "3.1.0", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { "@tufjs/models": "3.0.1", - "debug": "^4.3.6", - "make-fetch-happen": "^14.0.1" + "debug": "^4.4.1", + "make-fetch-happen": "^14.0.3" }, "engines": { "node": "^18.17.0 || >=20.5.0" @@ -25082,7 +24421,7 @@ } }, "node_modules/npm/node_modules/validate-npm-package-name": { - "version": "6.0.1", + "version": "6.0.2", "dev": true, "inBundle": true, "license": "ISC", @@ -25112,12 +24451,12 @@ } }, "node_modules/npm/node_modules/which/node_modules/isexe": { - "version": "3.1.1", + "version": "3.1.5", "dev": true, "inBundle": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "engines": { - "node": ">=16" + "node": ">=18" } }, "node_modules/npm/node_modules/wrap-ansi": { @@ -25171,7 +24510,7 @@ } }, "node_modules/npm/node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "6.1.0", + "version": "6.2.2", "dev": true, "inBundle": true, "license": "MIT", @@ -25206,12 +24545,12 @@ } }, "node_modules/npm/node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "7.1.0", + "version": "7.2.0", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "ansi-regex": "^6.0.1" + "ansi-regex": "^6.2.2" }, "engines": { "node": ">=12" @@ -25234,10 +24573,13 @@ } }, "node_modules/npm/node_modules/yallist": { - "version": "4.0.0", + "version": "5.0.0", "dev": true, "inBundle": true, - "license": "ISC" + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } }, "node_modules/npmlog": { "version": "7.0.1", @@ -25256,44 +24598,6 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/null-loader": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/null-loader/-/null-loader-4.0.1.tgz", - "integrity": "sha512-pxqVbi4U6N26lq+LmgIbB5XATP0VdZKOG25DhHi8btMmJJefGArFyDg1yc4U3hWCJbMqSrw0qyrz1UQX+qYXqg==", - "dev": true, - "dependencies": { - "loader-utils": "^2.0.0", - "schema-utils": "^3.0.0" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^4.0.0 || ^5.0.0" - } - }, - "node_modules/null-loader/node_modules/schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, "node_modules/nullthrows": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz", @@ -25306,15 +24610,6 @@ "dev": true, "license": "MIT" }, - "node_modules/oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "dev": true, - "engines": { - "node": "*" - } - }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -25745,19 +25040,20 @@ } }, "node_modules/parse": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/parse/-/parse-7.1.2.tgz", - "integrity": "sha512-PXcPZDElBni06WPMxg0e6XmvgYBu3v39pRezZDbsomi8y9k1uNEDO/uICIqndw8jdES2ZfVpHp0TQoar2SObHQ==", + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/parse/-/parse-8.5.0.tgz", + "integrity": "sha512-X9gI4Yjbi9LPMPnCtKL4h0Nxe1aSCFMPWcB1zbu11qU/Be3eVSB5I5IMBunTuWlVz6Wchu3dtM5jl/1aBZ9wiQ==", "license": "Apache-2.0", "dependencies": { - "@babel/runtime-corejs3": "7.28.4", + "@babel/runtime": "7.28.6", + "@babel/runtime-corejs3": "7.29.0", "crypto-js": "4.2.0", "idb-keyval": "6.2.2", "react-native-crypto-js": "1.0.0", - "ws": "8.18.3" + "ws": "8.19.0" }, "engines": { - "node": "18 || 19 || 20 || 22 || 24" + "node": ">=20.19.0 <21 || >=22.12.0 <23 || >=24.1.0 <25" } }, "node_modules/parse-json": { @@ -25788,28 +25084,27 @@ } }, "node_modules/parse-server": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/parse-server/-/parse-server-9.2.0.tgz", - "integrity": "sha512-YAjVkzDqmTLlkfHdI5Tu+HegheOLSE2uzWQSaTl6KSC9Ksck3cQVCRIarQdijWZoYml5rwwqyHak3v3hgOazsg==", + "version": "9.7.0", + "resolved": "https://registry.npmjs.org/parse-server/-/parse-server-9.7.0.tgz", + "integrity": "sha512-QY5h5dAJvIG3tAcPfCGoDGKFDKIGhbNZ20rPzzhbRvWcX5n2rrE7KWKrL1Sk9aIuLKS2VAN4Muk7p5zTDP/dfQ==", "dev": true, "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { - "@apollo/server": "5.4.0", + "@apollo/server": "5.5.0", "@as-integrations/express5": "1.1.2", "@graphql-tools/merge": "9.0.24", "@graphql-tools/schema": "10.0.23", "@graphql-tools/utils": "10.8.6", "@parse/fs-files-adapter": "3.0.0", - "@parse/push-adapter": "8.2.0", + "@parse/push-adapter": "8.3.1", "bcryptjs": "3.0.3", - "commander": "14.0.2", + "commander": "14.0.3", "cors": "2.8.6", - "deepcopy": "2.1.0", "express": "5.2.1", - "express-rate-limit": "7.5.1", - "follow-redirects": "1.15.9", - "graphql": "16.11.0", + "express-rate-limit": "8.3.0", + "follow-redirects": "1.15.11", + "graphql": "16.13.2", "graphql-list-fields": "2.0.4", "graphql-relay": "0.10.2", "graphql-upload": "15.0.2", @@ -25818,26 +25113,25 @@ "jwks-rsa": "3.2.0", "ldapjs": "3.0.7", "lodash": "4.17.23", - "lru-cache": "10.4.0", + "lru-cache": "11.2.7", "mime": "4.0.7", - "mongodb": "7.0.0", + "mongodb": "7.1.0", "mustache": "4.2.0", "otpauth": "9.4.0", - "parse": "8.0.3", - "path-to-regexp": "8.3.0", - "pg-monitor": "3.0.0", + "parse": "8.5.0", + "path-to-regexp": "8.4.0", + "pg-monitor": "3.1.0", "pg-promise": "12.6.0", "pluralize": "8.0.0", "punycode": "2.3.1", - "rate-limit-redis": "4.2.0", - "redis": "5.10.0", + "rate-limit-redis": "4.3.1", + "redis": "5.11.0", "semver": "7.7.2", - "subscriptions-transport-ws": "0.11.0", "tv4": "1.3.0", "uuid": "11.1.0", "winston": "3.19.0", "winston-daily-rotate-file": "5.0.0", - "ws": "8.18.2" + "ws": "8.20.0" }, "bin": { "parse-server": "bin/parse-server" @@ -25867,23 +25161,10 @@ "express": "^5.0.0" } }, - "node_modules/parse-server/node_modules/@babel/runtime-corejs3": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.28.6.tgz", - "integrity": "sha512-kz2fAQ5UzjV7X7D3ySxmj3vRq89dTpqOZWv76Z6pNPztkwb/0Yj1Mtx1xFrYj6mbIHysxtBot8J4o0JLCblcFw==", - "dev": true, - "license": "MIT", - "dependencies": { - "core-js-pure": "^3.43.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/parse-server/node_modules/commander": { - "version": "14.0.2", - "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.2.tgz", - "integrity": "sha512-TywoWNNRbhoD0BXs1P3ZEScW8W5iKrnbithIl0YH+uCmBd0QpPOA8yc82DS3BIE5Ma6FnBVUsJ7wVUDz4dvOWQ==", + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz", + "integrity": "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==", "dev": true, "license": "MIT", "engines": { @@ -25891,9 +25172,9 @@ } }, "node_modules/parse-server/node_modules/graphql": { - "version": "16.11.0", - "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.11.0.tgz", - "integrity": "sha512-mS1lbMsxgQj6hge1XZ6p7GPhbrtFwUFYi3wRzXAC/FmYnyXMTvvI3td3rjmQ2u8ewXueaSvRPWaEcgVVOT9Jnw==", + "version": "16.13.2", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.13.2.tgz", + "integrity": "sha512-5bJ+nf/UCpAjHM8i06fl7eLyVC9iuNAjm9qzkiu2ZGhM0VscSvS6WDPfAwkdkBuoXGM9FJSbKl6wylMwP9Ktig==", "dev": true, "license": "MIT", "engines": { @@ -25901,13 +25182,13 @@ } }, "node_modules/parse-server/node_modules/lru-cache": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.0.tgz", - "integrity": "sha512-bfJaPTuEiTYBu+ulDaeQ0F+uLmlfFkMgXj4cbwfuMSjgObGMzb55FMMbDvbRU0fAHZ4sLGkz2mKwcMg8Dvm8Ww==", + "version": "11.2.7", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.7.tgz", + "integrity": "sha512-aY/R+aEsRelme17KGQa/1ZSIpLpNYYrhcrepKTZgE+W3WM16YMCaPwOHLHsmopZHELU0Ojin1lPVxKR0MihncA==", "dev": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "engines": { - "node": ">=18" + "node": "20 || >=22" } }, "node_modules/parse-server/node_modules/mime": { @@ -25939,57 +25220,6 @@ "url": "https://github.com/hectorm/otpauth?sponsor=1" } }, - "node_modules/parse-server/node_modules/parse": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/parse/-/parse-8.0.3.tgz", - "integrity": "sha512-WQPrnfnXy6/p25OFD6qOAVK9hIhhU882Nw1AW5RjAJbO2G7YqChJxBgL94aexsaTnP9ajVzjGISSQ+mESrkMIA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@babel/runtime": "7.28.6", - "@babel/runtime-corejs3": "7.28.6", - "crypto-js": "4.2.0", - "idb-keyval": "6.2.2", - "react-native-crypto-js": "1.0.0", - "ws": "8.19.0" - }, - "engines": { - "node": ">=20.19.0 <21 || >=22.12.0 <23 || >=24.1.0 <25" - } - }, - "node_modules/parse-server/node_modules/parse/node_modules/ws": { - "version": "8.19.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz", - "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/parse-server/node_modules/path-to-regexp": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz", - "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==", - "dev": true, - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, "node_modules/parse-server/node_modules/semver": { "version": "7.7.2", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", @@ -26003,24 +25233,10 @@ "node": ">=10" } }, - "node_modules/parse-server/node_modules/uuid": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz", - "integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==", - "dev": true, - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], - "license": "MIT", - "bin": { - "uuid": "dist/esm/bin/uuid" - } - }, "node_modules/parse-server/node_modules/ws": { - "version": "8.18.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.2.tgz", - "integrity": "sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==", + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.20.0.tgz", + "integrity": "sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==", "dev": true, "license": "MIT", "engines": { @@ -26039,37 +25255,25 @@ } } }, - "node_modules/parse/node_modules/@babel/runtime-corejs3": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.28.4.tgz", - "integrity": "sha512-h7iEYiW4HebClDEhtvFObtPmIvrd1SSfpI9EhOeKk4CtIK/ngBWFpuhCzhdmRKtg71ylcue+9I6dv54XYO1epQ==", + "node_modules/parse/node_modules/@babel/runtime": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.6.tgz", + "integrity": "sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==", "license": "MIT", - "dependencies": { - "core-js-pure": "^3.43.0" - }, "engines": { "node": ">=6.9.0" } }, - "node_modules/parse/node_modules/ws": { - "version": "8.18.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", - "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", + "node_modules/parse/node_modules/@babel/runtime-corejs3": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.29.0.tgz", + "integrity": "sha512-TgUkdp71C9pIbBcHudc+gXZnihEDOjUAmXO1VO4HHGES7QLZcShR0stfKIxLSNIYx2fqhmJChOjm/wkF8wv4gA==", "license": "MIT", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" + "dependencies": { + "core-js-pure": "^3.48.0" }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } + "engines": { + "node": ">=6.9.0" } }, "node_modules/parse5": { @@ -26090,6 +25294,7 @@ "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz", "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==", "dev": true, + "license": "MIT", "dependencies": { "parse5": "^6.0.1" } @@ -26098,7 +25303,8 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/parse5/node_modules/entities": { "version": "6.0.1", @@ -26167,6 +25373,23 @@ "node": ">=8" } }, + "node_modules/path-expression-matcher": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/path-expression-matcher/-/path-expression-matcher-1.2.0.tgz", + "integrity": "sha512-DwmPWeFn+tq7TiyJ2CxezCAirXjFxvaiD03npak3cRjlP9+OjTmSy1EpIrEbh+l6JgUundniloMLDQ/6VTdhLQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", @@ -26206,6 +25429,16 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/path-to-regexp": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.0.tgz", + "integrity": "sha512-PuseHIvAnz3bjrM2rGJtSgo1zjgxapTLZ7x2pjhzWwlp4SJQgK3f3iZIQwkpEnBaKz6seKBADpM4B4ySkuYypg==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, "node_modules/path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", @@ -26227,12 +25460,6 @@ "dev": true, "license": "MIT" }, - "node_modules/performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", - "dev": true - }, "node_modules/pg": { "version": "8.18.0", "resolved": "https://registry.npmjs.org/pg/-/pg-8.18.0.tgz", @@ -26308,16 +25535,16 @@ } }, "node_modules/pg-monitor": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pg-monitor/-/pg-monitor-3.0.0.tgz", - "integrity": "sha512-62jezmq3lR+lKCIsi9BXVg8Fxv+JG5LtaAuUmex5EVnBPlvAU7Ad6dOiQXHtH1xNh/Oy6Hux36k8uIjZWNeWtQ==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pg-monitor/-/pg-monitor-3.1.0.tgz", + "integrity": "sha512-giK0h52AOO/v8iu6hZCdZ/X9W8oAM9Dm1VReQQtki532X8g4z1LVIm4Z/3cGvDcETWW+Ty0FrtU8iTrGFYIZfA==", "dev": true, "license": "MIT", "dependencies": { - "picocolors": "^1.1.1" + "picocolors": "1.1.1" }, "engines": { - "node": ">=14" + "node": ">=16" } }, "node_modules/pg-pool": { @@ -26415,10 +25642,11 @@ "license": "ISC" }, "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", "dev": true, + "license": "MIT", "engines": { "node": ">=8.6" }, @@ -26638,10 +25866,11 @@ } }, "node_modules/postcss-modules-extract-imports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", - "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz", + "integrity": "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==", "dev": true, + "license": "ISC", "engines": { "node": "^10 || ^12 || >= 14" }, @@ -26650,13 +25879,14 @@ } }, "node_modules/postcss-modules-local-by-default": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz", - "integrity": "sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.2.0.tgz", + "integrity": "sha512-5kcJm/zk+GJDSfw+V/42fJ5fhjL5YbFDl8nVdXkJPLLW+Vf9mTD5Xe0wqIaDnLuL2U6cDNpTr+UQ+v2HWIBhzw==", "dev": true, + "license": "MIT", "dependencies": { "icss-utils": "^5.0.0", - "postcss-selector-parser": "^6.0.2", + "postcss-selector-parser": "^7.0.0", "postcss-value-parser": "^4.1.0" }, "engines": { @@ -26667,12 +25897,13 @@ } }, "node_modules/postcss-modules-scope": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz", - "integrity": "sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.1.tgz", + "integrity": "sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA==", "dev": true, + "license": "ISC", "dependencies": { - "postcss-selector-parser": "^6.0.4" + "postcss-selector-parser": "^7.0.0" }, "engines": { "node": "^10 || ^12 || >= 14" @@ -26697,10 +25928,11 @@ } }, "node_modules/postcss-selector-parser": { - "version": "6.0.11", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.11.tgz", - "integrity": "sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz", + "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", "dev": true, + "license": "MIT", "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -26713,7 +25945,8 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/postcss-values-parser": { "version": "6.0.2", @@ -27102,12 +26335,6 @@ "dev": true, "license": "MIT" }, - "node_modules/psl": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", - "dev": true - }, "node_modules/pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", @@ -27308,9 +26535,9 @@ } }, "node_modules/qs": { - "version": "6.14.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.1.tgz", - "integrity": "sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.0.tgz", + "integrity": "sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ==", "license": "BSD-3-Clause", "dependencies": { "side-channel": "^1.1.0" @@ -27369,16 +26596,6 @@ "node": ">= 0.8" } }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, "node_modules/range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", @@ -27389,9 +26606,9 @@ } }, "node_modules/rate-limit-redis": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/rate-limit-redis/-/rate-limit-redis-4.2.0.tgz", - "integrity": "sha512-wV450NQyKC24NmPosJb2131RoczLdfIJdKCReNwtVpm5998U8SgKrAZrIHaN/NfQgqOHaan8Uq++B4sa5REwjA==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/rate-limit-redis/-/rate-limit-redis-4.3.1.tgz", + "integrity": "sha512-+a1zU8+D7L8siDK9jb14refQXz60vq427VuiplgnaLk9B2LnvGe/APLTfhwb4uNIL7eWVknh8GnRp/unCj+lMA==", "dev": true, "license": "MIT", "engines": { @@ -28002,17 +27219,17 @@ } }, "node_modules/redis": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/redis/-/redis-5.10.0.tgz", - "integrity": "sha512-0/Y+7IEiTgVGPrLFKy8oAEArSyEJkU0zvgV5xyi9NzNQ+SLZmyFbUsWIbgPcd4UdUh00opXGKlXJwMmsis5Byw==", + "version": "5.11.0", + "resolved": "https://registry.npmjs.org/redis/-/redis-5.11.0.tgz", + "integrity": "sha512-YwXjATVDT+AuxcyfOwZn046aml9jMlQPvU1VXIlLDVAExe0u93aTfPYSeRgG4p9Q/Jlkj+LXJ1XEoFV+j2JKcQ==", "dev": true, "license": "MIT", "dependencies": { - "@redis/bloom": "5.10.0", - "@redis/client": "5.10.0", - "@redis/json": "5.10.0", - "@redis/search": "5.10.0", - "@redis/time-series": "5.10.0" + "@redis/bloom": "5.11.0", + "@redis/client": "5.11.0", + "@redis/json": "5.11.0", + "@redis/search": "5.11.0", + "@redis/time-series": "5.11.0" }, "engines": { "node": ">= 18" @@ -28162,83 +27379,6 @@ "regjsparser": "bin/parser" } }, - "node_modules/request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", - "dev": true, - "dependencies": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/request-promise": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/request-promise/-/request-promise-4.2.6.tgz", - "integrity": "sha512-HCHI3DJJUakkOr8fNoCc73E5nU5bqITjOYFMDrKHYOXWXrgD/SBaC7LjwuPymUprRyuF06UK7hd/lMHkmUXglQ==", - "deprecated": "request-promise has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142", - "dev": true, - "license": "ISC", - "dependencies": { - "bluebird": "^3.5.0", - "request-promise-core": "1.1.4", - "stealthy-require": "^1.1.1", - "tough-cookie": "^2.3.3" - }, - "engines": { - "node": ">=0.10.0" - }, - "peerDependencies": { - "request": "^2.34" - } - }, - "node_modules/request-promise-core": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", - "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==", - "dev": true, - "license": "ISC", - "dependencies": { - "lodash": "^4.17.19" - }, - "engines": { - "node": ">=0.10.0" - }, - "peerDependencies": { - "request": "^2.34" - } - }, - "node_modules/request/node_modules/qs": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", - "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", - "dev": true, - "engines": { - "node": ">=0.6" - } - }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -28435,16 +27575,6 @@ "node": ">= 0.8" } }, - "node_modules/router/node_modules/path-to-regexp": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz", - "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==", - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, "node_modules/rrweb-cssom": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.8.0.tgz", @@ -28667,12 +27797,6 @@ "node": ">=18" } }, - "node_modules/sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", - "dev": true - }, "node_modules/saxes": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", @@ -28716,9 +27840,9 @@ } }, "node_modules/schema-utils/node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", "dev": true, "license": "MIT", "dependencies": { @@ -28862,6 +27986,22 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/semantic-release/node_modules/ansi-escapes": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.3.0.tgz", + "integrity": "sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "environment": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/semantic-release/node_modules/ansi-regex": { "version": "6.2.2", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", @@ -29093,6 +28233,41 @@ "node": "20 || >=22" } }, + "node_modules/semantic-release/node_modules/marked": { + "version": "15.0.12", + "resolved": "https://registry.npmjs.org/marked/-/marked-15.0.12.tgz", + "integrity": "sha512-8dD6FusOQSrpv9Z1rdNMdlSgQOIP880DHqnohobOmYLElGEqAL/JvxvuxZO16r4HtjTlfPRDC1hbvxC9dPN2nA==", + "dev": true, + "license": "MIT", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/semantic-release/node_modules/marked-terminal": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/marked-terminal/-/marked-terminal-7.3.0.tgz", + "integrity": "sha512-t4rBvPsHc57uE/2nJOLmMbZCQ4tgAccAED3ngXQqW6g+TxA488JzJ+FK3lQkzBQOI1mRV/r/Kq+1ZlJ4D0owQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-escapes": "^7.0.0", + "ansi-regex": "^6.1.0", + "chalk": "^5.4.1", + "cli-highlight": "^2.1.11", + "cli-table3": "^0.6.5", + "node-emoji": "^2.2.0", + "supports-hyperlinks": "^3.1.0" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "marked": ">=1 <16" + } + }, "node_modules/semantic-release/node_modules/normalize-package-data": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-8.0.0.tgz", @@ -29394,9 +28569,9 @@ } }, "node_modules/semver": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", - "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -29492,16 +28667,6 @@ "node": ">= 0.8" } }, - "node_modules/serialize-javascript": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", - "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "randombytes": "^2.1.0" - } - }, "node_modules/serve-static": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz", @@ -29997,31 +29162,6 @@ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true }, - "node_modules/sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "dev": true, - "dependencies": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "bin": { - "sshpk-conv": "bin/sshpk-conv", - "sshpk-sign": "bin/sshpk-sign", - "sshpk-verify": "bin/sshpk-verify" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/stack-trace": { "version": "0.0.10", "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", @@ -30053,15 +29193,6 @@ "node": ">=8" } }, - "node_modules/stealthy-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", - "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/stream-combiner2": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz", @@ -30370,9 +29501,9 @@ } }, "node_modules/strnum": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.1.2.tgz", - "integrity": "sha512-l63NF9y/cLROq/yqKXSLtcMeeyOfnSQlfMSlzFt/K73oIaD8DGaQWd7Z34X9GPiKqP5rbSh84Hl4bOlLcjiSrQ==", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.2.2.tgz", + "integrity": "sha512-DnR90I+jtXNSTXWdwrEy9FakW7UX+qUZg28gj5fk2vxxl7uS/3bpI4fjFYVmdK9etptYBPNkpahuQnEwhwECqA==", "dev": true, "funding": [ { @@ -30440,53 +29571,6 @@ "node": ">=18" } }, - "node_modules/subscriptions-transport-ws": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/subscriptions-transport-ws/-/subscriptions-transport-ws-0.11.0.tgz", - "integrity": "sha512-8D4C6DIH5tGiAIpp5I0wD/xRlNiZAPGHygzCe7VzyzUoxHtawzjNAY9SUTXU05/EY2NMY9/9GF0ycizkXr1CWQ==", - "deprecated": "The `subscriptions-transport-ws` package is no longer maintained. We recommend you use `graphql-ws` instead. For help migrating Apollo software to `graphql-ws`, see https://www.apollographql.com/docs/apollo-server/data/subscriptions/#switching-from-subscriptions-transport-ws For general help using `graphql-ws`, see https://github.com/enisdenjo/graphql-ws/blob/master/README.md", - "dev": true, - "license": "MIT", - "dependencies": { - "backo2": "^1.0.2", - "eventemitter3": "^3.1.0", - "iterall": "^1.2.1", - "symbol-observable": "^1.0.4", - "ws": "^5.2.0 || ^6.0.0 || ^7.0.0" - }, - "peerDependencies": { - "graphql": "^15.7.2 || ^16.0.0" - } - }, - "node_modules/subscriptions-transport-ws/node_modules/eventemitter3": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", - "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/subscriptions-transport-ws/node_modules/ws": { - "version": "7.5.10", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", - "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, "node_modules/super-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/super-regex/-/super-regex-1.0.0.tgz", @@ -30515,6 +29599,23 @@ "node": ">=8" } }, + "node_modules/supports-hyperlinks": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.2.0.tgz", + "integrity": "sha512-zFObLMyZeEwzAoKCyu1B91U79K2t7ApXuQfo8OuxwXLDgcKxuwM+YvcbIhm6QWqz7mHUH1TVytR1PwVVjEuMig==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">=14.18" + }, + "funding": { + "url": "https://github.com/chalk/supports-hyperlinks?sponsor=1" + } + }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", @@ -30527,38 +29628,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/svg-prep": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/svg-prep/-/svg-prep-1.0.4.tgz", - "integrity": "sha512-RT9dKj+l9yRsrQIZhdWqIftN0E4agtnPCn8pFJm9yM9bEWrNJhtUjG2g2AA/K+9pa4gh/CRFMXIPtcHOviQE2w==", - "dev": true, - "dependencies": { - "commander": "^2.8.1", - "xml2js": "^0.4.12" - }, - "bin": { - "svg-prep": "bin/index.js" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/svg-prep/node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, - "node_modules/symbol-observable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", - "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/symbol-tree": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", @@ -30614,22 +29683,20 @@ } }, "node_modules/tar": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", - "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", - "deprecated": "Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "version": "7.5.13", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.13.tgz", + "integrity": "sha512-tOG/7GyXpFevhXVh8jOPJrmtRpOTsYqUIkVdVooZYJS/z8WhfQUX8RJILmeuJNinGAMSu1veBr4asSHFt5/hng==", "dev": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "dependencies": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^5.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.1.0", + "yallist": "^5.0.0" }, "engines": { - "node": ">=10" + "node": ">=18" } }, "node_modules/tar-fs": { @@ -30674,27 +29741,14 @@ } } }, - "node_modules/tar/node_modules/minipass": { + "node_modules/tar/node_modules/yallist": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", - "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=8" - } - }, - "node_modules/tar/node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", "dev": true, - "license": "MIT", - "bin": { - "mkdirp": "bin/cmd.js" - }, + "license": "BlueOak-1.0.0", "engines": { - "node": ">=10" + "node": ">=18" } }, "node_modules/teeny-request": { @@ -30868,16 +29922,15 @@ } }, "node_modules/terser-webpack-plugin": { - "version": "5.3.16", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.16.tgz", - "integrity": "sha512-h9oBFCWrq78NyWWVcSwZarJkZ01c2AyGrzs1crmHZO3QUg9D61Wu4NPjBy69n7JqylFF5y+CsUZYmYEIZ3mR+Q==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.4.0.tgz", + "integrity": "sha512-Bn5vxm48flOIfkdl5CaD2+1CiUVbonWQ3KQPyP7/EuIl9Gbzq/gQFOzaMFUEgVjB1396tcK0SG8XcNJ/2kDH8g==", "dev": true, "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "^0.3.25", "jest-worker": "^27.4.5", "schema-utils": "^4.3.0", - "serialize-javascript": "^6.0.2", "terser": "^5.31.1" }, "engines": { @@ -31015,6 +30068,7 @@ "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", "dev": true, + "license": "MIT", "dependencies": { "any-promise": "^1.0.0" } @@ -31024,6 +30078,7 @@ "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", "dev": true, + "license": "MIT", "dependencies": { "thenify": ">= 3.1.0 < 4" }, @@ -31118,9 +30173,9 @@ } }, "node_modules/tinyglobby/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "dev": true, "license": "MIT", "engines": { @@ -31216,19 +30271,6 @@ "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz", "integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==" }, - "node_modules/tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dev": true, - "dependencies": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=0.8" - } - }, "node_modules/tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", @@ -31351,18 +30393,6 @@ "node": ">=0.6.11 <=0.7.0 || >=0.7.3" } }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dev": true, - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, "node_modules/tv4": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/tv4/-/tv4-1.3.0.tgz", @@ -31382,12 +30412,6 @@ "node": ">= 0.8.0" } }, - "node_modules/tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "dev": true - }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -31632,16 +30656,13 @@ } }, "node_modules/undici": { - "version": "5.29.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-5.29.0.tgz", - "integrity": "sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg==", + "version": "6.24.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.24.0.tgz", + "integrity": "sha512-lVLNosgqo5EkGqh5XUDhGfsMSoO8K0BAN0TyJLvwNRSl4xWGZlCVYsAIpa/OpA3TvmnM01GWcoKmc3ZWo5wKKA==", "dev": true, "license": "MIT", - "dependencies": { - "@fastify/busboy": "^2.0.0" - }, "engines": { - "node": ">=14.0" + "node": ">=18.17" } }, "node_modules/undici-types": { @@ -31942,13 +30963,17 @@ } }, "node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz", + "integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==", "dev": true, + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", "bin": { - "uuid": "bin/uuid" + "uuid": "dist/esm/bin/uuid" } }, "node_modules/v8-to-istanbul": { @@ -32610,7 +31635,6 @@ "version": "8.19.0", "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz", "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==", - "dev": true, "license": "MIT", "engines": { "node": ">=10.0.0" @@ -32638,28 +31662,6 @@ "node": ">=18" } }, - "node_modules/xml2js": { - "version": "0.4.23", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", - "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==", - "dev": true, - "dependencies": { - "sax": ">=0.6.0", - "xmlbuilder": "~11.0.0" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/xmlbuilder": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", - "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, "node_modules/xmlchars": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", @@ -32727,6 +31729,7 @@ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", "dev": true, + "license": "ISC", "engines": { "node": ">=10" } diff --git a/package.json b/package.json index 3c88412692..b46a255778 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "parse-dashboard", - "version": "9.0.0", + "version": "9.1.0-alpha.11", "repository": { "type": "git", "url": "https://github.com/parse-community/parse-dashboard" @@ -37,8 +37,8 @@ "LICENSE" ], "dependencies": { - "@babel/runtime": "7.28.6", - "@babel/runtime-corejs3": "7.29.0", + "@babel/runtime": "7.29.2", + "@babel/runtime-corejs3": "7.29.2", "bcryptjs": "3.0.3", "body-parser": "2.2.2", "chart.js": "4.5.1", @@ -47,20 +47,21 @@ "copy-to-clipboard": "3.3.3", "core-js": "3.48.0", "csrf-sync": "4.2.1", - "expr-eval-fork": "3.0.1", + "diff": "8.0.3", + "expr-eval-fork": "3.0.3", "express": "5.2.1", "express-session": "1.18.2", "fast-deep-equal": "3.1.3", "graphiql": "2.0.8", "graphql": "16.12.0", - "immutable": "5.1.4", + "immutable": "5.1.5", "immutable-devtools": "0.1.5", "inquirer": "13.2.2", "js-beautify": "1.15.4", "node-fetch": "3.3.2", "otpauth": "8.0.3", "package-json": "7.0.0", - "parse": "7.1.2", + "parse": "8.5.0", "passport": "0.7.0", "passport-local": "1.0.0", "prismjs": "1.30.0", @@ -82,7 +83,7 @@ "regenerator-runtime": "0.14.1" }, "devDependencies": { - "@actions/core": "2.0.1", + "@actions/core": "3.0.0", "@babel/core": "7.29.0", "@babel/eslint-parser": "7.28.6", "@babel/plugin-proposal-decorators": "7.29.0", @@ -94,38 +95,34 @@ "@semantic-release/changelog": "6.0.3", "@semantic-release/commit-analyzer": "13.0.1", "@semantic-release/git": "10.0.1", - "@semantic-release/github": "12.0.3", + "@semantic-release/github": "12.0.6", "@semantic-release/npm": "13.1.4", "@semantic-release/release-notes-generator": "14.1.0", "@types/jest": "30.0.0", "all-node-versions": "13.0.1", - "babel-loader": "10.0.0", - "css-loader": "6.7.3", + "babel-loader": "10.1.1", + "css-loader": "7.1.4", "eslint": "9.39.2", - "eslint-plugin-jest": "29.5.0", + "eslint-plugin-jest": "29.15.0", "eslint-plugin-react": "7.37.5", - "get-port": "7.1.0", + "get-port": "7.2.0", "globals": "17.3.0", "http-server": "14.1.1", "husky": "9.1.7", "jest": "30.0.4", "jest-environment-jsdom": "30.0.5", "madge": "8.0.0", - "marked": "15.0.12", + "marked": "17.0.3", "mongodb-runner": "^6.6.0", - "null-loader": "4.0.1", - "parse-server": "9.2.0", + "parse-server": "9.7.0", "prettier": "3.8.1", "puppeteer": "24.37.2", "react-test-renderer": "16.13.1", - "request": "2.88.2", - "request-promise": "4.2.6", "sass": "1.97.3", "sass-loader": "16.0.7", "semantic-release": "25.0.3", - "semver": "7.7.3", + "semver": "7.7.4", "style-loader": "3.3.1", - "svg-prep": "1.0.4", "typescript": "5.9.3", "webpack": "5.105.1", "webpack-cli": "6.0.1", @@ -133,8 +130,8 @@ "yaml": "2.8.2" }, "scripts": { - "ci:check": "node ./ci/ciCheck.js", - "ci:checkNodeEngine": "node ./ci/nodeEngineCheck.js", + "ci:check": "node ./ci/ciCheck.mjs", + "ci:checkNodeEngine": "node ./ci/nodeEngineCheck.mjs", "dev": "node ./Parse-Dashboard/index.js & webpack --config webpack/build.config.js --devtool eval-source-map --progress --watch", "dashboard": "node ./Parse-Dashboard/index.js & webpack --config webpack/build.config.js --progress --watch", "pig": "http-server ./PIG -p 4041 -s & webpack --config webpack/PIG.config.js --progress --watch", @@ -155,7 +152,7 @@ "parse-dashboard": "./bin/parse-dashboard" }, "engines": { - "node": ">=20.18.0 <21.0.0 || >=22.12.0 <23.0.0 || >=24.0.0 <25.0.0" + "node": ">=20.19.0 <21.0.0 || >=22.12.0 <23.0.0 || >=24.1.0 <25.0.0" }, "main": "Parse-Dashboard/app.js", "jest": { @@ -168,6 +165,9 @@ "moduleNameMapper": { "\\.(css|less)$": "/testing/styleMock.js" }, + "transformIgnorePatterns": [ + "node_modules/(?!(marked)/)" + ], "unmockedModulePathPatterns": [ "react", "react-dom", diff --git a/src/components/BrowserRow/BrowserRow.react.js b/src/components/BrowserRow/BrowserRow.react.js index bdc133a471..e038d483e8 100644 --- a/src/components/BrowserRow/BrowserRow.react.js +++ b/src/components/BrowserRow/BrowserRow.react.js @@ -56,6 +56,7 @@ export default class BrowserRow extends Component { onMouseOverRow, stickyLefts, freezeIndex, + isHighlighted, } = this.props; const attributes = obj.attributes; let requiredCols = []; @@ -74,8 +75,15 @@ export default class BrowserRow extends Component { } else if (obj.className === '_User' && obj.get('authData') !== undefined) { requiredCols = ['authData']; } - const rowBackground = row % 2 ? '#F4F5F7' : '#fdfafb'; + const highlightColor = '#eef4fb'; + const stickyHighlightColor = '#d6e4f0'; + const defaultRowBackground = '#ffffff'; + const rowBackground = isHighlighted ? highlightColor : defaultRowBackground; + const stickyBackground = isHighlighted ? stickyHighlightColor : defaultRowBackground; const rowStyle = { minWidth: rowWidth }; + if (isHighlighted) { + rowStyle.background = highlightColor; + } return (
onMouseOverRow(obj.id)}> @@ -104,7 +112,7 @@ export default class BrowserRow extends Component { position: 'sticky', left: 30, zIndex: 1, - background: rowBackground, + background: stickyBackground, borderBottom: '1px solid #e3e3ea', width: rowNumberWidth, }} diff --git a/src/components/CategoryList/CategoryList.react.js b/src/components/CategoryList/CategoryList.react.js index 1c656f3284..931e300ef9 100644 --- a/src/components/CategoryList/CategoryList.react.js +++ b/src/components/CategoryList/CategoryList.react.js @@ -20,6 +20,8 @@ export default class CategoryList extends React.Component { this.listWrapperRef = React.createRef(); this.state = { openClasses: [], + hoveredFilter: null, + hoveredClass: null, }; } @@ -170,7 +172,11 @@ export default class CategoryList extends React.Component { const link = generatePath(this.context, (this.props.linkPrefix || '') + (c.link || id)); return (
-
+
this.setState({ hoveredClass: id })} + onMouseLeave={() => this.setState({ hoveredClass: null })} + > { e.preventDefault(); c.onEdit(); @@ -221,8 +228,14 @@ export default class CategoryList extends React.Component { const url = id ? `${this.props.linkPrefix}${c.name}?filters=${encodeURIComponent(filter)}&filterId=${id}` : `${this.props.linkPrefix}${c.name}?filters=${encodeURIComponent(filter)}`; + const filterKey = `${c.name}-${index}`; return ( -
+
this.setState({ hoveredFilter: filterKey })} + onMouseLeave={() => this.setState({ hoveredFilter: null })} + > { @@ -236,6 +249,7 @@ export default class CategoryList extends React.Component { {this.props.onEditFilter && ( { e.preventDefault(); this.props.onEditFilter(c.name, filterData); diff --git a/src/components/CategoryList/CategoryList.scss b/src/components/CategoryList/CategoryList.scss index 6de579c3ab..f5a1e65961 100644 --- a/src/components/CategoryList/CategoryList.scss +++ b/src/components/CategoryList/CategoryList.scss @@ -100,8 +100,6 @@ align-items: flex-start; padding-top: 2px; cursor: pointer; - opacity: 0; - transition: opacity 0.2s ease; svg { fill: #8fb9cf; } @@ -111,10 +109,6 @@ } } } - - &:hover .edit { - opacity: 1; - } } .childLink { @@ -138,8 +132,6 @@ align-items: flex-start; padding-top: 2px; cursor: pointer; - opacity: 0; - transition: opacity 0.2s ease; svg { fill: #8fb9cf; } @@ -149,8 +141,4 @@ } } } - - &:hover .editFilter { - opacity: 1; - } } diff --git a/src/components/DataBrowserHeader/DataBrowserHeader.scss b/src/components/DataBrowserHeader/DataBrowserHeader.scss index 2510ca6255..4f1b78cd96 100644 --- a/src/components/DataBrowserHeader/DataBrowserHeader.scss +++ b/src/components/DataBrowserHeader/DataBrowserHeader.scss @@ -15,7 +15,6 @@ overflow: hidden; height: 30px; padding: 4px 6px 4px 2px; - cursor: pointer; border-left: 4px solid transparent; } diff --git a/src/components/DataBrowserHeaderBar/DataBrowserHeaderBar.react.js b/src/components/DataBrowserHeaderBar/DataBrowserHeaderBar.react.js index f914421b15..8117c6933b 100644 --- a/src/components/DataBrowserHeaderBar/DataBrowserHeaderBar.react.js +++ b/src/components/DataBrowserHeaderBar/DataBrowserHeaderBar.react.js @@ -50,7 +50,6 @@ export default class DataBrowserHeaderBar extends React.Component { setSelectedObjectId, setCurrent, stickyLefts, - handleLefts, freezeIndex, showRowNumber, rowNumberWidth, @@ -120,6 +119,11 @@ export default class DataBrowserHeaderBar extends React.Component { className += ` ${styles.preventSort} `; } + let handleClassName = styles.handle; + if (freezeIndex >= 0 && i === freezeIndex) { + handleClassName += ` ${styles.handleFreeze}`; + } + elements.push(
+ e.stopPropagation()} + />
); - const handleStyle = {}; - if (freezeIndex >= 0 && typeof handleLefts[i] !== 'undefined' && i <= freezeIndex) { - handleStyle.position = 'sticky'; - handleStyle.left = handleLefts[i]; - handleStyle.zIndex = 11; - if (i === freezeIndex) { - handleStyle.marginRight = 0; - handleStyle.width = 4; - } else { - handleStyle.background = wrapStyle.background; - } - } - elements.push( - - ); }); if (onAddColumn) { diff --git a/src/components/DataBrowserHeaderBar/DataBrowserHeaderBar.scss b/src/components/DataBrowserHeaderBar/DataBrowserHeaderBar.scss index 744a7b3466..c23d8ccbd4 100644 --- a/src/components/DataBrowserHeaderBar/DataBrowserHeaderBar.scss +++ b/src/components/DataBrowserHeaderBar/DataBrowserHeaderBar.scss @@ -18,14 +18,13 @@ display: block; min-width: 100%; width: max-content; - // to resolve rendering issue with retina displays - -webkit-transform: translate3d(0, 0, 0); - will-change: transform; } .wrap { + position: relative; display: inline-block; vertical-align: top; + cursor: pointer; } .addColumn { @@ -71,12 +70,24 @@ } .handle { - position: relative; - display: inline-block; - width: 8px; + position: absolute; + right: -8px; + top: 0; + width: 16px; height: 30px; - margin: 0 -4px; - cursor: ew-resize; + z-index: 2; + cursor: col-resize; + background: rgba(255, 255, 255, 0); + transition: background 0.15s ease; + + &:hover { + background: rgba(255, 255, 255, 0.15); + } +} + +.handleFreeze { + right: -4px; + width: 8px; } .pickerPointer { diff --git a/src/components/DateTimeEditor/DateTimeEditor.react.js b/src/components/DateTimeEditor/DateTimeEditor.react.js index d4ede599d7..e151b530c4 100644 --- a/src/components/DateTimeEditor/DateTimeEditor.react.js +++ b/src/components/DateTimeEditor/DateTimeEditor.react.js @@ -27,10 +27,6 @@ export default class DateTimeEditor extends React.Component { this.editorRef = React.createRef(); } - componentWillReceiveProps(props) { - this.setState({ value: props.value, text: props.value.toISOString() }); - } - componentDidMount() { document.body.addEventListener('click', this.checkExternalClick); document.body.addEventListener('touchend', this.checkExternalClick); @@ -85,9 +81,11 @@ export default class DateTimeEditor extends React.Component { text: this.props.value.toISOString(), }); } else { - if (this.state.text.endsWith('Z')) { + if (this.state.text.endsWith('Z') || this.state.text.endsWith('UTC')) { + // Timezone is explicit; the parsed Date is already correct. this.setState({ value: date }); } else { + // No timezone indicator; treat input as local time. const utc = new Date( Date.UTC( date.getFullYear(), diff --git a/src/components/FileInput/FileInput.react.js b/src/components/FileInput/FileInput.react.js index 2324ff0eeb..e142b02238 100644 --- a/src/components/FileInput/FileInput.react.js +++ b/src/components/FileInput/FileInput.react.js @@ -44,7 +44,7 @@ export default class FileInput extends React.Component { if (this.props.accept) { inputProps.accept = this.props.accept; } - const label = this.renderLabel(); + const label = this.props.buttonText ? null : this.renderLabel(); const buttonStyles = [styles.button]; if (this.props.disabled || this.props.uploading) { buttonStyles.push(styles.disabled); @@ -58,6 +58,8 @@ export default class FileInput extends React.Component {
{this.props.uploading ? (
+ ) : this.props.buttonText ? ( + {this.props.buttonText} ) : label ? ( Change file ) : ( diff --git a/src/components/JsonEditor/JsonEditor.scss b/src/components/JsonEditor/JsonEditor.scss index e0d35af85a..df5f06835e 100644 --- a/src/components/JsonEditor/JsonEditor.scss +++ b/src/components/JsonEditor/JsonEditor.scss @@ -42,7 +42,7 @@ pointer-events: none; background: transparent; color: #555572; - overflow: auto; + overflow: hidden; code { display: block; diff --git a/src/components/MultiSelect/MultiSelect.react.js b/src/components/MultiSelect/MultiSelect.react.js index 532b853fd9..f742c6c6d2 100644 --- a/src/components/MultiSelect/MultiSelect.react.js +++ b/src/components/MultiSelect/MultiSelect.react.js @@ -81,7 +81,7 @@ export default class MultiSelect extends React.Component { render() { let popover = null; if (this.state.open) { - const width = this.dropdownRef.current.clientWidth; + const width = this.props.menuWidth || this.dropdownRef.current.clientWidth; const classes = [styles.menu]; if (this.props.dense) { diff --git a/src/components/NumberEditor/NumberEditor.react.js b/src/components/NumberEditor/NumberEditor.react.js index d86e5fe26a..fcfe36187e 100644 --- a/src/components/NumberEditor/NumberEditor.react.js +++ b/src/components/NumberEditor/NumberEditor.react.js @@ -23,6 +23,7 @@ export default class NumberEditor extends React.Component { } componentDidMount() { + this.inputRef.current.focus(); this.inputRef.current.setSelectionRange(0, String(this.state.value).length); document.body.addEventListener('click', this.checkExternalClick); document.body.addEventListener('touchend', this.checkExternalClick); diff --git a/src/components/StringEditor/StringEditor.react.js b/src/components/StringEditor/StringEditor.react.js index c4067a3558..1258919851 100644 --- a/src/components/StringEditor/StringEditor.react.js +++ b/src/components/StringEditor/StringEditor.react.js @@ -23,6 +23,7 @@ export default class StringEditor extends React.Component { } componentDidMount() { + this.inputRef.current.focus(); this.inputRef.current.setSelectionRange(0, this.state.value.length); document.body.addEventListener('click', this.checkExternalClick); document.body.addEventListener('touchend', this.checkExternalClick); diff --git a/src/dashboard/Data/Browser/Browser.react.js b/src/dashboard/Data/Browser/Browser.react.js index d8afc59119..57dfe57af3 100644 --- a/src/dashboard/Data/Browser/Browser.react.js +++ b/src/dashboard/Data/Browser/Browser.react.js @@ -24,6 +24,14 @@ import ScriptResponseModal from 'dashboard/Data/Browser/ScriptResponseModal.reac import ExportDialog from 'dashboard/Data/Browser/ExportDialog.react'; import ExportSchemaDialog from 'dashboard/Data/Browser/ExportSchemaDialog.react'; import ExportSelectedRowsDialog from 'dashboard/Data/Browser/ExportSelectedRowsDialog.react'; +import ImportDataDialog from 'dashboard/Data/Browser/ImportDataDialog.react'; +import { + parseImportJSON, + parseImportCSV, + buildBatchRequests, + sendBatchImport, + checkDuplicates, +} from 'lib/importData'; import Notification from 'dashboard/Data/Browser/Notification.react'; import PointerKeyDialog from 'dashboard/Data/Browser/PointerKeyDialog.react'; import RemoveColumnDialog from 'dashboard/Data/Browser/RemoveColumnDialog.react'; @@ -152,6 +160,7 @@ class Browser extends DashboardView { showPointerKeyDialog: false, rowsToDelete: null, rowsToExport: null, + showImportDialog: false, relation: null, counts: {}, @@ -255,6 +264,9 @@ class Browser extends DashboardView { this.showExportSchemaDialog = this.showExportSchemaDialog.bind(this); this.confirmExportSelectedRows = this.confirmExportSelectedRows.bind(this); this.cancelExportSelectedRows = this.cancelExportSelectedRows.bind(this); + this.showImportDialog = this.showImportDialog.bind(this); + this.confirmImport = this.confirmImport.bind(this); + this.cancelImportDialog = this.cancelImportDialog.bind(this); this.getClassRelationColumns = this.getClassRelationColumns.bind(this); this.showCreateClass = this.showCreateClass.bind(this); this.refresh = this.refresh.bind(this); @@ -303,6 +315,8 @@ class Browser extends DashboardView { // Map of objectId -> promise for ongoing info panel cloud function requests this.infoPanelQueries = {}; + this.importDialogRef = null; + this.dataBrowserRef = React.createRef(); window.addEventListener('popstate', () => { @@ -2071,6 +2085,7 @@ class Browser extends DashboardView { this.state.showEditRowDialog || this.state.showPermissionsDialog || this.state.showExportSelectedRowsDialog || + this.state.showImportDialog || this.state.showAddToConfigDialog ); } @@ -2420,6 +2435,149 @@ class Browser extends DashboardView { }); } + showImportDialog() { + this.setState({ showImportDialog: true }); + } + + cancelImportDialog() { + this.setState({ showImportDialog: false }); + this.refresh(); + } + + async confirmImport(importOptions) { + const className = this.props.params.className; + const classColumns = this.getClassColumns(className, false); + const schema = {}; + classColumns.forEach(column => { + schema[column.name] = column; + }); + const knownColumns = classColumns.map(c => c.name); + + // Parse the file + let parseResult; + if (importOptions.fileType === '.json') { + parseResult = parseImportJSON(importOptions.content); + } else { + parseResult = parseImportCSV(importOptions.content, schema); + } + + if (parseResult.error) { + this.showNote(parseResult.error, true); + if (this.importDialogRef) { + this.importDialogRef.resetForm(); + } + return; + } + + // Check for unknown columns if fail mode + if (importOptions.unknownColumns === 'fail') { + const unknownCols = []; + for (const row of parseResult.rows) { + for (const key of Object.keys(row)) { + if (!knownColumns.includes(key) && !unknownCols.includes(key)) { + unknownCols.push(key); + } + } + } + if (unknownCols.length > 0) { + this.showNote(`Unknown columns found: ${unknownCols.join(', ')}. Import aborted.`, true); + if (this.importDialogRef) { + this.importDialogRef.resetForm(); + } + return; + } + } + + try { + // Track rows before duplicate filtering for skip count + const totalRowsBefore = parseResult.rows.length; + + // Check for duplicates if needed + if (importOptions.preserveObjectIds && importOptions.duplicateHandling !== 'overwrite') { + const objectIds = parseResult.rows + .map(r => r.objectId) + .filter(Boolean); + + if (objectIds.length > 0) { + const existing = await checkDuplicates(objectIds, className); + + if (importOptions.duplicateHandling === 'fail' && existing.length > 0) { + this.showNote( + `Duplicate objectIds found: ${existing.slice(0, 5).join(', ')}${existing.length > 5 ? '...' : ''}. Import aborted.`, + true + ); + if (this.importDialogRef) { + this.importDialogRef.resetForm(); + } + return; + } + + if (importOptions.duplicateHandling === 'skip') { + const existingSet = new Set(existing); + parseResult.rows = parseResult.rows.filter(r => !existingSet.has(r.objectId)); + if (parseResult.rows.length === 0) { + this.showNote('All rows already exist. Nothing to import.', true); + if (this.importDialogRef) { + this.importDialogRef.resetForm(); + } + return; + } + } + } + } + + const skippedCount = totalRowsBefore - parseResult.rows.length; + + // Build batch requests + const requests = buildBatchRequests(parseResult.rows, className, { + preserveObjectIds: importOptions.preserveObjectIds, + preserveTimestamps: importOptions.preserveTimestamps, + duplicateHandling: importOptions.duplicateHandling, + unknownColumns: importOptions.unknownColumns, + knownColumns, + }); + + // Set dialog to importing state + if (this.importDialogRef) { + this.importDialogRef.setImporting(); + } + + // Send batch import + const results = await sendBatchImport(requests, { + serverURL: this.context.serverURL, + applicationId: this.context.applicationId, + masterKey: this.context.masterKey, + maintenanceKey: importOptions.preserveTimestamps ? this.context.maintenanceKey : undefined, + continueOnError: importOptions.continueOnError, + onProgress: (progress) => { + if (this.importDialogRef) { + this.importDialogRef.setProgress(progress); + } + }, + }); + + // Show results in dialog with skip count included + if (this.importDialogRef) { + this.importDialogRef.setResults({ + ...results, + skipped: results.skipped + skippedCount, + }); + } + } catch (error) { + const msg = typeof error === 'string' ? error : error.message; + this.showNote(msg || 'Import failed due to a network error.', true); + if (this.importDialogRef) { + this.importDialogRef.setResults({ + imported: 0, + skipped: 0, + failed: 0, + errors: [], + stopped: true, + }); + } + } + } + cancelExportSelectedRows() { this.setState({ rowsToExport: null, @@ -2957,6 +3115,7 @@ class Browser extends DashboardView { onEditPermissions={this.onDialogToggle} onExportSelectedRows={this.showExportSelectedRowsDialog} onExportSchema={this.showExportSchemaDialog} + onImport={this.showImportDialog} onSaveNewRow={this.saveNewRow} onShowPointerKey={this.showPointerKeyDialog} onAbortAddRow={this.abortAddRow} @@ -3247,6 +3406,16 @@ class Browser extends DashboardView { } /> ); + } else if (this.state.showImportDialog) { + extras = ( + { this.importDialogRef = ref; }} + className={className} + maintenanceKey={this.context.maintenanceKey} + onCancel={this.cancelImportDialog} + onConfirm={this.confirmImport} + /> + ); } else if (this.state.showAddToConfigDialog) { extras = ( { stickyLefts[i] = left; - handleLefts[i] = left + h.width; if (h.visible) { left += h.width; } }); } let editor = null; + const isRowHighlighted = (rowIndex) => + (this.props.current && this.props.current.row === rowIndex) || + (this.props.selectedCells && + this.props.selectedCells.rowStart >= 0 && + rowIndex >= this.props.selectedCells.rowStart && + rowIndex <= this.props.selectedCells.rowEnd); let table =
; if (this.props.data) { const rowWidth = @@ -162,6 +166,7 @@ export default class BrowserTable extends React.Component { appId={this.props.appId} key={index} isEditing={isEditingRow} + isHighlighted={isRowHighlighted(index)} className={this.props.className} columns={this.props.columns} schema={this.props.schema} @@ -257,6 +262,7 @@ export default class BrowserTable extends React.Component { } {onAddRow && ( onExportSelectedRows({ '*': true })} /> onExportSchema()} /> + {!relation && ( + <> + + onImport()} /> + + )} )} {onAddRow &&
} diff --git a/src/dashboard/Data/Browser/ImportDataDialog.react.js b/src/dashboard/Data/Browser/ImportDataDialog.react.js new file mode 100644 index 0000000000..cd58ddffa0 --- /dev/null +++ b/src/dashboard/Data/Browser/ImportDataDialog.react.js @@ -0,0 +1,340 @@ +/* + * Copyright (c) 2016-present, Parse, LLC + * All rights reserved. + * + * This source code is licensed under the license found in the LICENSE file in + * the root directory of this source tree. + */ +import Modal from 'components/Modal/Modal.react'; +import React from 'react'; +import Dropdown from 'components/Dropdown/Dropdown.react'; +import Field from 'components/Field/Field.react'; +import Label from 'components/Label/Label.react'; +import Option from 'components/Dropdown/Option.react'; +import Toggle from 'components/Toggle/Toggle.react'; +import FileInput from 'components/FileInput/FileInput.react'; +import styles from 'dashboard/Data/Browser/ImportDataDialog.scss'; + +export default class ImportDataDialog extends React.Component { + constructor() { + super(); + + this.state = { + file: null, + fileError: null, + preserveObjectIds: false, + preserveTimestamps: false, + duplicateHandling: 'overwrite', + unknownColumns: 'auto', + continueOnError: true, + importing: false, + progress: null, + results: null, + }; + } + + valid() { + if (this.state.importing) { + return false; + } + if (this.state.results) { + return false; + } + if (!this.state.file) { + return false; + } + const ext = this.getFileExtension(); + if (ext !== '.json' && ext !== '.csv') { + return false; + } + return true; + } + + getFileExtension() { + if (!this.state.file) { + return null; + } + const name = this.state.file.name.toLowerCase(); + if (name.endsWith('.json')) { + return '.json'; + } + if (name.endsWith('.csv')) { + return '.csv'; + } + return null; + } + + handleFileChange(file) { + if (!file) { + this.setState({ file: null, fileError: null }); + return; + } + const name = file.name.toLowerCase(); + if (!name.endsWith('.json') && !name.endsWith('.csv')) { + this.setState({ file: null, fileError: 'Only .json and .csv files are supported.' }); + return; + } + this.setState({ file, fileError: null }); + } + + handleConfirm() { + const file = this.state.file; + if (!file) { + return; + } + this.setState({ importing: true, progress: null, fileError: null }); + const reader = new FileReader(); + reader.onload = (e) => { + const content = e.target.result; + const fileType = this.getFileExtension(); + this.props.onConfirm({ + content, + fileType, + preserveObjectIds: this.state.preserveObjectIds, + preserveTimestamps: this.state.preserveTimestamps, + duplicateHandling: this.state.duplicateHandling, + unknownColumns: this.state.unknownColumns, + continueOnError: this.state.continueOnError, + }); + }; + reader.onerror = () => { + this.setState({ + importing: false, + fileError: 'Failed to read the selected file. Please try again.', + }); + }; + reader.readAsText(file); + } + + setImporting() { + this.setState({ importing: true, progress: null, results: null }); + } + + resetForm() { + this.setState({ importing: false, progress: null, results: null }); + } + + setProgress(progress) { + this.setState({ progress }); + } + + setResults(results) { + this.setState({ importing: false, results }); + } + + formatBytes(bytes) { + if (!+bytes) { + return '0 Bytes'; + } + + const k = 1024; + const decimals = 2; + const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; + + const i = Math.floor(Math.log(bytes) / Math.log(k)); + + return `${parseFloat((bytes / Math.pow(k, i)).toFixed(decimals))} ${sizes[i]}`; + } + + renderForm() { + const hasMaintenanceKey = !!this.props.maintenanceKey; + + return ( + <> + } + input={ + this.handleFileChange(file)} + accept=".json,.csv" + buttonText={this.state.file ? this.state.file.name : undefined} + /> + } + /> + {this.state.fileError && ( +
{this.state.fileError}
+ )} + {this.state.file && ( +
+ Format: {this.getFileExtension()} · Size: {this.formatBytes(this.state.file.size)} +
+ )} + } + input={ + this.setState({ preserveObjectIds })} + /> + } + /> + {!this.state.preserveObjectIds && ( +
+ Pointer and Relation fields that reference objectIds in this file will not resolve correctly if new objectIds are generated. +
+ )} + } + input={ + hasMaintenanceKey ? ( + this.setState({ preserveTimestamps })} + /> + ) : ( +
+ {}} + /> +
+ ) + } + /> + {!hasMaintenanceKey && ( +
+ Requires a maintenanceKey to be configured in the dashboard. +
+ )} + {this.state.preserveObjectIds && ( + } + input={ + this.setState({ duplicateHandling })} + > + + + + + } + /> + )} + } + input={ + this.setState({ unknownColumns })} + > + + + + + } + /> + } + input={ + this.setState({ continueOnError })} + /> + } + /> + + ); + } + + renderProgress() { + const { progress } = this.state; + const percent = progress && progress.total > 0 + ? Math.round((progress.completed / progress.total) * 100) + : 0; + + return ( +
+
); return ( - - - {dialogContent} - - + <> + + + {dialogContent} + + + {this.state.showDiscardConfirm && ( + this.setState({ showDiscardConfirm: false })} + /> + )} + ); } } diff --git a/src/lib/DateUtils.js b/src/lib/DateUtils.js index 57163eafe0..3ffd0a7cff 100644 --- a/src/lib/DateUtils.js +++ b/src/lib/DateUtils.js @@ -103,25 +103,19 @@ export function monthsFrom(date, delta) { } export function dateStringUTC(date) { - let full = - String(date.getUTCDate()) + - ' ' + - shortMonth(date.getUTCMonth()) + - ' ' + - String(date.getUTCFullYear()) + - ' at '; - const time = { - hours: String(date.getUTCHours()), - minutes: String(date.getUTCMinutes()), - seconds: String(date.getUTCSeconds()), - }; - for (const k in time) { - if (time[k].length < 2) { - time[k] = '0' + time[k]; - } - } - full += time.hours + ':' + time.minutes + ':' + time.seconds + ' UTC'; - return full; + // Use locale 'en-GB' to maintain the current date time format of "dd MMM yyyy, HH:mm:ss"; + // when supporting multiple locales in the future, this forced locale should be removed + return date.toLocaleDateString('en-GB', { + year: 'numeric', + month: 'short', + day: 'numeric', + hour: 'numeric', + minute: 'numeric', + second: 'numeric', + hour12: false, + timeZone: 'UTC', + timeZoneName: 'short', + }); } export function monthDayStringUTC(date) { diff --git a/src/lib/ParseApp.js b/src/lib/ParseApp.js index 6d8173671a..3da640d0ea 100644 --- a/src/lib/ParseApp.js +++ b/src/lib/ParseApp.js @@ -32,6 +32,7 @@ export default class ParseApp { dashboardURL, javascriptKey, masterKey, + maintenanceKey, restKey, windowsKey, webhookKey, @@ -63,6 +64,7 @@ export default class ParseApp { this.clientKey = clientKey; this.javascriptKey = javascriptKey; this.masterKey = masterKey; + this.maintenanceKey = maintenanceKey; this.restKey = restKey; this.windowsKey = windowsKey; this.webhookKey = webhookKey; diff --git a/src/lib/importData.js b/src/lib/importData.js new file mode 100644 index 0000000000..28dd4265ac --- /dev/null +++ b/src/lib/importData.js @@ -0,0 +1,414 @@ +/* + * Copyright (c) 2016-present, Parse, LLC + * All rights reserved. + * + * This source code is licensed under the license found in the LICENSE file in + * the root directory of this source tree. + */ +import Parse from 'parse'; + +/** + * Parse a JSON string containing an array of objects for import. + * @param {string} content - Raw JSON string + * @returns {{ rows: Object[]|null, error: string|null }} + */ +export function parseImportJSON(content) { + let parsed; + try { + parsed = JSON.parse(content); + } catch (e) { + return { rows: null, error: `Invalid JSON: ${e.message}` }; + } + if (!Array.isArray(parsed)) { + return { rows: null, error: 'JSON content must be an array of objects.' }; + } + if (parsed.length === 0) { + return { rows: null, error: 'The array is empty. Nothing to import.' }; + } + const invalidRowIndex = parsed.findIndex( + row => !row || typeof row !== 'object' || Array.isArray(row) + ); + if (invalidRowIndex !== -1) { + return { + rows: null, + error: `Row ${invalidRowIndex + 1} is not an object.`, + }; + } + return { rows: parsed, error: null }; +} + +/** + * Parse a CSV string using the given column schema for type reconstruction. + * @param {string} content - Raw CSV string + * @param {Object} schema - Map of { columnName: { type, targetClass? } } + * @returns {{ rows: Object[]|null, error: string|null }} + */ +export function parseImportCSV(content, schema = {}) { + if (!content || content.trim().length === 0) { + return { rows: null, error: 'File is empty.' }; + } + + const lines = parseCSVLines(content); + if (lines.length === 0) { + return { rows: null, error: 'File is empty.' }; + } + + const headers = lines[0]; + if (lines.length < 2) { + return { rows: null, error: 'No data rows found. The file contains only headers.' }; + } + + const rows = []; + for (let i = 1; i < lines.length; i++) { + const values = lines[i]; + const row = {}; + for (let j = 0; j < headers.length; j++) { + const header = headers[j]; + const raw = j < values.length ? values[j] : ''; + if (raw === '') { + continue; // omit empty cells + } + const colSchema = schema[header]; + const type = colSchema ? colSchema.type : 'String'; + const converted = convertCSVValue(raw, type, colSchema); + if (converted === undefined) { + continue; + } + if (type === 'Number' && Number.isNaN(converted)) { + return { + rows: null, + error: `Invalid number in row ${i}, column "${header}".`, + }; + } + if (type === 'Boolean' && raw.toLowerCase() !== 'true' && raw.toLowerCase() !== 'false') { + return { + rows: null, + error: `Invalid boolean in row ${i}, column "${header}".`, + }; + } + row[header] = converted; + } + if (Object.keys(row).length === 0) { + continue; + } + rows.push(row); + } + + return { rows, error: null }; +} + +/** + * Parse CSV content into an array of arrays (rows of fields). + * Handles quoted fields, escaped double-quotes, embedded commas and newlines. + */ +function parseCSVLines(content) { + const rows = []; + let row = []; + let field = ''; + let inQuotes = false; + let i = 0; + + while (i < content.length) { + const ch = content[i]; + + if (inQuotes) { + if (ch === '"') { + // Look ahead for escaped quote + if (i + 1 < content.length && content[i + 1] === '"') { + field += '"'; + i += 2; + } else { + // End of quoted field + inQuotes = false; + i++; + } + } else { + field += ch; + i++; + } + } else { + if (ch === '"') { + inQuotes = true; + i++; + } else if (ch === ',') { + row.push(field); + field = ''; + i++; + } else if (ch === '\r') { + // Handle \r\n or lone \r + row.push(field); + field = ''; + rows.push(row); + row = []; + i++; + if (i < content.length && content[i] === '\n') { + i++; + } + } else if (ch === '\n') { + row.push(field); + field = ''; + rows.push(row); + row = []; + i++; + } else { + field += ch; + i++; + } + } + } + + // Push last field/row if there is content + if (field.length > 0 || row.length > 0) { + row.push(field); + rows.push(row); + } + + return rows; +} + +/** + * Convert a raw CSV string value to the correct type based on schema. + */ +function convertCSVValue(value, type, colSchema) { + switch (type) { + case 'Number': + return Number(value); + case 'Boolean': + return value.toLowerCase() === 'true'; + case 'Pointer': + return { + __type: 'Pointer', + className: colSchema ? colSchema.targetClass : undefined, + objectId: value, + }; + case 'Relation': + // Relations cannot be set via batch create/update; skip + return undefined; + case 'Date': + return { __type: 'Date', iso: value }; + case 'GeoPoint': + case 'File': + case 'Object': + case 'Array': + case 'ACL': + try { + return JSON.parse(value); + } catch { + return value; + } + case 'String': + default: + return value; + } +} + +/** + * Build Parse REST API batch request objects from parsed rows. + * @param {Object[]} rows - Parsed row objects + * @param {string} className - Parse class name + * @param {Object} options - { preserveObjectIds, preserveTimestamps, duplicateHandling, unknownColumns, knownColumns } + * @returns {{ method: string, path: string, body: Object }[]} + */ +export function buildBatchRequests(rows, className, options) { + const { + preserveObjectIds = false, + preserveTimestamps = false, + duplicateHandling, + unknownColumns, + knownColumns, + } = options || {}; + + const allowed = (unknownColumns === 'ignore' && knownColumns) ? new Set(knownColumns) : null; + + return rows.map(row => { + // Clone the row to avoid mutating the original + let body = { ...row }; + + // Filter unknown columns if requested + if (allowed) { + const filtered = {}; + for (const key of Object.keys(body)) { + if (allowed.has(key)) { + filtered[key] = body[key]; + } + } + body = filtered; + } + + // Handle timestamps + if (!preserveTimestamps) { + delete body.createdAt; + delete body.updatedAt; + } else { + // Ensure createdAt/updatedAt are in { __type: 'Date', iso: '...' } format + if (body.createdAt !== undefined) { + body.createdAt = ensureDateObject(body.createdAt); + } + if (body.updatedAt !== undefined) { + body.updatedAt = ensureDateObject(body.updatedAt); + } + } + + // Determine method and path based on preserveObjectIds and duplicateHandling + if (preserveObjectIds && duplicateHandling === 'overwrite' && body.objectId) { + const path = `/classes/${className}/${body.objectId}`; + delete body.objectId; + if (Object.keys(body).length === 0) { + return null; + } + return { method: 'PUT', path, body }; + } + + if (!preserveObjectIds) { + delete body.objectId; + } + if (Object.keys(body).length === 0) { + return null; + } + return { method: 'POST', path: `/classes/${className}`, body }; + }).filter(Boolean); +} + +/** + * Ensure a value is in Parse Date object format { __type: 'Date', iso: '...' }. + * Converts plain ISO strings to the object format. + */ +function ensureDateObject(value) { + if (value && typeof value === 'object' && value.__type === 'Date') { + return value; + } + if (typeof value === 'string') { + return { __type: 'Date', iso: value }; + } + return value; +} + +/** + * Send batch import requests to Parse Server. + * + * Uses the REST batch endpoint directly instead of Parse.Object.saveAll() because the + * JS SDK does not support: maintenanceKey headers (needed for preserving timestamps), + * per-batch progress callbacks, per-row error collection with indices, or explicit PUT + * vs POST control for overwrites. + * + * @param {{ method: string, path: string, body: Object }[]} requests + * @param {Object} options - { serverURL, applicationId, masterKey, maintenanceKey, continueOnError, onProgress } + * @returns {Promise<{ imported: number, skipped: number, failed: number, errors: Object[], stopped: boolean }>} + */ +export async function sendBatchImport(requests, options) { + const { + serverURL, + applicationId, + masterKey, + maintenanceKey, + continueOnError = true, + onProgress, + } = options || {}; + + const normalizedServerURL = (serverURL || '').replace(/\/+$/, ''); + const BATCH_SIZE = 50; + let imported = 0; + let failed = 0; + const errors = []; + let stopped = false; + let completed = 0; + const total = requests.length; + + // Extract the path prefix from serverURL (e.g., '/parse' from 'http://localhost:1337/parse') + // Parse Server's batch handler requires paths to include this prefix + let serverPath = ''; + try { + serverPath = new URL(normalizedServerURL).pathname.replace(/\/+$/, ''); + } catch { + // If URL parsing fails, try to extract path manually + const pathMatch = normalizedServerURL.match(/https?:\/\/[^/]+(\/.*)/); + if (pathMatch) { + serverPath = pathMatch[1].replace(/\/+$/, ''); + } + } + + // Build headers + const headers = { + 'Content-Type': 'application/json', + 'X-Parse-Application-Id': applicationId, + }; + if (maintenanceKey) { + headers['X-Parse-Maintenance-Key'] = maintenanceKey; + } else { + headers['X-Parse-Master-Key'] = masterKey; + } + + for (let i = 0; i < requests.length; i += BATCH_SIZE) { + const batch = requests.slice(i, i + BATCH_SIZE).map(req => ({ + ...req, + path: `${serverPath}${req.path}`, + })); + const response = await fetch(`${normalizedServerURL}/batch`, { + method: 'POST', + headers, + body: JSON.stringify({ requests: batch }), + }); + + if (!response.ok) { + const errorBody = await response.text(); + throw new Error(`Server returned ${response.status}: ${errorBody}`); + } + + const results = await response.json(); + let batchHasErrors = false; + + for (let j = 0; j < results.length; j++) { + const result = results[j]; + if (result.success) { + imported++; + } else if (result.error) { + failed++; + batchHasErrors = true; + errors.push({ index: i + j, ...result.error }); + } + } + + completed += batch.length; + + if (batchHasErrors && !continueOnError) { + stopped = true; + if (onProgress) { + onProgress({ completed, total }); + } + break; + } + + if (onProgress) { + onProgress({ completed, total }); + } + } + + return { imported, skipped: 0, failed, errors, stopped }; +} + +/** + * Check which objectIds already exist in a Parse Server class. + * @param {string[]} objectIds + * @param {string} className + * @returns {Promise} + */ +export async function checkDuplicates(objectIds, className) { + if (!objectIds || objectIds.length === 0) { + return []; + } + + const CHUNK_SIZE = 1000; + const allExisting = []; + + for (let i = 0; i < objectIds.length; i += CHUNK_SIZE) { + const chunk = objectIds.slice(i, i + CHUNK_SIZE); + const query = new Parse.Query(className); + query.containedIn('objectId', chunk); + query.select('objectId'); + query.limit(chunk.length); + const results = await query.find({ useMasterKey: true }); + allExisting.push(...results.map(obj => obj.id)); + } + + return allExisting; +} diff --git a/src/lib/tests/AgentAuth.test.js b/src/lib/tests/AgentAuth.test.js index b0cc65a38b..92a322c918 100644 --- a/src/lib/tests/AgentAuth.test.js +++ b/src/lib/tests/AgentAuth.test.js @@ -373,3 +373,206 @@ describe('Agent endpoint security', () => { expect(res.status).not.toBe(403); }); }); + +// --------------------------------------------------------------- +// No-user mode — remote access guard +// --------------------------------------------------------------- + +describe('Agent endpoint no-user mode', () => { + let server; + let port; + + const noUserConfig = { + apps: [ + { + serverURL: 'http://localhost:1337/parse', + appId: 'testAppId', + masterKey: 'testMasterKey', + appName: 'TestApp', + }, + ], + // No users configured + agent: { + models: [ + { + name: 'test-model', + provider: 'openai', + model: 'gpt-4', + apiKey: 'fake-api-key-for-testing', + }, + ], + }, + }; + + beforeAll((done) => { + const parseDashboard = require('../../../Parse-Dashboard/app.js'); + // dev: false to enable the remote access guard + const dashboardApp = parseDashboard(noUserConfig, { + cookieSessionSecret: SESSION_SECRET, + }); + + const parentApp = express(); + parentApp.use('/', dashboardApp); + + server = parentApp.listen(0, () => { + port = server.address().port; + done(); + }); + }); + + afterAll((done) => { + if (server) { + server.close(done); + } else { + done(); + } + }); + + it('allows local requests to the agent endpoint in no-user mode', async () => { + // Requests to 127.0.0.1 are local, so they should pass the guard + const res = await makeRequest(port, { + method: 'POST', + path: '/apps/TestApp/agent', + body: agentBody(), + }); + // Should not be blocked by the no-user guard (may fail at CSRF or later) + expect(res.status).not.toBe(401); + }); +}); + +describe('Agent endpoint no-user mode — remote requests', () => { + let server; + let port; + + const noUserConfig = { + apps: [ + { + serverURL: 'http://localhost:1337/parse', + appId: 'testAppId', + masterKey: 'testMasterKey', + appName: 'TestApp', + }, + ], + agent: { + models: [ + { + name: 'test-model', + provider: 'openai', + model: 'gpt-4', + apiKey: 'fake-api-key-for-testing', + }, + ], + }, + }; + + beforeAll((done) => { + const parseDashboard = require('../../../Parse-Dashboard/app.js'); + const dashboardApp = parseDashboard(noUserConfig, { + cookieSessionSecret: SESSION_SECRET, + }); + + const parentApp = express(); + // Spoof a non-local remote address before the dashboard middleware + parentApp.use((req, _res, next) => { + Object.defineProperty(req.connection, 'remoteAddress', { + value: '203.0.113.1', + writable: true, + configurable: true, + }); + next(); + }); + parentApp.use('/', dashboardApp); + + server = parentApp.listen(0, () => { + port = server.address().port; + done(); + }); + }); + + afterAll((done) => { + if (server) { + server.close(done); + } else { + done(); + } + }); + + it('returns 403 for remote non-HTTPS requests to the agent endpoint', async () => { + const res = await makeRequest(port, { + method: 'POST', + path: '/apps/TestApp/agent', + body: agentBody(), + }); + expect(res.status).toBe(403); + expect(res.body.error).toBe('Parse Dashboard can only be remotely accessed via HTTPS'); + }); +}); + +describe('Agent endpoint no-user mode — remote requests with allowInsecureHTTP', () => { + let server; + let port; + + const noUserConfig = { + apps: [ + { + serverURL: 'http://localhost:1337/parse', + appId: 'testAppId', + masterKey: 'testMasterKey', + appName: 'TestApp', + }, + ], + agent: { + models: [ + { + name: 'test-model', + provider: 'openai', + model: 'gpt-4', + apiKey: 'fake-api-key-for-testing', + }, + ], + }, + }; + + beforeAll((done) => { + const parseDashboard = require('../../../Parse-Dashboard/app.js'); + const dashboardApp = parseDashboard(noUserConfig, { + cookieSessionSecret: SESSION_SECRET, + allowInsecureHTTP: true, + }); + + const parentApp = express(); + // Spoof a non-local remote address before the dashboard middleware + parentApp.use((req, _res, next) => { + Object.defineProperty(req.connection, 'remoteAddress', { + value: '203.0.113.1', + writable: true, + configurable: true, + }); + next(); + }); + parentApp.use('/', dashboardApp); + + server = parentApp.listen(0, () => { + port = server.address().port; + done(); + }); + }); + + afterAll((done) => { + if (server) { + server.close(done); + } else { + done(); + } + }); + + it('returns 401 for remote requests to the agent endpoint in no-user mode when HTTPS is bypassed', async () => { + const res = await makeRequest(port, { + method: 'POST', + path: '/apps/TestApp/agent', + body: agentBody(), + }); + expect(res.status).toBe(401); + expect(res.body.error).toBe('Configure a user to access Parse Dashboard remotely'); + }); +}); diff --git a/src/lib/tests/BrowserRow.test.js b/src/lib/tests/BrowserRow.test.js new file mode 100644 index 0000000000..a75dca43b9 --- /dev/null +++ b/src/lib/tests/BrowserRow.test.js @@ -0,0 +1,107 @@ +jest.dontMock('../../components/BrowserRow/BrowserRow.react'); +jest.mock('idb-keyval'); + +import React from 'react'; +import renderer from 'react-test-renderer'; +const BrowserRow = require('../../components/BrowserRow/BrowserRow.react').default; + +const defaultProps = { + className: 'TestClass', + columns: { + objectId: { type: 'String' }, + name: { type: 'String' }, + }, + currentCol: undefined, + isUnique: false, + obj: { + id: 'abc123', + className: 'TestClass', + attributes: { objectId: 'abc123', name: 'Test' }, + get: function(key) { return this.attributes[key]; }, + }, + order: [ + { name: 'objectId', width: 150, visible: true }, + { name: 'name', width: 150, visible: true }, + ], + readOnlyFields: ['objectId'], + row: 0, + rowWidth: 330, + showRowNumber: true, + rowNumberWidth: 30, + skip: 0, + selection: {}, + selectRow: () => {}, + setCopyableValue: () => {}, + selectedObjectId: undefined, + setSelectedObjectId: () => {}, + callCloudFunction: () => {}, + isPanelVisible: false, + setCurrent: () => {}, + setEditing: () => {}, + setRelation: () => {}, + onEditSelectedRow: () => {}, + setContextMenu: () => {}, + onFilterChange: () => {}, + markRequiredFieldRow: undefined, + onMouseDownRowCheckBox: () => {}, + onMouseUpRowCheckBox: () => {}, + onMouseOverRowCheckBox: () => {}, + onMouseOverRow: () => {}, + onPointerClick: () => {}, + onPointerCmdClick: () => {}, + rowValue: undefined, + stickyLefts: [], + freezeIndex: -1, +}; + +describe('BrowserRow', () => { + describe('Row highlight', () => { + it('should not apply highlight styles when isHighlighted is false', () => { + const component = renderer + .create() + .toJSON(); + // Row div should not have highlight background + expect(component.props.style.background).toBeUndefined(); + }); + + it('should not apply highlight styles when isHighlighted is undefined', () => { + const component = renderer + .create() + .toJSON(); + expect(component.props.style.background).toBeUndefined(); + }); + + it('should apply subtle blue tint to row div when isHighlighted is true', () => { + const component = renderer + .create() + .toJSON(); + expect(component.props.style.background).toBe('#eef4fb'); + }); + + it('should apply stronger blue to checkbox cell when isHighlighted is true', () => { + const component = renderer + .create() + .toJSON(); + // First child is the checkbox span + const checkboxCell = component.children[0]; + expect(checkboxCell.props.style.background).toBe('#d6e4f0'); + }); + + it('should apply stronger blue to row number cell when isHighlighted is true', () => { + const component = renderer + .create() + .toJSON(); + // Second child is the row number span (when showRowNumber is true) + const rowNumberCell = component.children[1]; + expect(rowNumberCell.props.style.background).toBe('#d6e4f0'); + }); + + it('should use default background on checkbox cell when not highlighted', () => { + const component = renderer + .create() + .toJSON(); + const checkboxCell = component.children[0]; + expect(checkboxCell.props.style.background).toBe('#ffffff'); + }); + }); +}); diff --git a/src/lib/tests/ConfigConflictDiff.test.js b/src/lib/tests/ConfigConflictDiff.test.js new file mode 100644 index 0000000000..93addd2e69 --- /dev/null +++ b/src/lib/tests/ConfigConflictDiff.test.js @@ -0,0 +1,93 @@ +jest.dontMock('../../dashboard/Data/Config/ConfigConflictDiff.react'); + +import React from 'react'; +import renderer from 'react-test-renderer'; +const ConfigConflictDiff = require('../../dashboard/Data/Config/ConfigConflictDiff.react').default; + +// Mock the diff library +jest.mock('diff', () => ({ + diffLines: jest.fn((oldStr, newStr) => { + // Simple mock: if strings differ, return removed + added + if (oldStr === newStr) { + return [{ value: oldStr }]; + } + return [ + { value: oldStr, removed: true }, + { value: newStr, added: true }, + ]; + }), + diffChars: jest.fn((oldStr, newStr) => { + if (oldStr === newStr) { + return [{ value: oldStr }]; + } + return [ + { value: oldStr, removed: true }, + { value: newStr, added: true }, + ]; + }), +})); + +describe('ConfigConflictDiff', () => { + it('renders a diff for changed string values', () => { + const component = renderer.create( + + ); + const tree = component.toJSON(); + expect(tree).toBeTruthy(); + // Should have table child + expect(tree.children.length).toBe(1); + }); + + it('renders a diff for changed object values', () => { + const component = renderer.create( + + ); + const tree = component.toJSON(); + expect(tree).toBeTruthy(); + }); + + it('renders empty state when values are identical', () => { + const component = renderer.create( + + ); + const tree = component.toJSON(); + expect(tree.type).toBe('div'); + expect(tree.children[0]).toContain('identical'); + }); + + it('renders a diff for boolean values', () => { + const component = renderer.create( + + ); + const tree = component.toJSON(); + expect(tree).toBeTruthy(); + }); + + it('renders a diff for number values', () => { + const component = renderer.create( + + ); + const tree = component.toJSON(); + expect(tree).toBeTruthy(); + }); +}); diff --git a/src/lib/tests/importData.test.js b/src/lib/tests/importData.test.js new file mode 100644 index 0000000000..486c937480 --- /dev/null +++ b/src/lib/tests/importData.test.js @@ -0,0 +1,787 @@ +/** + * @jest-environment jsdom + */ +/* + * Copyright (c) 2016-present, Parse, LLC + * All rights reserved. + * + * This source code is licensed under the license found in the LICENSE file in + * the root directory of this source tree. + */ +jest.dontMock('../importData'); +jest.dontMock('parse'); + +const Parse = require('parse'); +const { + parseImportJSON, + parseImportCSV, + buildBatchRequests, + sendBatchImport, + checkDuplicates, +} = require('../importData'); + +// ────────────────────────────────────────────── +// parseImportJSON +// ────────────────────────────────────────────── +describe('parseImportJSON', () => { + it('parses a valid JSON array of objects', () => { + const content = JSON.stringify([ + { objectId: 'abc123', name: 'Alice', score: 100 }, + { objectId: 'def456', name: 'Bob', score: 200 }, + ]); + const result = parseImportJSON(content); + expect(result.error).toBeNull(); + expect(result.rows).toHaveLength(2); + expect(result.rows[0]).toEqual({ objectId: 'abc123', name: 'Alice', score: 100 }); + expect(result.rows[1]).toEqual({ objectId: 'def456', name: 'Bob', score: 200 }); + }); + + it('preserves Parse _toFullJSON() typed fields', () => { + const content = JSON.stringify([ + { + objectId: 'xyz', + createdAt: '2024-01-01T00:00:00.000Z', + location: { __type: 'GeoPoint', latitude: 40, longitude: -74 }, + avatar: { __type: 'File', name: 'pic.jpg', url: 'http://example.com/pic.jpg' }, + }, + ]); + const result = parseImportJSON(content); + expect(result.error).toBeNull(); + expect(result.rows[0].location.__type).toBe('GeoPoint'); + expect(result.rows[0].avatar.__type).toBe('File'); + }); + + it('returns error for invalid JSON', () => { + const result = parseImportJSON('not json at all'); + expect(result.rows).toBeNull(); + expect(result.error).toBeTruthy(); + }); + + it('returns error when JSON is not an array', () => { + const result = parseImportJSON(JSON.stringify({ key: 'value' })); + expect(result.rows).toBeNull(); + expect(result.error).toMatch(/array/i); + }); + + it('returns error for an empty array', () => { + const result = parseImportJSON(JSON.stringify([])); + expect(result.rows).toBeNull(); + expect(result.error).toMatch(/empty/i); + }); + + it('returns error when array contains non-object items', () => { + const result = parseImportJSON(JSON.stringify([1, 'hello', null])); + expect(result.rows).toBeNull(); + expect(result.error).toMatch(/row 1.*not an object/i); + }); + + it('returns error for non-object item in middle of array', () => { + const result = parseImportJSON(JSON.stringify([{ name: 'Alice' }, 42])); + expect(result.rows).toBeNull(); + expect(result.error).toMatch(/row 2.*not an object/i); + }); + + it('returns error for null content', () => { + const result = parseImportJSON(null); + expect(result.rows).toBeNull(); + expect(result.error).toBeTruthy(); + }); + + it('returns error for undefined content', () => { + const result = parseImportJSON(undefined); + expect(result.rows).toBeNull(); + expect(result.error).toBeTruthy(); + }); +}); + +// ────────────────────────────────────────────── +// parseImportCSV +// ────────────────────────────────────────────── +describe('parseImportCSV', () => { + it('parses basic CSV with String columns', () => { + const csv = 'name,city\nAlice,NYC\nBob,LA'; + const schema = { + name: { type: 'String' }, + city: { type: 'String' }, + }; + const result = parseImportCSV(csv, schema); + expect(result.error).toBeNull(); + expect(result.rows).toHaveLength(2); + expect(result.rows[0]).toEqual({ name: 'Alice', city: 'NYC' }); + expect(result.rows[1]).toEqual({ name: 'Bob', city: 'LA' }); + }); + + it('converts Number type', () => { + const csv = 'score\n42\n3.14'; + const schema = { score: { type: 'Number' } }; + const result = parseImportCSV(csv, schema); + expect(result.error).toBeNull(); + expect(result.rows[0].score).toBe(42); + expect(result.rows[1].score).toBe(3.14); + }); + + it('converts Boolean type', () => { + const csv = 'active\ntrue\nFalse\nTRUE'; + const schema = { active: { type: 'Boolean' } }; + const result = parseImportCSV(csv, schema); + expect(result.error).toBeNull(); + expect(result.rows[0].active).toBe(true); + expect(result.rows[1].active).toBe(false); + expect(result.rows[2].active).toBe(true); + }); + + it('converts Pointer type', () => { + const csv = 'author\nptr123'; + const schema = { author: { type: 'Pointer', targetClass: '_User' } }; + const result = parseImportCSV(csv, schema); + expect(result.error).toBeNull(); + expect(result.rows[0].author).toEqual({ + __type: 'Pointer', + className: '_User', + objectId: 'ptr123', + }); + }); + + it('skips Relation type columns (cannot be set via batch import)', () => { + const csv = 'name,friends\nAlice,rel456'; + const schema = { name: { type: 'String' }, friends: { type: 'Relation', targetClass: '_User' } }; + const result = parseImportCSV(csv, schema); + expect(result.error).toBeNull(); + expect(result.rows[0].name).toBe('Alice'); + expect(result.rows[0].friends).toBeUndefined(); + }); + + it('converts Date type', () => { + const csv = 'birthday\n2024-01-15T10:30:00.000Z'; + const schema = { birthday: { type: 'Date' } }; + const result = parseImportCSV(csv, schema); + expect(result.error).toBeNull(); + expect(result.rows[0].birthday).toEqual({ + __type: 'Date', + iso: '2024-01-15T10:30:00.000Z', + }); + }); + + it('parses GeoPoint from JSON string', () => { + const geoStr = JSON.stringify({ __type: 'GeoPoint', latitude: 40.7, longitude: -74.0 }); + const csv = `location\n"${geoStr.replace(/"/g, '""')}"`; + const schema = { location: { type: 'GeoPoint' } }; + const result = parseImportCSV(csv, schema); + expect(result.error).toBeNull(); + expect(result.rows[0].location).toEqual({ + __type: 'GeoPoint', + latitude: 40.7, + longitude: -74.0, + }); + }); + + it('parses File from JSON string', () => { + const fileStr = JSON.stringify({ __type: 'File', name: 'pic.jpg', url: 'http://example.com/pic.jpg' }); + const csv = `avatar\n"${fileStr.replace(/"/g, '""')}"`; + const schema = { avatar: { type: 'File' } }; + const result = parseImportCSV(csv, schema); + expect(result.error).toBeNull(); + expect(result.rows[0].avatar).toEqual({ + __type: 'File', + name: 'pic.jpg', + url: 'http://example.com/pic.jpg', + }); + }); + + it('parses Object from JSON string', () => { + const objStr = JSON.stringify({ key: 'value', nested: { a: 1 } }); + const csv = `data\n"${objStr.replace(/"/g, '""')}"`; + const schema = { data: { type: 'Object' } }; + const result = parseImportCSV(csv, schema); + expect(result.error).toBeNull(); + expect(result.rows[0].data).toEqual({ key: 'value', nested: { a: 1 } }); + }); + + it('parses Array from JSON string', () => { + const arrStr = JSON.stringify([1, 2, 3]); + const csv = `tags\n"${arrStr.replace(/"/g, '""')}"`; + const schema = { tags: { type: 'Array' } }; + const result = parseImportCSV(csv, schema); + expect(result.error).toBeNull(); + expect(result.rows[0].tags).toEqual([1, 2, 3]); + }); + + it('parses ACL from JSON string', () => { + const aclStr = JSON.stringify({ '*': { read: true }, 'user123': { read: true, write: true } }); + const csv = `ACL\n"${aclStr.replace(/"/g, '""')}"`; + const schema = { ACL: { type: 'ACL' } }; + const result = parseImportCSV(csv, schema); + expect(result.error).toBeNull(); + expect(result.rows[0].ACL).toEqual({ '*': { read: true }, 'user123': { read: true, write: true } }); + }); + + it('omits empty cells (undefined)', () => { + const csv = 'name,score\nAlice,\n,200'; + const schema = { + name: { type: 'String' }, + score: { type: 'Number' }, + }; + const result = parseImportCSV(csv, schema); + expect(result.error).toBeNull(); + expect(result.rows[0]).toEqual({ name: 'Alice' }); + expect(Object.prototype.hasOwnProperty.call(result.rows[0], 'score')).toBe(false); + expect(result.rows[1]).toEqual({ score: 200 }); + expect(Object.prototype.hasOwnProperty.call(result.rows[1], 'name')).toBe(false); + }); + + it('handles quoted fields with escaped double quotes', () => { + const csv = 'name,bio\nAlice,"She said ""hello"" to Bob"'; + const schema = { + name: { type: 'String' }, + bio: { type: 'String' }, + }; + const result = parseImportCSV(csv, schema); + expect(result.error).toBeNull(); + expect(result.rows[0].bio).toBe('She said "hello" to Bob'); + }); + + it('handles quoted fields with commas inside', () => { + const csv = 'name,address\nAlice,"123 Main St, Apt 4"'; + const schema = { + name: { type: 'String' }, + address: { type: 'String' }, + }; + const result = parseImportCSV(csv, schema); + expect(result.error).toBeNull(); + expect(result.rows[0].address).toBe('123 Main St, Apt 4'); + }); + + it('handles quoted fields with newlines inside', () => { + const csv = 'name,notes\nAlice,"line1\nline2"'; + const schema = { + name: { type: 'String' }, + notes: { type: 'String' }, + }; + const result = parseImportCSV(csv, schema); + expect(result.error).toBeNull(); + expect(result.rows[0].notes).toBe('line1\nline2'); + }); + + it('treats columns without schema as String (default)', () => { + const csv = 'name,unknown\nAlice,something'; + const schema = { name: { type: 'String' } }; + const result = parseImportCSV(csv, schema); + expect(result.error).toBeNull(); + expect(result.rows[0].unknown).toBe('something'); + }); + + it('returns error for empty content', () => { + const result = parseImportCSV('', {}); + expect(result.rows).toBeNull(); + expect(result.error).toMatch(/empty/i); + }); + + it('returns error for header-only CSV (no data rows)', () => { + const result = parseImportCSV('name,score', { name: { type: 'String' } }); + expect(result.rows).toBeNull(); + expect(result.error).toMatch(/no data/i); + }); + + it('handles Windows-style line endings (CRLF)', () => { + const csv = 'name,score\r\nAlice,100\r\nBob,200'; + const schema = { + name: { type: 'String' }, + score: { type: 'Number' }, + }; + const result = parseImportCSV(csv, schema); + expect(result.error).toBeNull(); + expect(result.rows).toHaveLength(2); + expect(result.rows[0]).toEqual({ name: 'Alice', score: 100 }); + }); + + it('returns error for invalid number value', () => { + const csv = 'score\nnot-a-number'; + const schema = { score: { type: 'Number' } }; + const result = parseImportCSV(csv, schema); + expect(result.rows).toBeNull(); + expect(result.error).toMatch(/invalid number/i); + }); + + it('returns error for invalid boolean value', () => { + const csv = 'active\nyes'; + const schema = { active: { type: 'Boolean' } }; + const result = parseImportCSV(csv, schema); + expect(result.rows).toBeNull(); + expect(result.error).toMatch(/invalid boolean/i); + }); + + it('skips blank CSV rows (trailing newlines)', () => { + const csv = 'name,score\nAlice,100\n\n'; + const schema = { + name: { type: 'String' }, + score: { type: 'Number' }, + }; + const result = parseImportCSV(csv, schema); + expect(result.error).toBeNull(); + expect(result.rows).toHaveLength(1); + expect(result.rows[0]).toEqual({ name: 'Alice', score: 100 }); + }); + + it('skips Relation values without leaking undefined into row', () => { + const csv = 'name,friends\nAlice,rel123'; + const schema = { name: { type: 'String' }, friends: { type: 'Relation', targetClass: '_User' } }; + const result = parseImportCSV(csv, schema); + expect(result.error).toBeNull(); + expect(result.rows[0]).toEqual({ name: 'Alice' }); + expect(Object.keys(result.rows[0])).not.toContain('friends'); + }); +}); + +// ────────────────────────────────────────────── +// buildBatchRequests +// ────────────────────────────────────────────── +describe('buildBatchRequests', () => { + const baseRows = [ + { objectId: 'id1', name: 'Alice', score: 100, createdAt: '2024-01-01T00:00:00.000Z', updatedAt: '2024-01-02T00:00:00.000Z' }, + { objectId: 'id2', name: 'Bob', score: 200, createdAt: '2024-02-01T00:00:00.000Z', updatedAt: '2024-02-02T00:00:00.000Z' }, + ]; + + it('creates POST requests stripping objectId when preserveObjectIds=false', () => { + const requests = buildBatchRequests(baseRows, 'GameScore', { + preserveObjectIds: false, + preserveTimestamps: false, + }); + expect(requests).toHaveLength(2); + expect(requests[0].method).toBe('POST'); + expect(requests[0].path).toBe('/classes/GameScore'); + expect(requests[0].body.objectId).toBeUndefined(); + expect(requests[0].body.name).toBe('Alice'); + expect(requests[1].method).toBe('POST'); + expect(requests[1].body.objectId).toBeUndefined(); + }); + + it('creates PUT requests when preserveObjectIds=true and duplicateHandling=overwrite', () => { + const requests = buildBatchRequests(baseRows, 'GameScore', { + preserveObjectIds: true, + preserveTimestamps: false, + duplicateHandling: 'overwrite', + }); + expect(requests).toHaveLength(2); + expect(requests[0].method).toBe('PUT'); + expect(requests[0].path).toBe('/classes/GameScore/id1'); + expect(requests[0].body.objectId).toBeUndefined(); + expect(requests[0].body.name).toBe('Alice'); + expect(requests[1].method).toBe('PUT'); + expect(requests[1].path).toBe('/classes/GameScore/id2'); + }); + + it('creates POST requests with objectId in body when preserveObjectIds=true and duplicateHandling is not overwrite', () => { + const requests = buildBatchRequests(baseRows, 'GameScore', { + preserveObjectIds: true, + preserveTimestamps: false, + duplicateHandling: 'skip', + }); + expect(requests).toHaveLength(2); + expect(requests[0].method).toBe('POST'); + expect(requests[0].path).toBe('/classes/GameScore'); + expect(requests[0].body.objectId).toBe('id1'); + }); + + it('strips createdAt and updatedAt when preserveTimestamps=false', () => { + const requests = buildBatchRequests(baseRows, 'GameScore', { + preserveObjectIds: false, + preserveTimestamps: false, + }); + expect(requests[0].body.createdAt).toBeUndefined(); + expect(requests[0].body.updatedAt).toBeUndefined(); + }); + + it('preserves timestamps as Date objects when preserveTimestamps=true with string dates', () => { + const requests = buildBatchRequests(baseRows, 'GameScore', { + preserveObjectIds: false, + preserveTimestamps: true, + }); + expect(requests[0].body.createdAt).toEqual({ + __type: 'Date', + iso: '2024-01-01T00:00:00.000Z', + }); + expect(requests[0].body.updatedAt).toEqual({ + __type: 'Date', + iso: '2024-01-02T00:00:00.000Z', + }); + }); + + it('preserves timestamps that are already in Date object format', () => { + const rows = [ + { + objectId: 'id1', + name: 'Alice', + createdAt: { __type: 'Date', iso: '2024-01-01T00:00:00.000Z' }, + updatedAt: { __type: 'Date', iso: '2024-01-02T00:00:00.000Z' }, + }, + ]; + const requests = buildBatchRequests(rows, 'GameScore', { + preserveObjectIds: false, + preserveTimestamps: true, + }); + expect(requests[0].body.createdAt).toEqual({ + __type: 'Date', + iso: '2024-01-01T00:00:00.000Z', + }); + }); + + it('filters unknown columns when unknownColumns=ignore', () => { + const rows = [ + { objectId: 'id1', name: 'Alice', score: 100, unknownField: 'foo', anotherUnknown: 'bar' }, + ]; + const requests = buildBatchRequests(rows, 'GameScore', { + preserveObjectIds: false, + preserveTimestamps: false, + unknownColumns: 'ignore', + knownColumns: ['objectId', 'name', 'score', 'createdAt', 'updatedAt'], + }); + expect(requests[0].body.name).toBe('Alice'); + expect(requests[0].body.score).toBe(100); + expect(requests[0].body.unknownField).toBeUndefined(); + expect(requests[0].body.anotherUnknown).toBeUndefined(); + }); + + it('keeps unknown columns when unknownColumns is not ignore', () => { + const rows = [ + { objectId: 'id1', name: 'Alice', unknownField: 'foo' }, + ]; + const requests = buildBatchRequests(rows, 'GameScore', { + preserveObjectIds: false, + preserveTimestamps: false, + unknownColumns: 'create', + knownColumns: ['objectId', 'name'], + }); + expect(requests[0].body.unknownField).toBe('foo'); + }); + + it('handles rows without objectId gracefully', () => { + const rows = [{ name: 'Alice', score: 100 }]; + const requests = buildBatchRequests(rows, 'GameScore', { + preserveObjectIds: false, + preserveTimestamps: false, + }); + expect(requests).toHaveLength(1); + expect(requests[0].method).toBe('POST'); + expect(requests[0].path).toBe('/classes/GameScore'); + expect(requests[0].body).toEqual({ name: 'Alice', score: 100 }); + }); + + it('returns empty array for empty rows', () => { + const requests = buildBatchRequests([], 'GameScore', { + preserveObjectIds: false, + preserveTimestamps: false, + }); + expect(requests).toEqual([]); + }); + + it('skips rows that become empty after filtering and field removal', () => { + const rows = [ + { objectId: 'abc', createdAt: '2024-01-01', updatedAt: '2024-01-01' }, + { objectId: 'def', name: 'Alice', createdAt: '2024-01-01' }, + ]; + const requests = buildBatchRequests(rows, 'GameScore', { + preserveObjectIds: false, + preserveTimestamps: false, + }); + // First row has only system fields → empty after stripping → skipped + // Second row retains name → included + expect(requests).toEqual([ + { method: 'POST', path: '/classes/GameScore', body: { name: 'Alice' } }, + ]); + }); + + it('skips rows that become empty after unknown column filtering', () => { + const rows = [ + { unknownField: 'value' }, + { name: 'Bob', unknownField: 'value' }, + ]; + const requests = buildBatchRequests(rows, 'GameScore', { + preserveObjectIds: false, + preserveTimestamps: false, + unknownColumns: 'ignore', + knownColumns: ['name', 'score'], + }); + expect(requests).toEqual([ + { method: 'POST', path: '/classes/GameScore', body: { name: 'Bob' } }, + ]); + }); +}); + +// ────────────────────────────────────────────── +// sendBatchImport +// ────────────────────────────────────────────── +describe('sendBatchImport', () => { + const baseOptions = { + serverURL: 'http://localhost:1337/parse', + applicationId: 'app1', + masterKey: 'master1', + continueOnError: true, + onProgress: jest.fn(), + }; + + beforeEach(() => { + global.fetch = jest.fn(); + baseOptions.onProgress = jest.fn(); + }); + + afterEach(() => { + delete global.fetch; + }); + + it('sends requests in batches of 50', async () => { + // Create 120 requests to test batching (should be 3 batches: 50, 50, 20) + const requests = Array.from({ length: 120 }, (_, i) => ({ + method: 'POST', + path: '/classes/GameScore', + body: { score: i }, + })); + + global.fetch.mockResolvedValue({ + ok: true, + json: async () => Array.from({ length: 50 }, () => ({ success: {} })), + }); + // Override for last batch + global.fetch + .mockResolvedValueOnce({ ok: true, json: async () => Array.from({ length: 50 }, () => ({ success: {} })) }) + .mockResolvedValueOnce({ ok: true, json: async () => Array.from({ length: 50 }, () => ({ success: {} })) }) + .mockResolvedValueOnce({ ok: true, json: async () => Array.from({ length: 20 }, () => ({ success: {} })) }); + + const result = await sendBatchImport(requests, baseOptions); + expect(global.fetch).toHaveBeenCalledTimes(3); + expect(result.imported).toBe(120); + expect(result.failed).toBe(0); + expect(result.errors).toEqual([]); + expect(result.stopped).toBe(false); + }); + + it('sends correct headers with masterKey', async () => { + const requests = [{ method: 'POST', path: '/classes/GameScore', body: { score: 1 } }]; + global.fetch.mockResolvedValueOnce({ + ok: true, + json: async () => [{ success: {} }], + }); + + await sendBatchImport(requests, baseOptions); + + expect(global.fetch).toHaveBeenCalledWith( + 'http://localhost:1337/parse/batch', + expect.objectContaining({ + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-Parse-Application-Id': 'app1', + 'X-Parse-Master-Key': 'master1', + }, + }) + ); + }); + + it('sends maintenanceKey header when provided', async () => { + const requests = [{ method: 'POST', path: '/classes/GameScore', body: { score: 1 } }]; + global.fetch.mockResolvedValueOnce({ + ok: true, + json: async () => [{ success: {} }], + }); + + await sendBatchImport(requests, { + ...baseOptions, + maintenanceKey: 'maintenance1', + }); + + expect(global.fetch).toHaveBeenCalledWith( + 'http://localhost:1337/parse/batch', + expect.objectContaining({ + headers: { + 'Content-Type': 'application/json', + 'X-Parse-Application-Id': 'app1', + 'X-Parse-Maintenance-Key': 'maintenance1', + }, + }) + ); + }); + + it('sends request body with requests array', async () => { + const requests = [ + { method: 'POST', path: '/classes/GameScore', body: { score: 1 } }, + { method: 'PUT', path: '/classes/GameScore/id1', body: { score: 2 } }, + ]; + global.fetch.mockResolvedValueOnce({ + ok: true, + json: async () => [{ success: {} }, { success: {} }], + }); + + await sendBatchImport(requests, baseOptions); + + const call = global.fetch.mock.calls[0]; + const sentBody = JSON.parse(call[1].body); + // Paths should be prefixed with the server path (e.g., /parse) + expect(sentBody.requests).toEqual([ + { method: 'POST', path: '/parse/classes/GameScore', body: { score: 1 } }, + { method: 'PUT', path: '/parse/classes/GameScore/id1', body: { score: 2 } }, + ]); + }); + + it('counts imported and failed correctly', async () => { + const requests = [ + { method: 'POST', path: '/classes/GameScore', body: { score: 1 } }, + { method: 'POST', path: '/classes/GameScore', body: { score: 2 } }, + { method: 'POST', path: '/classes/GameScore', body: { score: 3 } }, + ]; + global.fetch.mockResolvedValueOnce({ + ok: true, + json: async () => [ + { success: { objectId: 'new1' } }, + { error: { code: 137, error: 'A duplicate value for a field with unique values was provided' } }, + { success: { objectId: 'new3' } }, + ], + }); + + const result = await sendBatchImport(requests, baseOptions); + expect(result.imported).toBe(2); + expect(result.failed).toBe(1); + expect(result.errors).toHaveLength(1); + expect(result.errors[0].index).toBe(1); + expect(result.errors[0].code).toBe(137); + }); + + it('calls onProgress after each batch', async () => { + const requests = Array.from({ length: 75 }, (_, i) => ({ + method: 'POST', + path: '/classes/GameScore', + body: { score: i }, + })); + + global.fetch + .mockResolvedValueOnce({ ok: true, json: async () => Array.from({ length: 50 }, () => ({ success: {} })) }) + .mockResolvedValueOnce({ ok: true, json: async () => Array.from({ length: 25 }, () => ({ success: {} })) }); + + await sendBatchImport(requests, baseOptions); + + expect(baseOptions.onProgress).toHaveBeenCalledTimes(2); + expect(baseOptions.onProgress).toHaveBeenNthCalledWith(1, { completed: 50, total: 75 }); + expect(baseOptions.onProgress).toHaveBeenNthCalledWith(2, { completed: 75, total: 75 }); + }); + + it('stops after first batch with errors when continueOnError=false', async () => { + const requests = Array.from({ length: 75 }, (_, i) => ({ + method: 'POST', + path: '/classes/GameScore', + body: { score: i }, + })); + + global.fetch.mockResolvedValueOnce({ + ok: true, + json: async () => { + const results = Array.from({ length: 50 }, () => ({ success: {} })); + results[10] = { error: { code: 137, error: 'Duplicate' } }; + return results; + }, + }); + + const result = await sendBatchImport(requests, { + ...baseOptions, + continueOnError: false, + }); + + expect(global.fetch).toHaveBeenCalledTimes(1); + expect(result.stopped).toBe(true); + expect(result.imported).toBe(49); + expect(result.failed).toBe(1); + expect(result.errors).toHaveLength(1); + }); + + it('continues all batches when continueOnError=true even with errors', async () => { + const requests = Array.from({ length: 75 }, (_, i) => ({ + method: 'POST', + path: '/classes/GameScore', + body: { score: i }, + })); + + global.fetch + .mockResolvedValueOnce({ + ok: true, + json: async () => { + const results = Array.from({ length: 50 }, () => ({ success: {} })); + results[5] = { error: { code: 137, error: 'Duplicate' } }; + return results; + }, + }) + .mockResolvedValueOnce({ + ok: true, + json: async () => Array.from({ length: 25 }, () => ({ success: {} })), + }); + + const result = await sendBatchImport(requests, { + ...baseOptions, + continueOnError: true, + }); + + expect(global.fetch).toHaveBeenCalledTimes(2); + expect(result.stopped).toBe(false); + expect(result.imported).toBe(74); + expect(result.failed).toBe(1); + }); + + it('handles empty requests array', async () => { + const result = await sendBatchImport([], baseOptions); + expect(result.imported).toBe(0); + expect(result.failed).toBe(0); + expect(result.errors).toEqual([]); + expect(result.stopped).toBe(false); + expect(global.fetch).not.toHaveBeenCalled(); + }); +}); + +// ────────────────────────────────────────────── +// checkDuplicates +// ────────────────────────────────────────────── +describe('checkDuplicates', () => { + let mockFind; + let mockQuery; + + beforeEach(() => { + mockFind = jest.fn().mockResolvedValue([]); + mockQuery = { + containedIn: jest.fn(), + select: jest.fn(), + limit: jest.fn(), + find: mockFind, + }; + jest.spyOn(Parse, 'Query').mockImplementation(() => mockQuery); + }); + + afterEach(() => { + Parse.Query.mockRestore(); + }); + + it('queries with correct className and objectIds', async () => { + await checkDuplicates(['id1', 'id2'], 'GameScore'); + + expect(Parse.Query).toHaveBeenCalledWith('GameScore'); + expect(mockQuery.containedIn).toHaveBeenCalledWith('objectId', ['id1', 'id2']); + expect(mockQuery.select).toHaveBeenCalledWith('objectId'); + expect(mockQuery.limit).toHaveBeenCalledWith(2); + expect(mockFind).toHaveBeenCalledWith({ useMasterKey: true }); + }); + + it('returns objectIds that already exist', async () => { + mockFind.mockResolvedValueOnce([ + { id: 'id1' }, + { id: 'id3' }, + ]); + + const result = await checkDuplicates(['id1', 'id2', 'id3'], 'GameScore'); + expect(result).toEqual(['id1', 'id3']); + }); + + it('returns empty array when no duplicates exist', async () => { + const result = await checkDuplicates(['id1', 'id2'], 'GameScore'); + expect(result).toEqual([]); + }); + + it('returns empty array for empty objectIds input', async () => { + const result = await checkDuplicates([], 'GameScore'); + expect(result).toEqual([]); + expect(Parse.Query).not.toHaveBeenCalled(); + }); +}); diff --git a/testing/preprocessor.js b/testing/preprocessor.js index 32a1956367..d5fc55f3cc 100644 --- a/testing/preprocessor.js +++ b/testing/preprocessor.js @@ -32,10 +32,12 @@ module.exports = { src = src.replace(/from 'stylesheets/g, 'from \'' + relPrefix + 'stylesheets'); src = src.replace(/from 'lib/g, 'from \'' + relPrefix + 'lib'); src = src.replace(/from 'components/g, 'from \'' + relPrefix + 'components'); + src = src.replace(/from 'dashboard/g, 'from \'' + relPrefix + 'dashboard'); - // Ignore all files within node_modules + // Ignore most files within node_modules, but transpile ESM-only packages // babel files can be .js, .es, .jsx or .es6 - if (filename.indexOf('node_modules') < 0 && !filename.endsWith('package.json')) { + const esmPackages = /node_modules[\/\\](marked)[\/\\]/; + if ((filename.indexOf('node_modules') < 0 || esmPackages.test(filename)) && !filename.endsWith('package.json')) { return babel.transform(src, { filename: filename, retainLines: true, diff --git a/webpack/base.config.js b/webpack/base.config.js index 8f1bb1c83d..a91a1af961 100644 --- a/webpack/base.config.js +++ b/webpack/base.config.js @@ -48,7 +48,9 @@ module.exports = { { loader: 'css-loader', options: { - modules: true, + modules: { + namedExport: false, + }, importLoaders: 2, }, }, @@ -76,7 +78,7 @@ module.exports = { }, { test: /\.flow$/, - use: 'null-loader', + type: 'asset/source', }, ], }, diff --git a/webpack/plugins/svg-prep.js b/webpack/plugins/svg-prep.js index af6a70f4cb..b5db1bdfa8 100644 --- a/webpack/plugins/svg-prep.js +++ b/webpack/plugins/svg-prep.js @@ -9,10 +9,57 @@ const fs = require('fs'); const path = require('path'); -const SvgPrep = require('svg-prep'); const { Compilation, sources } = require('webpack'); const { RawSource } = sources; +/** + * Builds an SVG sprite from individual SVG files. Each SVG becomes a + * element identified by its filename (without extension). + */ +function buildSvgSprite(files) { + const symbols = files.map(file => { + const name = path.basename(file, '.svg'); + const svg = fs.readFileSync(file, 'utf-8'); + + // Extract viewBox from the root element + const viewBoxMatch = svg.match(/viewBox="([^"]*)"/); + const viewBox = viewBoxMatch ? viewBoxMatch[1] : '0 0 100 100'; + + // Extract inner content between and + const innerMatch = svg.match(/]*>([\s\S]*)<\/svg>/); + const inner = innerMatch ? innerMatch[1] : ''; + + // Strip elements that are unnecessary or potential XSS vectors + // Remove attributes that interfere with sprite styling or pose security risks + const cleaned = inner + .replace(//gi, '') + .replace(//gi, '') + .replace(//gi, '') + .replace(//gi, '') + .replace(//gi, '') + .replace(//g, '') + .replace(/\s+id="[^"]*"/g, '') + .replace(/\s+fill="[^"]*"/g, '') + .replace(/\s+class="[^"]*"/g, '') + .replace(/\s+style="[^"]*"/g, '') + .replace(/\s+stroke="[^"]*"/g, '') + .replace(/\s+stroke-[a-z]+="[^"]*"/g, '') + .replace(/\s+on[a-zA-Z]+="[^"]*"/g, '') + .replace(/\s+on[a-zA-Z]+='[^']*'/g, '') + .replace(/\s+href="[^"]*"/g, '') + .replace(/\s+xlink:href="[^"]*"/g, ''); + + return ` \n ${cleaned.trim()}\n `; + }); + + return [ + '', + '', + ].join('\n'); +} + function SvgPrepPlugin(options) { this.options = {}; Object.assign( @@ -33,17 +80,16 @@ SvgPrepPlugin.prototype.apply = function (compiler) { }, async () => { if (!this.options.source) { - return Promise.resolve(); + return; } - // TODO: Keep track of file hashes, so we can avoid recompiling when none have changed const files = fs .readdirSync(this.options.source) .filter(name => name.endsWith('.svg')) + .sort() .map(name => path.join(this.options.source, name)); - const sprited = await SvgPrep(files).filter({ removeIds: true, noFill: true }).output(); - + const sprited = buildSvgSprite(files); compilation.emitAsset(this.options.output, new RawSource(sprited)); } );