From 7a51fca2f92c793202a092e12acaa7b1a955105b Mon Sep 17 00:00:00 2001 From: Gregor Vostrak Date: Tue, 2 Dec 2025 13:30:08 +0100 Subject: [PATCH 001/115] only show Weekly Billable Amount of current organization on dashboard, fixes #977 --- app/Service/DashboardService.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/Service/DashboardService.php b/app/Service/DashboardService.php index 456a782b..250bc7f9 100644 --- a/app/Service/DashboardService.php +++ b/app/Service/DashboardService.php @@ -266,7 +266,8 @@ public function totalWeeklyBillableAmount(User $user, Organization $organization ) as aggregate')) ->where('billable', '=', true) ->whereNotNull('billable_rate') - ->where('user_id', '=', $user->id); + ->where('user_id', '=', $user->getKey()) + ->where('organization_id', '=', $organization->getKey()); $query = $this->constrainDateByPossibleDates($query, $possibleDays, $timezone); /** @var Collection $resultDb */ From 814d539fb00e9d1114459436bd482a29f9a96233 Mon Sep 17 00:00:00 2001 From: Gregor Vostrak Date: Tue, 2 Dec 2025 17:46:58 +0100 Subject: [PATCH 002/115] move rangecalendar, popover and daterangepicker to ui package --- .../Common/Reporting/ReportingRoundingControls.vue | 2 +- .../Components/ui/calendar/CalendarDateInput.vue | 2 +- .../js/packages/ui/src/Input/DateRangePicker.vue | 4 ++-- resources/js/packages/ui/src/Input/Dropdown.vue | 2 +- .../ui => packages/ui/src}/accordion/Accordion.vue | 0 .../ui/src}/accordion/AccordionContent.vue | 2 +- .../ui/src}/accordion/AccordionItem.vue | 2 +- .../ui/src}/accordion/AccordionTrigger.vue | 2 +- .../ui => packages/ui/src}/accordion/index.ts | 0 resources/js/packages/ui/src/index.ts | 14 ++++++++++++++ .../ui => packages/ui/src}/popover/Popover.vue | 0 .../ui/src}/popover/PopoverContent.vue | 0 .../ui/src}/popover/PopoverTrigger.vue | 0 .../ui => packages/ui/src}/popover/index.ts | 0 .../ui/src}/range-calendar/RangeCalendar.vue | 0 .../ui/src}/range-calendar/RangeCalendarCell.vue | 0 .../range-calendar/RangeCalendarCellTrigger.vue | 0 .../ui/src}/range-calendar/RangeCalendarGrid.vue | 0 .../src}/range-calendar/RangeCalendarGridBody.vue | 0 .../src}/range-calendar/RangeCalendarGridHead.vue | 0 .../src}/range-calendar/RangeCalendarGridRow.vue | 0 .../src}/range-calendar/RangeCalendarHeadCell.vue | 0 .../ui/src}/range-calendar/RangeCalendarHeader.vue | 0 .../src}/range-calendar/RangeCalendarHeading.vue | 0 .../range-calendar/RangeCalendarNextButton.vue | 0 .../range-calendar/RangeCalendarPrevButton.vue | 0 .../ui => packages/ui/src}/range-calendar/index.ts | 0 27 files changed, 22 insertions(+), 8 deletions(-) rename resources/js/{Components/ui => packages/ui/src}/accordion/Accordion.vue (100%) rename resources/js/{Components/ui => packages/ui/src}/accordion/AccordionContent.vue (95%) rename resources/js/{Components/ui => packages/ui/src}/accordion/AccordionItem.vue (94%) rename resources/js/{Components/ui => packages/ui/src}/accordion/AccordionTrigger.vue (96%) rename resources/js/{Components/ui => packages/ui/src}/accordion/index.ts (100%) rename resources/js/{Components/ui => packages/ui/src}/popover/Popover.vue (100%) rename resources/js/{Components/ui => packages/ui/src}/popover/PopoverContent.vue (100%) rename resources/js/{Components/ui => packages/ui/src}/popover/PopoverTrigger.vue (100%) rename resources/js/{Components/ui => packages/ui/src}/popover/index.ts (100%) rename resources/js/{Components/ui => packages/ui/src}/range-calendar/RangeCalendar.vue (100%) rename resources/js/{Components/ui => packages/ui/src}/range-calendar/RangeCalendarCell.vue (100%) rename resources/js/{Components/ui => packages/ui/src}/range-calendar/RangeCalendarCellTrigger.vue (100%) rename resources/js/{Components/ui => packages/ui/src}/range-calendar/RangeCalendarGrid.vue (100%) rename resources/js/{Components/ui => packages/ui/src}/range-calendar/RangeCalendarGridBody.vue (100%) rename resources/js/{Components/ui => packages/ui/src}/range-calendar/RangeCalendarGridHead.vue (100%) rename resources/js/{Components/ui => packages/ui/src}/range-calendar/RangeCalendarGridRow.vue (100%) rename resources/js/{Components/ui => packages/ui/src}/range-calendar/RangeCalendarHeadCell.vue (100%) rename resources/js/{Components/ui => packages/ui/src}/range-calendar/RangeCalendarHeader.vue (100%) rename resources/js/{Components/ui => packages/ui/src}/range-calendar/RangeCalendarHeading.vue (100%) rename resources/js/{Components/ui => packages/ui/src}/range-calendar/RangeCalendarNextButton.vue (100%) rename resources/js/{Components/ui => packages/ui/src}/range-calendar/RangeCalendarPrevButton.vue (100%) rename resources/js/{Components/ui => packages/ui/src}/range-calendar/index.ts (100%) diff --git a/resources/js/Components/Common/Reporting/ReportingRoundingControls.vue b/resources/js/Components/Common/Reporting/ReportingRoundingControls.vue index 46820659..2efe0c4e 100644 --- a/resources/js/Components/Common/Reporting/ReportingRoundingControls.vue +++ b/resources/js/Components/Common/Reporting/ReportingRoundingControls.vue @@ -1,6 +1,6 @@ diff --git a/resources/js/packages/ui/src/TimezoneMismatchModal.vue b/resources/js/packages/ui/src/TimezoneMismatchModal.vue new file mode 100644 index 00000000..31cf61f3 --- /dev/null +++ b/resources/js/packages/ui/src/TimezoneMismatchModal.vue @@ -0,0 +1,109 @@ + + + + + diff --git a/resources/js/packages/ui/src/index.ts b/resources/js/packages/ui/src/index.ts index 9ef17a62..2b623271 100644 --- a/resources/js/packages/ui/src/index.ts +++ b/resources/js/packages/ui/src/index.ts @@ -38,6 +38,7 @@ import FullCalendarEventContent from './FullCalendar/FullCalendarEventContent.vu import FullCalendarDayHeader from './FullCalendar/FullCalendarDayHeader.vue'; import TimeEntryCalendar from './FullCalendar/TimeEntryCalendar.vue'; import DateRangePicker from './Input/DateRangePicker.vue'; +import TimezoneMismatchModal from './TimezoneMismatchModal.vue'; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from './tooltip/index'; import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from './accordion/index'; import { Popover, PopoverContent, PopoverTrigger, PopoverAnchor } from './popover/index'; @@ -74,6 +75,7 @@ export { FullCalendarDayHeader, TimeEntryCalendar, DateRangePicker, + TimezoneMismatchModal, Tooltip, TooltipContent, TooltipProvider, From 0691fe10ef37e6df0fbdd7dcead587c828cf64de Mon Sep 17 00:00:00 2001 From: Gregor Vostrak Date: Tue, 9 Dec 2025 14:00:53 +0100 Subject: [PATCH 005/115] add direct axios dependency to package, bump package versions --- resources/js/packages/api/package-lock.json | 193 +++- resources/js/packages/api/package.json | 3 +- resources/js/packages/ui/package-lock.json | 991 ++++++-------------- resources/js/packages/ui/package.json | 2 +- 4 files changed, 462 insertions(+), 727 deletions(-) diff --git a/resources/js/packages/api/package-lock.json b/resources/js/packages/api/package-lock.json index 4e372d27..df2d3a3a 100644 --- a/resources/js/packages/api/package-lock.json +++ b/resources/js/packages/api/package-lock.json @@ -1,15 +1,16 @@ { "name": "@solidtime/api", - "version": "0.0.5", + "version": "0.0.6", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@solidtime/api", - "version": "0.0.5", + "version": "0.0.6", "license": "AGPL-3.0", "dependencies": { "@zodios/core": "^10.9.6", + "axios": "^1.13.2", "typescript": "^5.5.4", "zod": "^3.23.8" }, @@ -1094,18 +1095,16 @@ "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/axios": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.5.tgz", - "integrity": "sha512-fZu86yCo+svH3uqJ/yTdQ0QHpQu5oL+/QE+QPSv6BZSkDAoky9vytxp7u5qk83OJFS3kEBcesWni9WTZAv3tSw==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.2.tgz", + "integrity": "sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==", "license": "MIT", - "peer": true, "dependencies": { "follow-redirects": "^1.15.6", - "form-data": "^4.0.0", + "form-data": "^4.0.4", "proxy-from-env": "^1.1.0" } }, @@ -1127,12 +1126,24 @@ "concat-map": "0.0.1" } }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "license": "MIT", - "peer": true, "dependencies": { "delayed-stream": "~1.0.0" }, @@ -1198,11 +1209,24 @@ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "license": "MIT", - "peer": true, "engines": { "node": ">=0.4.0" } }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/entities": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", @@ -1216,6 +1240,51 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/esbuild": { "version": "0.21.5", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", @@ -1280,7 +1349,6 @@ } ], "license": "MIT", - "peer": true, "engines": { "node": ">=4.0" }, @@ -1291,14 +1359,15 @@ } }, "node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", + "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", "license": "MIT", - "peer": true, "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", "mime-types": "^2.1.12" }, "engines": { @@ -1339,12 +1408,60 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", @@ -1362,11 +1479,37 @@ "node": ">=8" } }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/hasown": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dev": true, "license": "MIT", "dependencies": { "function-bind": "^1.1.2" @@ -1489,12 +1632,20 @@ "@jridgewell/sourcemap-codec": "^1.5.0" } }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "license": "MIT", - "peer": true, "engines": { "node": ">= 0.6" } @@ -1504,7 +1655,6 @@ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "license": "MIT", - "peer": true, "dependencies": { "mime-db": "1.52.0" }, @@ -1657,8 +1807,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/punycode": { "version": "2.3.1", diff --git a/resources/js/packages/api/package.json b/resources/js/packages/api/package.json index c9ad514f..7c25c473 100644 --- a/resources/js/packages/api/package.json +++ b/resources/js/packages/api/package.json @@ -1,6 +1,6 @@ { "name": "@solidtime/api", - "version": "0.0.5", + "version": "0.0.6", "description": "Package containing the solidtime api client and type declarations", "main": "./dist/solidtime-api.umd.cjs", "module": "./dist/solidtime-api.js", @@ -29,6 +29,7 @@ "license": "AGPL-3.0", "dependencies": { "@zodios/core": "^10.9.6", + "axios": "^1.13.2", "typescript": "^5.5.4", "zod": "^3.23.8" }, diff --git a/resources/js/packages/ui/package-lock.json b/resources/js/packages/ui/package-lock.json index 3e620e15..eb2eab44 100644 --- a/resources/js/packages/ui/package-lock.json +++ b/resources/js/packages/ui/package-lock.json @@ -1,12 +1,12 @@ { "name": "@solidtime/ui", - "version": "0.0.13", + "version": "0.0.14", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@solidtime/ui", - "version": "0.0.13", + "version": "0.0.14", "license": "AGPL-3.0", "devDependencies": { "@types/node": "^22.4.1", @@ -652,24 +652,6 @@ "node": "20 || >=22" } }, - "node_modules/@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "license": "ISC", - "peer": true, - "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.13", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", @@ -709,19 +691,19 @@ } }, "node_modules/@microsoft/api-extractor": { - "version": "7.55.0", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.55.0.tgz", - "integrity": "sha512-TYc5OtAK/9E3HGgd2bIfSjQDYIwPc0dysf9rPiwXZGsq916I6W2oww9bhm1OxPOeg6rMfOX3PoroGd7oCryYog==", + "version": "7.55.1", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.55.1.tgz", + "integrity": "sha512-l8Z+8qrLkZFM3HM95Dbpqs6G39fpCa7O5p8A7AkA6hSevxkgwsOlLrEuPv0ADOyj5dI1Af5WVDiwpKG/ya5G3w==", "dev": true, "license": "MIT", "dependencies": { - "@microsoft/api-extractor-model": "7.32.0", + "@microsoft/api-extractor-model": "7.32.1", "@microsoft/tsdoc": "~0.16.0", "@microsoft/tsdoc-config": "~0.18.0", - "@rushstack/node-core-library": "5.18.0", + "@rushstack/node-core-library": "5.19.0", "@rushstack/rig-package": "0.6.0", - "@rushstack/terminal": "0.19.3", - "@rushstack/ts-command-line": "5.1.3", + "@rushstack/terminal": "0.19.4", + "@rushstack/ts-command-line": "5.1.4", "diff": "~8.0.2", "lodash": "~4.17.15", "minimatch": "10.0.3", @@ -735,31 +717,15 @@ } }, "node_modules/@microsoft/api-extractor-model": { - "version": "7.32.0", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.32.0.tgz", - "integrity": "sha512-QIVJSreb8fGGJy1Qx0yzGVXxvHJN1WXgkFNHFheVv1iBJNqgvp+xeT3ienJmRwXmPPc5Es/cxBrXtKZJR3i7iw==", + "version": "7.32.1", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.32.1.tgz", + "integrity": "sha512-u4yJytMYiUAnhcNQcZDTh/tVtlrzKlyKrQnLOV+4Qr/5gV+cpufWzCYAB1Q23URFqD6z2RoL2UYncM9xJVGNKA==", "dev": true, "license": "MIT", "dependencies": { "@microsoft/tsdoc": "~0.16.0", "@microsoft/tsdoc-config": "~0.18.0", - "@rushstack/node-core-library": "5.18.0" - } - }, - "node_modules/@microsoft/api-extractor/node_modules/minimatch": { - "version": "10.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.3.tgz", - "integrity": "sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==", - "dev": true, - "license": "ISC", - "dependencies": { - "@isaacs/brace-expansion": "^5.0.0" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "@rushstack/node-core-library": "5.19.0" } }, "node_modules/@microsoft/api-extractor/node_modules/typescript": { @@ -834,17 +800,6 @@ "node": ">= 8" } }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "license": "MIT", - "optional": true, - "peer": true, - "engines": { - "node": ">=14" - } - }, "node_modules/@rollup/pluginutils": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.3.0.tgz", @@ -882,9 +837,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.53.2.tgz", - "integrity": "sha512-yDPzwsgiFO26RJA4nZo8I+xqzh7sJTZIWQOxn+/XOdPE31lAvLIYCKqjV+lNH/vxE2L2iH3plKxDCRK6i+CwhA==", + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.53.3.tgz", + "integrity": "sha512-mRSi+4cBjrRLoaal2PnqH82Wqyb+d3HsPUN/W+WslCXsZsyHa9ZeQQX/pQsZaVIWDkPcpV6jJ+3KLbTbgnwv8w==", "cpu": [ "arm" ], @@ -896,9 +851,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.53.2.tgz", - "integrity": "sha512-k8FontTxIE7b0/OGKeSN5B6j25EuppBcWM33Z19JoVT7UTXFSo3D9CdU39wGTeb29NO3XxpMNauh09B+Ibw+9g==", + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.53.3.tgz", + "integrity": "sha512-CbDGaMpdE9sh7sCmTrTUyllhrg65t6SwhjlMJsLr+J8YjFuPmCEjbBSx4Z/e4SmDyH3aB5hGaJUP2ltV/vcs4w==", "cpu": [ "arm64" ], @@ -910,9 +865,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.53.2.tgz", - "integrity": "sha512-A6s4gJpomNBtJ2yioj8bflM2oogDwzUiMl2yNJ2v9E7++sHrSrsQ29fOfn5DM/iCzpWcebNYEdXpaK4tr2RhfQ==", + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.53.3.tgz", + "integrity": "sha512-Nr7SlQeqIBpOV6BHHGZgYBuSdanCXuw09hon14MGOLGmXAFYjx1wNvquVPmpZnl0tLjg25dEdr4IQ6GgyToCUA==", "cpu": [ "arm64" ], @@ -924,9 +879,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.53.2.tgz", - "integrity": "sha512-e6XqVmXlHrBlG56obu9gDRPW3O3hLxpwHpLsBJvuI8qqnsrtSZ9ERoWUXtPOkY8c78WghyPHZdmPhHLWNdAGEw==", + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.53.3.tgz", + "integrity": "sha512-DZ8N4CSNfl965CmPktJ8oBnfYr3F8dTTNBQkRlffnUarJ2ohudQD17sZBa097J8xhQ26AwhHJ5mvUyQW8ddTsQ==", "cpu": [ "x64" ], @@ -938,9 +893,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.53.2.tgz", - "integrity": "sha512-v0E9lJW8VsrwPux5Qe5CwmH/CF/2mQs6xU1MF3nmUxmZUCHazCjLgYvToOk+YuuUqLQBio1qkkREhxhc656ViA==", + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.53.3.tgz", + "integrity": "sha512-yMTrCrK92aGyi7GuDNtGn2sNW+Gdb4vErx4t3Gv/Tr+1zRb8ax4z8GWVRfr3Jw8zJWvpGHNpss3vVlbF58DZ4w==", "cpu": [ "arm64" ], @@ -952,9 +907,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.53.2.tgz", - "integrity": "sha512-ClAmAPx3ZCHtp6ysl4XEhWU69GUB1D+s7G9YjHGhIGCSrsg00nEGRRZHmINYxkdoJehde8VIsDC5t9C0gb6yqA==", + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.53.3.tgz", + "integrity": "sha512-lMfF8X7QhdQzseM6XaX0vbno2m3hlyZFhwcndRMw8fbAGUGL3WFMBdK0hbUBIUYcEcMhVLr1SIamDeuLBnXS+Q==", "cpu": [ "x64" ], @@ -966,9 +921,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.53.2.tgz", - "integrity": "sha512-EPlb95nUsz6Dd9Qy13fI5kUPXNSljaG9FiJ4YUGU1O/Q77i5DYFW5KR8g1OzTcdZUqQQ1KdDqsTohdFVwCwjqg==", + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.53.3.tgz", + "integrity": "sha512-k9oD15soC/Ln6d2Wv/JOFPzZXIAIFLp6B+i14KhxAfnq76ajt0EhYc5YPeX6W1xJkAdItcVT+JhKl1QZh44/qw==", "cpu": [ "arm" ], @@ -980,9 +935,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.53.2.tgz", - "integrity": "sha512-BOmnVW+khAUX+YZvNfa0tGTEMVVEerOxN0pDk2E6N6DsEIa2Ctj48FOMfNDdrwinocKaC7YXUZ1pHlKpnkja/Q==", + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.53.3.tgz", + "integrity": "sha512-vTNlKq+N6CK/8UktsrFuc+/7NlEYVxgaEgRXVUVK258Z5ymho29skzW1sutgYjqNnquGwVUObAaxae8rZ6YMhg==", "cpu": [ "arm" ], @@ -994,9 +949,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.53.2.tgz", - "integrity": "sha512-Xt2byDZ+6OVNuREgBXr4+CZDJtrVso5woFtpKdGPhpTPHcNG7D8YXeQzpNbFRxzTVqJf7kvPMCub/pcGUWgBjA==", + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.53.3.tgz", + "integrity": "sha512-RGrFLWgMhSxRs/EWJMIFM1O5Mzuz3Xy3/mnxJp/5cVhZ2XoCAxJnmNsEyeMJtpK+wu0FJFWz+QF4mjCA7AUQ3w==", "cpu": [ "arm64" ], @@ -1008,9 +963,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.53.2.tgz", - "integrity": "sha512-+LdZSldy/I9N8+klim/Y1HsKbJ3BbInHav5qE9Iy77dtHC/pibw1SR/fXlWyAk0ThnpRKoODwnAuSjqxFRDHUQ==", + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.53.3.tgz", + "integrity": "sha512-kASyvfBEWYPEwe0Qv4nfu6pNkITLTb32p4yTgzFCocHnJLAHs+9LjUu9ONIhvfT/5lv4YS5muBHyuV84epBo/A==", "cpu": [ "arm64" ], @@ -1022,9 +977,9 @@ ] }, "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.53.2.tgz", - "integrity": "sha512-8ms8sjmyc1jWJS6WdNSA23rEfdjWB30LH8Wqj0Cqvv7qSHnvw6kgMMXRdop6hkmGPlyYBdRPkjJnj3KCUHV/uQ==", + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.53.3.tgz", + "integrity": "sha512-JiuKcp2teLJwQ7vkJ95EwESWkNRFJD7TQgYmCnrPtlu50b4XvT5MOmurWNrCj3IFdyjBQ5p9vnrX4JM6I8OE7g==", "cpu": [ "loong64" ], @@ -1036,9 +991,9 @@ ] }, "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.53.2.tgz", - "integrity": "sha512-3HRQLUQbpBDMmzoxPJYd3W6vrVHOo2cVW8RUo87Xz0JPJcBLBr5kZ1pGcQAhdZgX9VV7NbGNipah1omKKe23/g==", + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.53.3.tgz", + "integrity": "sha512-EoGSa8nd6d3T7zLuqdojxC20oBfNT8nexBbB/rkxgKj5T5vhpAQKKnD+h3UkoMuTyXkP5jTjK/ccNRmQrPNDuw==", "cpu": [ "ppc64" ], @@ -1050,9 +1005,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.53.2.tgz", - "integrity": "sha512-fMjKi+ojnmIvhk34gZP94vjogXNNUKMEYs+EDaB/5TG/wUkoeua7p7VCHnE6T2Tx+iaghAqQX8teQzcvrYpaQA==", + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.53.3.tgz", + "integrity": "sha512-4s+Wped2IHXHPnAEbIB0YWBv7SDohqxobiiPA1FIWZpX+w9o2i4LezzH/NkFUl8LRci/8udci6cLq+jJQlh+0g==", "cpu": [ "riscv64" ], @@ -1064,9 +1019,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.53.2.tgz", - "integrity": "sha512-XuGFGU+VwUUV5kLvoAdi0Wz5Xbh2SrjIxCtZj6Wq8MDp4bflb/+ThZsVxokM7n0pcbkEr2h5/pzqzDYI7cCgLQ==", + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.53.3.tgz", + "integrity": "sha512-68k2g7+0vs2u9CxDt5ktXTngsxOQkSEV/xBbwlqYcUrAVh6P9EgMZvFsnHy4SEiUl46Xf0IObWVbMvPrr2gw8A==", "cpu": [ "riscv64" ], @@ -1078,9 +1033,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.53.2.tgz", - "integrity": "sha512-w6yjZF0P+NGzWR3AXWX9zc0DNEGdtvykB03uhonSHMRa+oWA6novflo2WaJr6JZakG2ucsyb+rvhrKac6NIy+w==", + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.53.3.tgz", + "integrity": "sha512-VYsFMpULAz87ZW6BVYw3I6sWesGpsP9OPcyKe8ofdg9LHxSbRMd7zrVrr5xi/3kMZtpWL/wC+UIJWJYVX5uTKg==", "cpu": [ "s390x" ], @@ -1092,9 +1047,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.53.2.tgz", - "integrity": "sha512-yo8d6tdfdeBArzC7T/PnHd7OypfI9cbuZzPnzLJIyKYFhAQ8SvlkKtKBMbXDxe1h03Rcr7u++nFS7tqXz87Gtw==", + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.53.3.tgz", + "integrity": "sha512-3EhFi1FU6YL8HTUJZ51imGJWEX//ajQPfqWLI3BQq4TlvHy4X0MOr5q3D2Zof/ka0d5FNdPwZXm3Yyib/UEd+w==", "cpu": [ "x64" ], @@ -1106,9 +1061,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.53.2.tgz", - "integrity": "sha512-ah59c1YkCxKExPP8O9PwOvs+XRLKwh/mV+3YdKqQ5AMQ0r4M4ZDuOrpWkUaqO7fzAHdINzV9tEVu8vNw48z0lA==", + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.53.3.tgz", + "integrity": "sha512-eoROhjcc6HbZCJr+tvVT8X4fW3/5g/WkGvvmwz/88sDtSJzO7r/blvoBDgISDiCjDRZmHpwud7h+6Q9JxFwq1Q==", "cpu": [ "x64" ], @@ -1120,9 +1075,9 @@ ] }, "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.53.2.tgz", - "integrity": "sha512-4VEd19Wmhr+Zy7hbUsFZ6YXEiP48hE//KPLCSVNY5RMGX2/7HZ+QkN55a3atM1C/BZCGIgqN+xrVgtdak2S9+A==", + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.53.3.tgz", + "integrity": "sha512-OueLAWgrNSPGAdUdIjSWXw+u/02BRTcnfw9PN41D2vq/JSEPnJnVuBgw18VkN8wcd4fjUs+jFHVM4t9+kBSNLw==", "cpu": [ "arm64" ], @@ -1134,9 +1089,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.53.2.tgz", - "integrity": "sha512-IlbHFYc/pQCgew/d5fslcy1KEaYVCJ44G8pajugd8VoOEI8ODhtb/j8XMhLpwHCMB3yk2J07ctup10gpw2nyMA==", + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.53.3.tgz", + "integrity": "sha512-GOFuKpsxR/whszbF/bzydebLiXIHSgsEUp6M0JI8dWvi+fFa1TD6YQa4aSZHtpmh2/uAlj/Dy+nmby3TJ3pkTw==", "cpu": [ "arm64" ], @@ -1148,9 +1103,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.53.2.tgz", - "integrity": "sha512-lNlPEGgdUfSzdCWU176ku/dQRnA7W+Gp8d+cWv73jYrb8uT7HTVVxq62DUYxjbaByuf1Yk0RIIAbDzp+CnOTFg==", + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.53.3.tgz", + "integrity": "sha512-iah+THLcBJdpfZ1TstDFbKNznlzoxa8fmnFYK4V67HvmuNYkVdAywJSoteUszvBQ9/HqN2+9AZghbajMsFT+oA==", "cpu": [ "ia32" ], @@ -1162,9 +1117,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.53.2.tgz", - "integrity": "sha512-S6YojNVrHybQis2lYov1sd+uj7K0Q05NxHcGktuMMdIQ2VixGwAfbJ23NnlvvVV1bdpR2m5MsNBViHJKcA4ADw==", + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.53.3.tgz", + "integrity": "sha512-J9QDiOIZlZLdcot5NXEepDkstocktoVjkaKUtqzgzpt2yWjGlbYiKyp05rWwk4nypbYUNoFAztEgixoLaSETkg==", "cpu": [ "x64" ], @@ -1176,9 +1131,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.53.2.tgz", - "integrity": "sha512-k+/Rkcyx//P6fetPoLMb8pBeqJBNGx81uuf7iljX9++yNBVRDQgD04L+SVXmXmh5ZP4/WOp4mWF0kmi06PW2tA==", + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.53.3.tgz", + "integrity": "sha512-UhTd8u31dXadv0MopwGgNOBpUVROFKWVQgAg5N1ESyCz8AuBcMqm4AuTjrwgQKGDfoFuz02EuMRHQIw/frmYKQ==", "cpu": [ "x64" ], @@ -1190,9 +1145,9 @@ ] }, "node_modules/@rushstack/node-core-library": { - "version": "5.18.0", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.18.0.tgz", - "integrity": "sha512-XDebtBdw5S3SuZIt+Ra2NieT8kQ3D2Ow1HxhDQ/2soinswnOu9e7S69VSwTOLlQnx5mpWbONu+5JJjDxMAb6Fw==", + "version": "5.19.0", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.19.0.tgz", + "integrity": "sha512-BxAopbeWBvNJ6VGiUL+5lbJXywTdsnMeOS8j57Cn/xY10r6sV/gbsTlfYKjzVCUBZATX2eRzJHSMCchsMTGN6A==", "dev": true, "license": "MIT", "dependencies": { @@ -1258,13 +1213,13 @@ } }, "node_modules/@rushstack/terminal": { - "version": "0.19.3", - "resolved": "https://registry.npmjs.org/@rushstack/terminal/-/terminal-0.19.3.tgz", - "integrity": "sha512-0P8G18gK9STyO+CNBvkKPnWGMxESxecTYqOcikHOVIHXa9uAuTK+Fw8TJq2Gng1w7W6wTC9uPX6hGNvrMll2wA==", + "version": "0.19.4", + "resolved": "https://registry.npmjs.org/@rushstack/terminal/-/terminal-0.19.4.tgz", + "integrity": "sha512-f4XQk02CrKfrMgyOfhYd3qWI944dLC21S4I/LUhrlAP23GTMDNG6EK5effQtFkISwUKCgD9vMBrJZaPSUquxWQ==", "dev": true, "license": "MIT", "dependencies": { - "@rushstack/node-core-library": "5.18.0", + "@rushstack/node-core-library": "5.19.0", "@rushstack/problem-matcher": "0.1.1", "supports-color": "~8.1.1" }, @@ -1278,13 +1233,13 @@ } }, "node_modules/@rushstack/ts-command-line": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-5.1.3.tgz", - "integrity": "sha512-Kdv0k/BnnxIYFlMVC1IxrIS0oGQd4T4b7vKfx52Y2+wk2WZSDFIvedr7JrhenzSlm3ou5KwtoTGTGd5nbODRug==", + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-5.1.4.tgz", + "integrity": "sha512-H0I6VdJ6sOUbktDFpP2VW5N29w8v4hRoNZOQz02vtEi6ZTYL1Ju8u+TcFiFawUDrUsx/5MQTUhd79uwZZVwVlA==", "dev": true, "license": "MIT", "dependencies": { - "@rushstack/terminal": "0.19.3", + "@rushstack/terminal": "0.19.4", "@types/argparse": "1.0.38", "argparse": "~1.0.9", "string-argv": "~0.3.1" @@ -1374,69 +1329,69 @@ } }, "node_modules/@volar/language-core": { - "version": "2.4.23", - "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-2.4.23.tgz", - "integrity": "sha512-hEEd5ET/oSmBC6pi1j6NaNYRWoAiDhINbT8rmwtINugR39loROSlufGdYMF9TaKGfz+ViGs1Idi3mAhnuPcoGQ==", + "version": "2.4.26", + "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-2.4.26.tgz", + "integrity": "sha512-hH0SMitMxnB43OZpyF1IFPS9bgb2I3bpCh76m2WEK7BE0A0EzpYsRp0CCH2xNKshr7kacU5TQBLYn4zj7CG60A==", "dev": true, "license": "MIT", "dependencies": { - "@volar/source-map": "2.4.23" + "@volar/source-map": "2.4.26" } }, "node_modules/@volar/source-map": { - "version": "2.4.23", - "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-2.4.23.tgz", - "integrity": "sha512-Z1Uc8IB57Lm6k7q6KIDu/p+JWtf3xsXJqAX/5r18hYOTpJyBn0KXUR8oTJ4WFYOcDzWC9n3IflGgHowx6U6z9Q==", + "version": "2.4.26", + "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-2.4.26.tgz", + "integrity": "sha512-JJw0Tt/kSFsIRmgTQF4JSt81AUSI1aEye5Zl65EeZ8H35JHnTvFGmpDOBn5iOxd48fyGE+ZvZBp5FcgAy/1Qhw==", "dev": true, "license": "MIT" }, "node_modules/@volar/typescript": { - "version": "2.4.23", - "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-2.4.23.tgz", - "integrity": "sha512-lAB5zJghWxVPqfcStmAP1ZqQacMpe90UrP5RJ3arDyrhy4aCUQqmxPPLB2PWDKugvylmO41ljK7vZ+t6INMTag==", + "version": "2.4.26", + "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-2.4.26.tgz", + "integrity": "sha512-N87ecLD48Sp6zV9zID/5yuS1+5foj0DfuYGdQ6KHj/IbKvyKv1zNX6VCmnKYwtmHadEO6mFc2EKISiu3RDPAvA==", "dev": true, "license": "MIT", "dependencies": { - "@volar/language-core": "2.4.23", + "@volar/language-core": "2.4.26", "path-browserify": "^1.0.1", "vscode-uri": "^3.0.8" } }, "node_modules/@vue/compiler-core": { - "version": "3.5.24", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.24.tgz", - "integrity": "sha512-eDl5H57AOpNakGNAkFDH+y7kTqrQpJkZFXhWZQGyx/5Wh7B1uQYvcWkvZi11BDhscPgj8N7XV3oRwiPnx1Vrig==", + "version": "3.5.25", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.25.tgz", + "integrity": "sha512-vay5/oQJdsNHmliWoZfHPoVZZRmnSWhug0BYT34njkYTPqClh3DNWLkZNJBVSjsNMrg0CCrBfoKkjZQPM/QVUw==", "license": "MIT", "dependencies": { "@babel/parser": "^7.28.5", - "@vue/shared": "3.5.24", + "@vue/shared": "3.5.25", "entities": "^4.5.0", "estree-walker": "^2.0.2", "source-map-js": "^1.2.1" } }, "node_modules/@vue/compiler-dom": { - "version": "3.5.24", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.24.tgz", - "integrity": "sha512-1QHGAvs53gXkWdd3ZMGYuvQFXHW4ksKWPG8HP8/2BscrbZ0brw183q2oNWjMrSWImYLHxHrx1ItBQr50I/q2zw==", + "version": "3.5.25", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.25.tgz", + "integrity": "sha512-4We0OAcMZsKgYoGlMjzYvaoErltdFI2/25wqanuTu+S4gismOTRTBPi4IASOjxWdzIwrYSjnqONfKvuqkXzE2Q==", "license": "MIT", "dependencies": { - "@vue/compiler-core": "3.5.24", - "@vue/shared": "3.5.24" + "@vue/compiler-core": "3.5.25", + "@vue/shared": "3.5.25" } }, "node_modules/@vue/compiler-sfc": { - "version": "3.5.24", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.24.tgz", - "integrity": "sha512-8EG5YPRgmTB+YxYBM3VXy8zHD9SWHUJLIGPhDovo3Z8VOgvP+O7UP5vl0J4BBPWYD9vxtBabzW1EuEZ+Cqs14g==", + "version": "3.5.25", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.25.tgz", + "integrity": "sha512-PUgKp2rn8fFsI++lF2sO7gwO2d9Yj57Utr5yEsDf3GNaQcowCLKL7sf+LvVFvtJDXUp/03+dC6f2+LCv5aK1ag==", "license": "MIT", "peer": true, "dependencies": { "@babel/parser": "^7.28.5", - "@vue/compiler-core": "3.5.24", - "@vue/compiler-dom": "3.5.24", - "@vue/compiler-ssr": "3.5.24", - "@vue/shared": "3.5.24", + "@vue/compiler-core": "3.5.25", + "@vue/compiler-dom": "3.5.25", + "@vue/compiler-ssr": "3.5.25", + "@vue/shared": "3.5.25", "estree-walker": "^2.0.2", "magic-string": "^0.30.21", "postcss": "^8.5.6", @@ -1444,14 +1399,14 @@ } }, "node_modules/@vue/compiler-ssr": { - "version": "3.5.24", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.24.tgz", - "integrity": "sha512-trOvMWNBMQ/odMRHW7Ae1CdfYx+7MuiQu62Jtu36gMLXcaoqKvAyh+P73sYG9ll+6jLB6QPovqoKGGZROzkFFg==", + "version": "3.5.25", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.25.tgz", + "integrity": "sha512-ritPSKLBcParnsKYi+GNtbdbrIE1mtuFEJ4U1sWeuOMlIziK5GtOL85t5RhsNy4uWIXPgk+OUdpnXiTdzn8o3A==", "license": "MIT", "peer": true, "dependencies": { - "@vue/compiler-dom": "3.5.24", - "@vue/shared": "3.5.24" + "@vue/compiler-dom": "3.5.25", + "@vue/shared": "3.5.25" } }, "node_modules/@vue/compiler-vue2": { @@ -1489,58 +1444,74 @@ } } }, + "node_modules/@vue/language-core/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@vue/reactivity": { - "version": "3.5.24", - "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.24.tgz", - "integrity": "sha512-BM8kBhtlkkbnyl4q+HiF5R5BL0ycDPfihowulm02q3WYp2vxgPcJuZO866qa/0u3idbMntKEtVNuAUp5bw4teg==", + "version": "3.5.25", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.25.tgz", + "integrity": "sha512-5xfAypCQepv4Jog1U4zn8cZIcbKKFka3AgWHEFQeK65OW+Ys4XybP6z2kKgws4YB43KGpqp5D/K3go2UPPunLA==", "license": "MIT", "peer": true, "dependencies": { - "@vue/shared": "3.5.24" + "@vue/shared": "3.5.25" } }, "node_modules/@vue/runtime-core": { - "version": "3.5.24", - "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.24.tgz", - "integrity": "sha512-RYP/byyKDgNIqfX/gNb2PB55dJmM97jc9wyF3jK7QUInYKypK2exmZMNwnjueWwGceEkP6NChd3D2ZVEp9undQ==", + "version": "3.5.25", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.25.tgz", + "integrity": "sha512-Z751v203YWwYzy460bzsYQISDfPjHTl+6Zzwo/a3CsAf+0ccEjQ8c+0CdX1WsumRTHeywvyUFtW6KvNukT/smA==", "license": "MIT", "peer": true, "dependencies": { - "@vue/reactivity": "3.5.24", - "@vue/shared": "3.5.24" + "@vue/reactivity": "3.5.25", + "@vue/shared": "3.5.25" } }, "node_modules/@vue/runtime-dom": { - "version": "3.5.24", - "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.24.tgz", - "integrity": "sha512-Z8ANhr/i0XIluonHVjbUkjvn+CyrxbXRIxR7wn7+X7xlcb7dJsfITZbkVOeJZdP8VZwfrWRsWdShH6pngMxRjw==", + "version": "3.5.25", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.25.tgz", + "integrity": "sha512-a4WrkYFbb19i9pjkz38zJBg8wa/rboNERq3+hRRb0dHiJh13c+6kAbgqCPfMaJ2gg4weWD3APZswASOfmKwamA==", "license": "MIT", "peer": true, "dependencies": { - "@vue/reactivity": "3.5.24", - "@vue/runtime-core": "3.5.24", - "@vue/shared": "3.5.24", + "@vue/reactivity": "3.5.25", + "@vue/runtime-core": "3.5.25", + "@vue/shared": "3.5.25", "csstype": "^3.1.3" } }, "node_modules/@vue/server-renderer": { - "version": "3.5.24", - "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.24.tgz", - "integrity": "sha512-Yh2j2Y4G/0/4z/xJ1Bad4mxaAk++C2v4kaa8oSYTMJBJ00/ndPuxCnWeot0/7/qafQFLh5pr6xeV6SdMcE/G1w==", + "version": "3.5.25", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.25.tgz", + "integrity": "sha512-UJaXR54vMG61i8XNIzTSf2Q7MOqZHpp8+x3XLGtE3+fL+nQd+k7O5+X3D/uWrnQXOdMw5VPih+Uremcw+u1woQ==", "license": "MIT", "peer": true, "dependencies": { - "@vue/compiler-ssr": "3.5.24", - "@vue/shared": "3.5.24" + "@vue/compiler-ssr": "3.5.25", + "@vue/shared": "3.5.25" }, "peerDependencies": { - "vue": "3.5.24" + "vue": "3.5.25" } }, "node_modules/@vue/shared": { - "version": "3.5.24", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.24.tgz", - "integrity": "sha512-9cwHL2EsJBdi8NY22pngYYWzkTDhld6fAD6jlaeloNGciNSJL6bLpbxVgXl96X00Jtc6YWQv96YA/0sxex/k1A==", + "version": "3.5.25", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.25.tgz", + "integrity": "sha512-AbOPdQQnAnzs58H2FrrDxYj/TJfmeS2jdfEEhgiKINy+bnOANmVizIEgq1r+C5zsbs6l1CCQxtcj71rwNQ4jWg==", "license": "MIT" }, "node_modules/@vue/tsconfig": { @@ -1670,32 +1641,6 @@ "dev": true, "license": "MIT" }, - "node_modules/ansi-regex": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", - "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/ansi-styles": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", - "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, "node_modules/any-promise": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", @@ -1811,9 +1756,9 @@ "license": "MIT" }, "node_modules/baseline-browser-mapping": { - "version": "2.8.26", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.26.tgz", - "integrity": "sha512-73lC1ugzwoaWCLJ1LvOgrR5xsMLTqSKIEoMHVtL9E/HNk0PXtTM76ZIm84856/SF7Nv8mPZxKoBsgpm0tR1u1Q==", + "version": "2.8.32", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.32.tgz", + "integrity": "sha512-OPz5aBThlyLFgxyhdwf/s2+8ab3OvT7AdTNvKHBwpXomIYeXqpUUuT8LrdtxZSsWJ4R4CU1un4XGh5Ez3nlTpw==", "dev": true, "license": "Apache-2.0", "bin": { @@ -1914,9 +1859,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001754", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001754.tgz", - "integrity": "sha512-x6OeBXueoAceOmotzx3PO4Zpt4rzpeIFsSr6AAePTZxSkXiYDUmpypEl7e2+8NCd9bD7bXjqyef8CJYPC1jfxg==", + "version": "1.0.30001757", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001757.tgz", + "integrity": "sha512-r0nnL/I28Zi/yjk1el6ilj27tKcdjLsNqAOZr0yVjWPrSQyHgKI2INaEWw21bAQSv2LXRt1XuCS/GomNpWOxsQ==", "dev": true, "funding": [ { @@ -1995,26 +1940,6 @@ "node": ">=6" } }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "peer": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT", - "peer": true - }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -2052,21 +1977,6 @@ "dev": true, "license": "MIT" }, - "node_modules/cross-spawn": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "license": "MIT", - "peer": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/cssesc": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", @@ -2080,9 +1990,9 @@ } }, "node_modules/csstype": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", "license": "MIT", "peer": true }, @@ -2173,27 +2083,13 @@ "node": ">= 0.4" } }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "license": "MIT", - "peer": true - }, "node_modules/electron-to-chromium": { - "version": "1.5.250", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.250.tgz", - "integrity": "sha512-/5UMj9IiGDMOFBnN4i7/Ry5onJrAGSbOGo3s9FEKmwobGq6xw832ccET0CE3CkkMBZ8GJSlUIesZofpyurqDXw==", + "version": "1.5.263", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.263.tgz", + "integrity": "sha512-DrqJ11Knd+lo+dv+lltvfMDLU27g14LMdH2b0O3Pio4uk0x+z7OR+JrmyacTPN2M8w3BrZ7/RTwG3R9B7irPlg==", "dev": true, "license": "ISC" }, - "node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "license": "MIT", - "peer": true - }, "node_modules/entities": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", @@ -2398,27 +2294,10 @@ } } }, - "node_modules/foreground-child": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", - "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", - "license": "ISC", - "peer": true, - "dependencies": { - "cross-spawn": "^7.0.6", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/form-data": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", - "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", + "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", "license": "MIT", "peer": true, "dependencies": { @@ -2523,27 +2402,6 @@ "node": ">= 0.4" } }, - "node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", - "license": "ISC", - "peer": true, - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -2685,16 +2543,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=8" - } - }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -2718,29 +2566,6 @@ "node": ">=0.12.0" } }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "license": "ISC", - "peer": true - }, - "node_modules/jackspeak": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", - "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", - "license": "BlueOak-1.0.0", - "peer": true, - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, "node_modules/jiti": { "version": "1.21.7", "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", @@ -2831,11 +2656,17 @@ "license": "MIT" }, "node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, "license": "ISC", - "peer": true + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } }, "node_modules/magic-string": { "version": "0.30.21", @@ -2904,30 +2735,21 @@ } }, "node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.3.tgz", + "integrity": "sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==", + "dev": true, "license": "ISC", "dependencies": { - "brace-expansion": "^2.0.1" + "@isaacs/brace-expansion": "^5.0.0" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": "20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "license": "ISC", - "peer": true, - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, "node_modules/mlly": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.8.0.tgz", @@ -3057,13 +2879,6 @@ "license": "MIT", "peer": true }, - "node_modules/package-json-from-dist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", - "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", - "license": "BlueOak-1.0.0", - "peer": true - }, "node_modules/parse-duration": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/parse-duration/-/parse-duration-2.1.4.tgz", @@ -3077,39 +2892,12 @@ "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", "license": "MIT" }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=8" - } - }, "node_modules/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "license": "MIT" }, - "node_modules/path-scurry": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", - "license": "BlueOak-1.0.0", - "peer": true, - "dependencies": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/pathe": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", @@ -3432,9 +3220,9 @@ } }, "node_modules/reka-ui": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/reka-ui/-/reka-ui-2.6.0.tgz", - "integrity": "sha512-NrGMKrABD97l890mFS3TNUzB0BLUfbL3hh0NjcJRIUSUljb288bx3Mzo31nOyUcdiiW0HqFGXJwyCBh9cWgb0w==", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/reka-ui/-/reka-ui-2.6.1.tgz", + "integrity": "sha512-XK7cJDQoNuGXfCNzBBo/81Yg/OgjPwvbabnlzXG2VsdSgNsT6iIkuPBPr+C0Shs+3bb0x0lbPvgQAhMSCKm5Ww==", "license": "MIT", "peer": true, "dependencies": { @@ -3495,9 +3283,9 @@ } }, "node_modules/rollup": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.53.2.tgz", - "integrity": "sha512-MHngMYwGJVi6Fmnk6ISmnk7JAHRNF0UkuucA0CUW3N3a4KnONPEZz+vUanQP/ZC/iY1Qkf3bwPWzyY84wEks1g==", + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.53.3.tgz", + "integrity": "sha512-w8GmOxZfBmKknvdXU1sdM9NHcoQejwF/4mNgj2JuEEdRaHwwF12K7e9eXn1nLZ07ad+du76mkVsyeb2rKGllsA==", "dev": true, "license": "MIT", "dependencies": { @@ -3511,28 +3299,28 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.53.2", - "@rollup/rollup-android-arm64": "4.53.2", - "@rollup/rollup-darwin-arm64": "4.53.2", - "@rollup/rollup-darwin-x64": "4.53.2", - "@rollup/rollup-freebsd-arm64": "4.53.2", - "@rollup/rollup-freebsd-x64": "4.53.2", - "@rollup/rollup-linux-arm-gnueabihf": "4.53.2", - "@rollup/rollup-linux-arm-musleabihf": "4.53.2", - "@rollup/rollup-linux-arm64-gnu": "4.53.2", - "@rollup/rollup-linux-arm64-musl": "4.53.2", - "@rollup/rollup-linux-loong64-gnu": "4.53.2", - "@rollup/rollup-linux-ppc64-gnu": "4.53.2", - "@rollup/rollup-linux-riscv64-gnu": "4.53.2", - "@rollup/rollup-linux-riscv64-musl": "4.53.2", - "@rollup/rollup-linux-s390x-gnu": "4.53.2", - "@rollup/rollup-linux-x64-gnu": "4.53.2", - "@rollup/rollup-linux-x64-musl": "4.53.2", - "@rollup/rollup-openharmony-arm64": "4.53.2", - "@rollup/rollup-win32-arm64-msvc": "4.53.2", - "@rollup/rollup-win32-ia32-msvc": "4.53.2", - "@rollup/rollup-win32-x64-gnu": "4.53.2", - "@rollup/rollup-win32-x64-msvc": "4.53.2", + "@rollup/rollup-android-arm-eabi": "4.53.3", + "@rollup/rollup-android-arm64": "4.53.3", + "@rollup/rollup-darwin-arm64": "4.53.3", + "@rollup/rollup-darwin-x64": "4.53.3", + "@rollup/rollup-freebsd-arm64": "4.53.3", + "@rollup/rollup-freebsd-x64": "4.53.3", + "@rollup/rollup-linux-arm-gnueabihf": "4.53.3", + "@rollup/rollup-linux-arm-musleabihf": "4.53.3", + "@rollup/rollup-linux-arm64-gnu": "4.53.3", + "@rollup/rollup-linux-arm64-musl": "4.53.3", + "@rollup/rollup-linux-loong64-gnu": "4.53.3", + "@rollup/rollup-linux-ppc64-gnu": "4.53.3", + "@rollup/rollup-linux-riscv64-gnu": "4.53.3", + "@rollup/rollup-linux-riscv64-musl": "4.53.3", + "@rollup/rollup-linux-s390x-gnu": "4.53.3", + "@rollup/rollup-linux-x64-gnu": "4.53.3", + "@rollup/rollup-linux-x64-musl": "4.53.3", + "@rollup/rollup-openharmony-arm64": "4.53.3", + "@rollup/rollup-win32-arm64-msvc": "4.53.3", + "@rollup/rollup-win32-ia32-msvc": "4.53.3", + "@rollup/rollup-win32-x64-gnu": "4.53.3", + "@rollup/rollup-win32-x64-msvc": "4.53.3", "fsevents": "~2.3.2" } }, @@ -3576,55 +3364,6 @@ "node": ">=10" } }, - "node_modules/semver/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "license": "MIT", - "peer": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "license": "ISC", - "peer": true, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -3661,110 +3400,6 @@ "node": ">=0.6.19" } }, - "node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "license": "MIT", - "peer": true, - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/string-width-cjs": { - "name": "string-width", - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "license": "MIT", - "peer": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "license": "MIT", - "peer": true - }, - "node_modules/string-width-cjs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "peer": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", - "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", - "license": "MIT", - "peer": true, - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/strip-ansi-cjs": { - "name": "strip-ansi", - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "peer": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=8" - } - }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -3779,18 +3414,18 @@ } }, "node_modules/sucrase": { - "version": "3.35.0", - "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", - "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", + "version": "3.35.1", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.1.tgz", + "integrity": "sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==", "license": "MIT", "peer": true, "dependencies": { "@jridgewell/gen-mapping": "^0.3.2", "commander": "^4.0.0", - "glob": "^10.3.10", "lines-and-columns": "^1.1.6", "mz": "^2.7.0", "pirates": "^4.0.1", + "tinyglobby": "^0.2.11", "ts-interface-checker": "^0.1.9" }, "bin": { @@ -3901,6 +3536,54 @@ "node": ">=0.8" } }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "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==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -4106,17 +3789,17 @@ "license": "MIT" }, "node_modules/vue": { - "version": "3.5.24", - "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.24.tgz", - "integrity": "sha512-uTHDOpVQTMjcGgrqFPSb8iO2m1DUvo+WbGqoXQz8Y1CeBYQ0FXf2z1gLRaBtHjlRz7zZUBHxjVB5VTLzYkvftg==", + "version": "3.5.25", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.25.tgz", + "integrity": "sha512-YLVdgv2K13WJ6n+kD5owehKtEXwdwXuj2TTyJMsO7pSeKw2bfRNZGjhB7YzrpbMYj5b5QsUebHpOqR3R3ziy/g==", "license": "MIT", "peer": true, "dependencies": { - "@vue/compiler-dom": "3.5.24", - "@vue/compiler-sfc": "3.5.24", - "@vue/runtime-dom": "3.5.24", - "@vue/server-renderer": "3.5.24", - "@vue/shared": "3.5.24" + "@vue/compiler-dom": "3.5.25", + "@vue/compiler-sfc": "3.5.25", + "@vue/runtime-dom": "3.5.25", + "@vue/server-renderer": "3.5.25", + "@vue/shared": "3.5.25" }, "peerDependencies": { "typescript": "*" @@ -4205,118 +3888,20 @@ "license": "MIT", "peer": true }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "node_modules/vue-tsc/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "license": "ISC", "peer": true, "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "license": "MIT", - "peer": true, - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs": { - "name": "wrap-ansi", - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "license": "MIT", - "peer": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "peer": true, - "dependencies": { - "color-convert": "^2.0.1" + "brace-expansion": "^2.0.1" }, "engines": { - "node": ">=8" + "node": ">=16 || 14 >=14.17" }, "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "license": "MIT", - "peer": true - }, - "node_modules/wrap-ansi-cjs/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "license": "MIT", - "peer": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "peer": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/yallist": { diff --git a/resources/js/packages/ui/package.json b/resources/js/packages/ui/package.json index 6812d917..3dfa4d6c 100644 --- a/resources/js/packages/ui/package.json +++ b/resources/js/packages/ui/package.json @@ -1,6 +1,6 @@ { "name": "@solidtime/ui", - "version": "0.0.13", + "version": "0.0.14", "description": "Package containing the solidtime ui components", "main": "./dist/solidtime-ui-lib.umd.cjs", "module": "./dist/solidtime-ui-lib.js", From de97d15925373b2c4845adbae27615cf987e2dea Mon Sep 17 00:00:00 2001 From: Gregor Vostrak Date: Tue, 9 Dec 2025 14:30:39 +0100 Subject: [PATCH 006/115] add tailwind theme and css variables to files export, bump ui package version --- resources/js/packages/ui/package-lock.json | 4 ++-- resources/js/packages/ui/package.json | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/resources/js/packages/ui/package-lock.json b/resources/js/packages/ui/package-lock.json index eb2eab44..1412d51b 100644 --- a/resources/js/packages/ui/package-lock.json +++ b/resources/js/packages/ui/package-lock.json @@ -1,12 +1,12 @@ { "name": "@solidtime/ui", - "version": "0.0.14", + "version": "0.0.15", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@solidtime/ui", - "version": "0.0.14", + "version": "0.0.15", "license": "AGPL-3.0", "devDependencies": { "@types/node": "^22.4.1", diff --git a/resources/js/packages/ui/package.json b/resources/js/packages/ui/package.json index 3dfa4d6c..da80c08f 100644 --- a/resources/js/packages/ui/package.json +++ b/resources/js/packages/ui/package.json @@ -1,6 +1,6 @@ { "name": "@solidtime/ui", - "version": "0.0.14", + "version": "0.0.15", "description": "Package containing the solidtime ui components", "main": "./dist/solidtime-ui-lib.umd.cjs", "module": "./dist/solidtime-ui-lib.js", @@ -33,7 +33,9 @@ "preview": "vite preview" }, "files": [ - "dist" + "dist", + "styles.css", + "tailwind.theme.js" ], "keywords": [ "solidtime", From 743c64909a473e9935fddd88f2e47dc8455d7cef Mon Sep 17 00:00:00 2001 From: Gregor Vostrak Date: Tue, 16 Dec 2025 20:18:09 +0100 Subject: [PATCH 007/115] restrict time entries create endpoints for employees to only projects where they have access to --- .../V1/TimeEntry/TimeEntryStoreRequest.php | 13 +- .../TimeEntryUpdateMultipleRequest.php | 13 +- .../V1/TimeEntry/TimeEntryUpdateRequest.php | 13 +- .../Endpoint/Api/V1/TimeEntryEndpointTest.php | 142 ++++++++++++++++++ 4 files changed, 178 insertions(+), 3 deletions(-) diff --git a/app/Http/Requests/V1/TimeEntry/TimeEntryStoreRequest.php b/app/Http/Requests/V1/TimeEntry/TimeEntryStoreRequest.php index b4d3840c..ec51f84e 100644 --- a/app/Http/Requests/V1/TimeEntry/TimeEntryStoreRequest.php +++ b/app/Http/Requests/V1/TimeEntry/TimeEntryStoreRequest.php @@ -10,8 +10,10 @@ use App\Models\Project; use App\Models\Tag; use App\Models\Task; +use App\Service\PermissionStore; use Illuminate\Contracts\Validation\ValidationRule; use Illuminate\Database\Eloquent\Builder; +use Illuminate\Support\Facades\Auth; use Korridor\LaravelModelValidationRules\Rules\ExistsEloquent; /** @@ -42,7 +44,16 @@ public function rules(): array 'required_with:task_id', ExistsEloquent::make(Project::class, null, function (Builder $builder): Builder { /** @var Builder $builder */ - return $builder->whereBelongsTo($this->organization, 'organization'); + $builder = $builder->whereBelongsTo($this->organization, 'organization'); + + // If user doesn't have 'all' permission for time entries or projects, only allow access to public projects or projects they're a member of + $permissionStore = app(PermissionStore::class); + if (! $permissionStore->has($this->organization, 'time-entries:create:all') + && ! $permissionStore->has($this->organization, 'projects:view:all')) { + $builder = $builder->visibleByEmployee(Auth::user()); + } + + return $builder; })->uuid(), ], // ID of the task that the time entry should belong to diff --git a/app/Http/Requests/V1/TimeEntry/TimeEntryUpdateMultipleRequest.php b/app/Http/Requests/V1/TimeEntry/TimeEntryUpdateMultipleRequest.php index 9f198654..e7c4b600 100644 --- a/app/Http/Requests/V1/TimeEntry/TimeEntryUpdateMultipleRequest.php +++ b/app/Http/Requests/V1/TimeEntry/TimeEntryUpdateMultipleRequest.php @@ -10,8 +10,10 @@ use App\Models\Project; use App\Models\Tag; use App\Models\Task; +use App\Service\PermissionStore; use Illuminate\Contracts\Validation\ValidationRule; use Illuminate\Database\Eloquent\Builder; +use Illuminate\Support\Facades\Auth; use Korridor\LaravelModelValidationRules\Rules\ExistsEloquent; /** @@ -54,7 +56,16 @@ public function rules(): array 'required_with:task_id', ExistsEloquent::make(Project::class, null, function (Builder $builder): Builder { /** @var Builder $builder */ - return $builder->whereBelongsTo($this->organization, 'organization'); + $builder = $builder->whereBelongsTo($this->organization, 'organization'); + + // If user doesn't have 'all' permission for time entries or projects, only allow access to public projects or projects they're a member of + $permissionStore = app(PermissionStore::class); + if (! $permissionStore->has($this->organization, 'time-entries:update:all') + && ! $permissionStore->has($this->organization, 'projects:view:all')) { + $builder = $builder->visibleByEmployee(Auth::user()); + } + + return $builder; })->uuid(), ], // ID of the task that the time entry should belong to diff --git a/app/Http/Requests/V1/TimeEntry/TimeEntryUpdateRequest.php b/app/Http/Requests/V1/TimeEntry/TimeEntryUpdateRequest.php index e9e6795a..d895d98f 100644 --- a/app/Http/Requests/V1/TimeEntry/TimeEntryUpdateRequest.php +++ b/app/Http/Requests/V1/TimeEntry/TimeEntryUpdateRequest.php @@ -10,8 +10,10 @@ use App\Models\Project; use App\Models\Tag; use App\Models\Task; +use App\Service\PermissionStore; use Illuminate\Contracts\Validation\ValidationRule; use Illuminate\Database\Eloquent\Builder; +use Illuminate\Support\Facades\Auth; use Korridor\LaravelModelValidationRules\Rules\ExistsEloquent; /** @@ -42,7 +44,16 @@ public function rules(): array 'required_with:task_id', ExistsEloquent::make(Project::class, null, function (Builder $builder): Builder { /** @var Builder $builder */ - return $builder->whereBelongsTo($this->organization, 'organization'); + $builder = $builder->whereBelongsTo($this->organization, 'organization'); + + // If user doesn't have 'all' permission for time entries or projects, only allow access to public projects or projects they're a member of + $permissionStore = app(PermissionStore::class); + if (! $permissionStore->has($this->organization, 'time-entries:update:all') + && ! $permissionStore->has($this->organization, 'projects:view:all')) { + $builder = $builder->visibleByEmployee(Auth::user()); + } + + return $builder; })->uuid(), ], // ID of the task that the time entry should belong to diff --git a/tests/Unit/Endpoint/Api/V1/TimeEntryEndpointTest.php b/tests/Unit/Endpoint/Api/V1/TimeEntryEndpointTest.php index 585a68b6..1a29232e 100644 --- a/tests/Unit/Endpoint/Api/V1/TimeEntryEndpointTest.php +++ b/tests/Unit/Endpoint/Api/V1/TimeEntryEndpointTest.php @@ -1922,6 +1922,7 @@ public function test_store_endpoint_fails_if_user_already_has_active_time_entry_ // Arrange $data = $this->createUserWithPermission([ 'time-entries:create:own', + 'projects:view:all', ]); $activeTimeEntry = TimeEntry::factory()->forOrganization($data->organization)->forMember($data->member)->active()->create(); $timeEntryFake = TimeEntry::factory()->forOrganization($data->organization)->withTask($data->organization)->withTags($data->organization)->make(); @@ -1949,6 +1950,7 @@ public function test_store_endpoint_validation_fails_if_task_id_does_not_belong_ // Arrange $data = $this->createUserWithPermission([ 'time-entries:create:own', + 'projects:view:all', ]); $timeEntryFake = TimeEntry::factory()->forOrganization($data->organization)->withTask($data->organization)->make(); $timeEntryFake2 = TimeEntry::factory()->forOrganization($data->organization)->withTask($data->organization)->make(); @@ -1978,6 +1980,7 @@ public function test_store_endpoint_validation_fails_if_project_id_is_missing_bu // Arrange $data = $this->createUserWithPermission([ 'time-entries:create:own', + 'projects:view:all', ]); $timeEntryFake = TimeEntry::factory()->forOrganization($data->organization)->withTask($data->organization)->make(); $timeEntryFake2 = TimeEntry::factory()->forOrganization($data->organization)->withTask($data->organization)->make(); @@ -2007,6 +2010,7 @@ public function test_store_endpoint_creates_new_time_entry_for_current_user(): v // Arrange $data = $this->createUserWithPermission([ 'time-entries:create:own', + 'projects:view:all', ]); $timeEntryFake = TimeEntry::factory()->withTask($data->organization)->forOrganization($data->organization)->make(); Passport::actingAs($data->user); @@ -2037,6 +2041,7 @@ public function test_store_endpoint_fails_gracefully_if_non_uuid_text_is_in_uuid // Arrange $data = $this->createUserWithPermission([ 'time-entries:create:own', + 'projects:view:all', ]); $timeEntryFake = TimeEntry::factory()->withTask($data->organization)->forOrganization($data->organization)->make(); Passport::actingAs($data->user); @@ -2053,11 +2058,47 @@ public function test_store_endpoint_fails_gracefully_if_non_uuid_text_is_in_uuid $response->assertStatus(422); } + public function test_store_endpoint_fails_if_employee_tries_to_create_time_entry_for_private_project_without_access(): void + { + // Arrange + $data = $this->createUserWithPermission([ + 'time-entries:create:own', + ]); + + // Create a private project that the employee is not a member of + $privateProject = Project::factory()->forOrganization($data->organization)->create([ + 'is_public' => false, + ]); + + Passport::actingAs($data->user); + + // Act + $response = $this->postJson(route('api.v1.time-entries.store', [$data->organization->getKey()]), [ + 'description' => 'Test time entry', + 'billable' => false, + 'start' => now()->toIso8601ZuluString(), + 'end' => now()->addHour()->toIso8601ZuluString(), + 'member_id' => $data->member->getKey(), + 'project_id' => $privateProject->getKey(), + ]); + + // Assert + $response->assertStatus(422); + $response->assertJsonValidationErrors(['project_id']); + + // Verify the time entry was NOT created in the database + $this->assertDatabaseMissing(TimeEntry::class, [ + 'project_id' => $privateProject->getKey(), + 'member_id' => $data->member->getKey(), + ]); + } + public function test_store_endpoints_sets_billable_rate(): void { // Arrange $data = $this->createUserWithPermission([ 'time-entries:create:own', + 'projects:view:all', ]); $timeEntryFake = TimeEntry::factory()->withTask($data->organization)->forOrganization($data->organization)->make(); $project = Project::factory()->forOrganization($data->organization)->billable()->create(); @@ -2088,6 +2129,7 @@ public function test_store_endpoint_creates_new_time_entry_with_minimal_fields() // Arrange $data = $this->createUserWithPermission([ 'time-entries:create:own', + 'projects:view:all', ]); $timeEntryFake = TimeEntry::factory()->forOrganization($data->organization)->make(); Passport::actingAs($data->user); @@ -2113,6 +2155,7 @@ public function test_store_endpoint_can_create_new_time_entry_with_project_and_a // Arrange $data = $this->createUserWithPermission([ 'time-entries:create:own', + 'projects:view:all', ]); $client = Client::factory()->forOrganization($data->organization)->create(); $project = Project::factory()->forOrganization($data->organization)->forClient($client)->create(); @@ -2143,6 +2186,7 @@ public function test_store_endpoint_fails_if_user_has_no_permission_to_create_ti // Arrange $data = $this->createUserWithPermission([ 'time-entries:create:own', + 'projects:view:all', ]); $otherUser = User::factory()->create(); $otherMember = Member::factory()->forOrganization($data->organization)->forUser($otherUser)->role(Role::Employee)->create(); @@ -2202,6 +2246,7 @@ public function test_create_endpoint_recalculates_project_and_task_spent_time_if // Arrange $data = $this->createUserWithPermission([ 'time-entries:create:own', + 'projects:view:all', ]); $project = Project::factory()->forOrganization($data->organization)->create(); $task = Task::factory()->forOrganization($data->organization)->forProject($project)->create(); @@ -2236,6 +2281,39 @@ public function test_create_endpoint_recalculates_project_and_task_spent_time_if }); } + public function test_update_endpoint_fails_if_employee_tries_to_update_time_entry_to_private_project_without_access(): void + { + // Arrange + $data = $this->createUserWithPermission([ + 'time-entries:update:own', + ]); + + // Create a time entry for the employee + $timeEntry = TimeEntry::factory()->forOrganization($data->organization)->forMember($data->member)->create(); + + // Create a private project that the employee is not a member of + $privateProject = Project::factory()->forOrganization($data->organization)->create([ + 'is_public' => false, + ]); + + Passport::actingAs($data->user); + + // Act + $response = $this->putJson(route('api.v1.time-entries.update', [$data->organization->getKey(), $timeEntry->getKey()]), [ + 'project_id' => $privateProject->getKey(), + ]); + + // Assert + $response->assertStatus(422); + $response->assertJsonValidationErrors(['project_id']); + + // Verify the time entry was NOT updated in the database + $this->assertDatabaseMissing(TimeEntry::class, [ + 'id' => $timeEntry->getKey(), + 'project_id' => $privateProject->getKey(), + ]); + } + public function test_update_endpoint_fails_if_user_has_no_permission_to_update_own_time_entries(): void { // Arrange @@ -2264,9 +2342,11 @@ public function test_update_endpoint_fails_if_user_is_not_part_of_time_entry_org // Arrange $data = $this->createUserWithPermission([ 'time-entries:update:own', + 'projects:view:all', ]); $otherUser = $this->createUserWithPermission([ 'time-entries:update:own', + 'projects:view:all', ]); $timeEntry = TimeEntry::factory()->forOrganization($otherUser->organization)->forMember($otherUser->member)->create(); $timeEntryFake = TimeEntry::factory()->forOrganization($data->organization)->make(); @@ -2290,6 +2370,7 @@ public function test_update_endpoint_fails_if_user_has_no_permission_to_update_t // Arrange $data = $this->createUserWithPermission([ 'time-entries:update:own', + 'projects:view:all', ]); $user = User::factory()->create(); $member = Member::factory()->forOrganization($data->organization)->forUser($user)->role(Role::Employee)->create(); @@ -2315,6 +2396,7 @@ public function test_update_endpoint_validation_fails_if_task_id_does_not_belong // Arrange $data = $this->createUserWithPermission([ 'time-entries:update:own', + 'projects:view:all', ]); $timeEntry = TimeEntry::factory()->forOrganization($data->organization)->forMember($data->member)->create(); $timeEntryFake = TimeEntry::factory()->forOrganization($data->organization)->withTask($data->organization)->make(); @@ -2344,6 +2426,7 @@ public function test_update_endpoint_validation_fails_if_project_id_is_missing_b // Arrange $data = $this->createUserWithPermission([ 'time-entries:update:own', + 'projects:view:all', ]); $timeEntry = TimeEntry::factory()->forOrganization($data->organization)->forMember($data->member)->create(); $timeEntryFake = TimeEntry::factory()->forOrganization($data->organization)->withTask($data->organization)->make(); @@ -2373,6 +2456,7 @@ public function test_update_endpoint_updates_time_entry_for_current_user(): void // Arrange $data = $this->createUserWithPermission([ 'time-entries:update:own', + 'projects:view:all', ]); $timeEntry = TimeEntry::factory()->forOrganization($data->organization)->forMember($data->member)->create(); $timeEntryFake = TimeEntry::factory()->withTags($data->organization)->forOrganization($data->organization)->make(); @@ -2401,6 +2485,7 @@ public function test_update_endpoints_sets_billable_rate(): void // Arrange $data = $this->createUserWithPermission([ 'time-entries:update:own', + 'projects:view:all', ]); $timeEntry = TimeEntry::factory()->forOrganization($data->organization)->forMember($data->member)->create(); $timeEntryFake = TimeEntry::factory()->withTags($data->organization)->forOrganization($data->organization)->make(); @@ -2432,6 +2517,7 @@ public function test_update_endpoint_updates_time_entry_for_current_user_but_doe // Arrange $data = $this->createUserWithPermission([ 'time-entries:update:own', + 'projects:view:all', ]); $timeEntry = TimeEntry::factory()->forOrganization($data->organization)->forMember($data->member)->create(); $timeEntryFake = TimeEntry::factory()->withTags($data->organization)->forOrganization($data->organization)->make(); @@ -2459,6 +2545,7 @@ public function test_update_endpoint_fails_if_user_tries_to_reactivate_a_time_en // Arrange $data = $this->createUserWithPermission([ 'time-entries:update:own', + 'projects:view:all', ]); $timeEntry = TimeEntry::factory()->forOrganization($data->organization)->forMember($data->member)->create(); $timeEntryFake = TimeEntry::factory()->forOrganization($data->organization)->make(); @@ -2576,6 +2663,7 @@ public function test_update_endpoint_recalculates_project_and_task_spend_time_af // Arrange $data = $this->createUserWithPermission([ 'time-entries:update:own', + 'projects:view:all', ]); $project = Project::factory()->forOrganization($data->organization)->create(); $task = Task::factory()->forOrganization($data->organization)->forProject($project)->create(); @@ -2610,6 +2698,7 @@ public function test_update_endpoint_recalculates_project_and_task_spend_time_af // Arrange $data = $this->createUserWithPermission([ 'time-entries:update:own', + 'projects:view:all', ]); $oldProject = Project::factory()->forOrganization($data->organization)->create(); $oldTask = Task::factory()->forOrganization($data->organization)->forProject($oldProject)->create(); @@ -3029,11 +3118,53 @@ public function test_update_multiple_endpoint_fails_if_user_has_no_permission_to $response->assertForbidden(); } + public function test_update_multiple_endpoint_fails_if_employee_tries_to_update_time_entries_to_private_project_without_access(): void + { + // Arrange + $data = $this->createUserWithPermission([ + 'time-entries:update:own', + ]); + + // Create time entries for the employee + $timeEntry1 = TimeEntry::factory()->forOrganization($data->organization)->forMember($data->member)->create(); + $timeEntry2 = TimeEntry::factory()->forOrganization($data->organization)->forMember($data->member)->create(); + + // Create a private project that the employee is not a member of + $privateProject = Project::factory()->forOrganization($data->organization)->create([ + 'is_public' => false, + ]); + + Passport::actingAs($data->user); + + // Act + $response = $this->patchJson(route('api.v1.time-entries.update-multiple', [$data->organization->getKey()]), [ + 'ids' => [$timeEntry1->getKey(), $timeEntry2->getKey()], + 'changes' => [ + 'project_id' => $privateProject->getKey(), + ], + ]); + + // Assert + $response->assertStatus(422); + $response->assertJsonValidationErrors(['changes.project_id']); + + // Verify the time entries were NOT updated in the database + $this->assertDatabaseMissing(TimeEntry::class, [ + 'id' => $timeEntry1->getKey(), + 'project_id' => $privateProject->getKey(), + ]); + $this->assertDatabaseMissing(TimeEntry::class, [ + 'id' => $timeEntry2->getKey(), + 'project_id' => $privateProject->getKey(), + ]); + } + public function test_update_multiple_remove_task_from_time_entries_only_if_project_is_set_to_a_new_value_without_setting_a_new_task(): void { // Arrange $data = $this->createUserWithPermission([ 'time-entries:update:own', + 'projects:view:all', ]); $project1 = Project::factory()->forOrganization($data->organization)->create(); $project2 = Project::factory()->forOrganization($data->organization)->create(); @@ -3081,6 +3212,7 @@ public function test_update_multiple_updates_own_time_entries_and_fails_for_time // Arrange $data = $this->createUserWithPermission([ 'time-entries:update:own', + 'projects:view:all', ]); $otherData = $this->createUserWithPermission(); $otherUser = User::factory()->create(); @@ -3138,6 +3270,7 @@ public function test_update_multiple_updates_own_time_entries_and_fails_for_time // Arrange $data = $this->createUserWithPermission([ 'time-entries:update:own', + 'projects:view:all', ]); $otherData = $this->createUserWithPermission(); $otherUser = User::factory()->create(); @@ -3217,6 +3350,7 @@ public function test_update_multiple_updates_sets_description_to_empty_if_the_cl // Arrange $data = $this->createUserWithPermission([ 'time-entries:update:own', + 'projects:view:all', ]); $timeEntry1 = TimeEntry::factory()->forMember($data->member)->create([ 'description' => '', @@ -3398,6 +3532,7 @@ public function test_store_endpoint_blocks_overlapping_entries_when_start_overla // Arrange $data = $this->createUserWithPermission([ 'time-entries:create:own', + 'projects:view:all', ]); $data->organization->prevent_overlapping_time_entries = true; $data->organization->save(); @@ -3432,6 +3567,7 @@ public function test_store_endpoint_blocks_overlapping_entries_when_end_overlaps // Arrange $data = $this->createUserWithPermission([ 'time-entries:create:own', + 'projects:view:all', ]); $data->organization->prevent_overlapping_time_entries = true; $data->organization->save(); @@ -3466,6 +3602,7 @@ public function test_store_endpoint_blocks_overlapping_entries_when_new_entry_is // Arrange $data = $this->createUserWithPermission([ 'time-entries:create:own', + 'projects:view:all', ]); $data->organization->prevent_overlapping_time_entries = true; $data->organization->save(); @@ -3500,6 +3637,7 @@ public function test_store_endpoint_blocks_overlapping_entries_when_new_entry_su // Arrange $data = $this->createUserWithPermission([ 'time-entries:create:own', + 'projects:view:all', ]); $data->organization->prevent_overlapping_time_entries = true; $data->organization->save(); @@ -3534,6 +3672,7 @@ public function test_store_endpoint_blocks_starting_active_entry_when_it_overlap // Arrange $data = $this->createUserWithPermission([ 'time-entries:create:own', + 'projects:view:all', ]); $data->organization->prevent_overlapping_time_entries = true; $data->organization->save(); @@ -3570,6 +3709,7 @@ public function test_store_endpoint_allows_future_time_entries_even_with_running $this->travelTo($now); $data = $this->createUserWithPermission([ 'time-entries:create:own', + 'projects:view:all', ]); $data->organization->prevent_overlapping_time_entries = true; $data->organization->save(); @@ -3597,6 +3737,7 @@ public function test_update_endpoint_blocks_overlap_and_excludes_current_entry() // Arrange $data = $this->createUserWithPermission([ 'time-entries:update:own', + 'projects:view:all', ]); $data->organization->prevent_overlapping_time_entries = true; $data->organization->save(); @@ -3820,6 +3961,7 @@ public function test_update_multiple_updates_own_time_entries_fails_if_member_id // Arrange $data = $this->createUserWithPermission([ 'time-entries:update:own', + 'projects:view:all', ]); $otherUser = User::factory()->create(); $otherMember = Member::factory()->forOrganization($data->organization)->forUser($otherUser)->role(Role::Employee)->create(); From db57055941574319a1690891b582de59e146d935 Mon Sep 17 00:00:00 2001 From: Gregor Vostrak Date: Wed, 7 Jan 2026 20:16:56 +0100 Subject: [PATCH 008/115] add filters and sorting to projects table --- docker-compose.yml | 2 +- e2e/projects.spec.ts | 210 ++++++++++++++++-- .../Common/Client/ClientTableHeading.vue | 7 +- .../Invitation/InvitationTableHeading.vue | 5 +- .../Common/Member/MemberTableHeading.vue | 11 +- .../Common/Project/BaseFilterBadge.vue | 50 +++++ .../Project/ProjectClientFilterBadge.vue | 68 ++++++ .../Common/Project/ProjectDropdown.vue | 2 +- .../Project/ProjectStatusFilterBadge.vue | 46 ++++ .../Common/Project/ProjectTable.vue | 100 ++++++++- .../Common/Project/ProjectTableHeading.vue | 80 ++++++- .../Common/Project/ProjectTableRow.vue | 14 +- .../Common/Project/ProjectsFilterDropdown.vue | 129 +++++++++++ .../js/Components/Common/Project/constants.ts | 1 + .../ProjectMemberTableHeading.vue | 7 +- .../Common/Report/ReportTableHeading.vue | 9 +- .../js/Components/Common/TableHeading.vue | 2 +- .../Components/Common/Tag/TagTableHeading.vue | 3 +- .../Common/Task/TaskTableHeading.vue | 9 +- resources/js/Components/ui/tabs/TabsList.vue | 4 +- resources/js/Pages/Projects.vue | 135 +++++++++-- .../packages/ui/src/Client/ClientDropdown.vue | 2 +- .../packages/ui/src/Icons/ListFilterIcon.vue | 20 ++ .../ui/src/Input/MultiselectDropdown.vue | 2 +- .../js/packages/ui/src/Tag/TagDropdown.vue | 2 +- .../TimeTrackerProjectTaskDropdown.vue | 2 +- .../TimeTracker/TimeTrackerRangeSelector.vue | 2 +- resources/js/packages/ui/styles.css | 40 +--- resources/js/packages/ui/tailwind.theme.js | 10 +- resources/js/utils/useProjects.ts | 9 + resources/js/utils/useProjectsQuery.ts | 34 +++ tailwind.config.js | 1 + 32 files changed, 887 insertions(+), 131 deletions(-) create mode 100644 resources/js/Components/Common/Project/BaseFilterBadge.vue create mode 100644 resources/js/Components/Common/Project/ProjectClientFilterBadge.vue create mode 100644 resources/js/Components/Common/Project/ProjectStatusFilterBadge.vue create mode 100644 resources/js/Components/Common/Project/ProjectsFilterDropdown.vue create mode 100644 resources/js/Components/Common/Project/constants.ts create mode 100644 resources/js/packages/ui/src/Icons/ListFilterIcon.vue create mode 100644 resources/js/utils/useProjectsQuery.ts diff --git a/docker-compose.yml b/docker-compose.yml index 53d73ed4..6974efb1 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -107,7 +107,7 @@ services: - sail - reverse-proxy playwright: - image: mcr.microsoft.com/playwright:v1.51.1-jammy + image: mcr.microsoft.com/playwright:v1.57.0-jammy command: ['npx', 'playwright', 'test', '--ui-port=8080', '--ui-host=0.0.0.0'] working_dir: /src extra_hosts: diff --git a/e2e/projects.spec.ts b/e2e/projects.spec.ts index 9dd51c5d..b052baed 100644 --- a/e2e/projects.spec.ts +++ b/e2e/projects.spec.ts @@ -8,6 +8,13 @@ async function goToProjectsOverview(page: Page) { await page.goto(PLAYWRIGHT_BASE_URL + '/projects'); } +// Helper to clear localStorage before tests that check persistence +async function clearProjectTableState(page: Page) { + await page.evaluate(() => { + localStorage.removeItem('project-table-state'); + }); +} + // Create new project via modal test('test that creating and deleting a new project via the modal works', async ({ page }) => { const newProjectName = 'New Project ' + Math.floor(1 + Math.random() * 10000); @@ -45,34 +52,62 @@ test('test that creating and deleting a new project via the modal works', async await expect(page.getByTestId('project_table')).not.toContainText(newProjectName); }); +// Helper to select a status filter using the new dropdown UI +async function selectStatusFilter(page: Page, status: 'Active' | 'Archived') { + // Click the Filter button to open the dropdown + await page.getByRole('button', { name: 'Filter projects' }).click(); + // Click on Status submenu + await page.getByRole('menuitem', { name: 'Status' }).click(); + // Select the status option + await page.getByRole('menuitem', { name: status }).click(); +} + +// Helper to remove status filter by clicking the X on the badge +async function removeStatusFilter(page: Page) { + const statusBadge = page.getByTestId('status-filter-badge'); + // Click the remove button (second button in the badge, contains XMarkIcon) + await statusBadge.locator('button').last().click(); +} + test('test that archiving and unarchiving projects works', async ({ page }) => { const newProjectName = 'New Project ' + Math.floor(1 + Math.random() * 10000); await goToProjectsOverview(page); + await clearProjectTableState(page); + await page.reload(); + await page.getByRole('button', { name: 'Create Project' }).click(); await page.getByLabel('Project Name').fill(newProjectName); await page.getByRole('button', { name: 'Create Project' }).click(); await expect(page.getByText(newProjectName)).toBeVisible(); + // Archive the project await page.getByRole('row').first().getByRole('button').click(); - await Promise.all([ - page.getByRole('menuitem').getByText('Archive').first().click(), - expect(page.getByText(newProjectName)).not.toBeVisible(), - ]); - await Promise.all([ - page.getByRole('tab', { name: 'Archived' }).click(), - expect(page.getByText(newProjectName)).toBeVisible(), - ]); + await page.getByRole('menuitem').getByText('Archive').first().click(); + + // Project should still be visible since default is "all" (no filter) + await expect(page.getByText(newProjectName)).toBeVisible(); + // Apply Active filter - archived project should disappear + await selectStatusFilter(page, 'Active'); + await expect(page.getByText(newProjectName)).not.toBeVisible(); + + // Remove Active filter and apply Archived filter + await removeStatusFilter(page); + await selectStatusFilter(page, 'Archived'); + await expect(page.getByText(newProjectName)).toBeVisible(); + + // Unarchive the project await page.getByRole('row').first().getByRole('button').click(); - await Promise.all([ - page.getByRole('menuitem').getByText('Unarchive').first().click(), - expect(page.getByText(newProjectName)).not.toBeVisible(), - ]); - await Promise.all([ - page.getByRole('tab', { name: 'Active' }).click(), - expect(page.getByText(newProjectName)).toBeVisible(), - ]); + await page.getByRole('menuitem').getByText('Unarchive').first().click(); + + // Project should disappear from Archived view + await expect(page.getByText(newProjectName)).not.toBeVisible(); + + // Remove Archived filter and apply Active filter to see the project + await removeStatusFilter(page); + await selectStatusFilter(page, 'Active'); + await expect(page.getByText(newProjectName)).toBeVisible(); }); test('test that updating billable rate works with existing time entries', async ({ page }) => { @@ -116,6 +151,147 @@ test('test that updating billable rate works with existing time entries', async ).toBeVisible(); }); +// Sorting tests +test('test that sorting projects by name works', async ({ page }) => { + await goToProjectsOverview(page); + await clearProjectTableState(page); + await page.reload(); + + // Wait for the table to load + await expect(page.getByTestId('project_table')).toBeVisible(); + + // Get initial project names + const getProjectNames = async () => { + const rows = page + .getByTestId('project_table') + .locator('[data-testid="project_table"] > div') + .filter({ hasNot: page.locator('.border-t') }); + const names: string[] = []; + const count = await page.getByTestId('project_table').getByRole('row').count(); + for (let i = 0; i < count; i++) { + const row = page.getByTestId('project_table').getByRole('row').nth(i); + const nameCell = row.locator('div').first(); + const text = await nameCell.textContent(); + if (text) { + names.push(text.trim()); + } + } + return names; + }; + + // Click on Name header to sort ascending (default should already be ascending) + const nameHeader = page.getByText('Name').first(); + await nameHeader.click(); + + // Wait for sort to apply + await page.waitForTimeout(100); + + // Click again to sort descending + await nameHeader.click(); + await page.waitForTimeout(100); + + // Verify the sort indicator is showing descending + await expect(page.locator('svg').first()).toBeVisible(); +}); + +test('test that sorting projects by status works', async ({ page }) => { + await goToProjectsOverview(page); + await clearProjectTableState(page); + await page.reload(); + + // Default is "all" so no filter needed - Wait for the table to load + await expect(page.getByTestId('project_table')).toBeVisible(); + + // Click on Status header to sort + const statusHeader = page.getByText('Status').first(); + await statusHeader.click(); + + // Wait for sort to apply + await page.waitForTimeout(100); + + // Sort indicator should be visible + await expect(statusHeader.locator('svg')).toBeVisible(); +}); + +// Filter tests +test('test that filtering projects by status works', async ({ page }) => { + const newProjectName = 'Filter Test Project ' + Math.floor(1 + Math.random() * 10000); + await goToProjectsOverview(page); + await clearProjectTableState(page); + await page.reload(); + + // Create a new project + await page.getByRole('button', { name: 'Create Project' }).click(); + await page.getByLabel('Project Name').fill(newProjectName); + await page.getByRole('button', { name: 'Create Project' }).click(); + await expect(page.getByText(newProjectName)).toBeVisible(); + + // Archive the project + await page.getByRole('row').first().getByRole('button').click(); + await page.getByRole('menuitem').getByText('Archive').first().click(); + + // Project should still be visible (default is "all" - no filter) + await expect(page.getByText(newProjectName)).toBeVisible(); + + // Apply Active filter - archived project should disappear + await selectStatusFilter(page, 'Active'); + await expect(page.getByText(newProjectName)).not.toBeVisible(); + + // Remove Active filter - project should reappear (back to "all") + await removeStatusFilter(page); + await expect(page.getByText(newProjectName)).toBeVisible(); + + // Apply Archived filter - project should still be visible + await selectStatusFilter(page, 'Archived'); + await expect(page.getByText(newProjectName)).toBeVisible(); + + // Remove Archived filter and apply Active filter - project should not be visible + await removeStatusFilter(page); + await selectStatusFilter(page, 'Active'); + await expect(page.getByText(newProjectName)).not.toBeVisible(); +}); + +test('test that filter state persists after page reload', async ({ page }) => { + await goToProjectsOverview(page); + await clearProjectTableState(page); + await page.reload(); + + // Apply Active status filter + await selectStatusFilter(page, 'Active'); + + // Verify the filter badge is visible + await expect(page.getByTestId('status-filter-badge')).toBeVisible(); + + // Wait for the state to be saved + await page.waitForTimeout(100); + + // Reload the page + await page.reload(); + + // Verify the filter badge is still visible after reload + await expect(page.getByTestId('status-filter-badge')).toBeVisible(); +}); + +test('test that sort state persists after page reload', async ({ page }) => { + await goToProjectsOverview(page); + await clearProjectTableState(page); + await page.reload(); + + // Click on Name header twice to sort descending + const nameHeader = page.getByText('Name').first(); + await nameHeader.click(); + await nameHeader.click(); + + // Wait for the state to be saved + await page.waitForTimeout(100); + + // Reload the page + await page.reload(); + + // Verify descending sort indicator is visible on Name column + await expect(page.getByTestId('project_table')).toBeVisible(); +}); + // Create new project with new Client // Create new project with existing Client @@ -124,8 +300,6 @@ test('test that updating billable rate works with existing time entries', async // Test that project task count is displayed correctly -// Test that active / archive / all filter works (once implemented) - // Edit Project Modal Test // Add Project with billable rate diff --git a/resources/js/Components/Common/Client/ClientTableHeading.vue b/resources/js/Components/Common/Client/ClientTableHeading.vue index 45971b78..8817be67 100644 --- a/resources/js/Components/Common/Client/ClientTableHeading.vue +++ b/resources/js/Components/Common/Client/ClientTableHeading.vue @@ -4,12 +4,11 @@ import TableHeading from '@/Components/Common/TableHeading.vue';