mirror of
https://github.com/solidtime-io/solidtime.git
synced 2026-08-19 05:32:16 +01:00
Compare commits
8 Commits
f308cf6295
...
5129aa51dd
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5129aa51dd | ||
|
|
114a32536d | ||
|
|
ff8a0f065b | ||
|
|
44fd0ffb91 | ||
|
|
c07c62bfab | ||
|
|
f599757761 | ||
|
|
e54fd2460c | ||
|
|
e997a2b39f |
54
.dockerignore
Normal file
54
.dockerignore
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
.git
|
||||||
|
**/.git
|
||||||
|
.gitmodules
|
||||||
|
**/.gitmodules
|
||||||
|
.github
|
||||||
|
.DS_Store
|
||||||
|
.fleet
|
||||||
|
.idea
|
||||||
|
.vscode
|
||||||
|
*.log
|
||||||
|
npm-debug.log
|
||||||
|
yarn-error.log
|
||||||
|
k8s
|
||||||
|
docs
|
||||||
|
e2e
|
||||||
|
tests
|
||||||
|
|
||||||
|
docker-compose.yml
|
||||||
|
docker/local
|
||||||
|
|
||||||
|
.phpunit.cache
|
||||||
|
.phpunit.result.cache
|
||||||
|
coverage
|
||||||
|
test-results
|
||||||
|
playwright-report
|
||||||
|
blob-report
|
||||||
|
playwright/.cache
|
||||||
|
openapi.json
|
||||||
|
playwright
|
||||||
|
playwright.config.ts
|
||||||
|
vitest.config.ts
|
||||||
|
phpunit.xml
|
||||||
|
phpstan.neon
|
||||||
|
pint.json
|
||||||
|
eslint.config.mjs
|
||||||
|
tsconfig.json
|
||||||
|
jsconfig.json
|
||||||
|
postcss.config.js
|
||||||
|
tailwind.config.js
|
||||||
|
|
||||||
|
node_modules
|
||||||
|
extensions/*/node_modules
|
||||||
|
|
||||||
|
Homestead.json
|
||||||
|
Homestead.yaml
|
||||||
|
auth.json
|
||||||
|
.env.backup
|
||||||
|
.rnd
|
||||||
|
|
||||||
|
_ide_helper.php
|
||||||
|
.phpstorm.meta.php
|
||||||
|
|
||||||
|
storage/logs/*
|
||||||
|
storage/*.key
|
||||||
19
.github/workflows/build-onpremise.yml
vendored
19
.github/workflows/build-onpremise.yml
vendored
@@ -8,6 +8,8 @@ on:
|
|||||||
pull_request:
|
pull_request:
|
||||||
paths:
|
paths:
|
||||||
- '.github/workflows/build-onpremise.yml'
|
- '.github/workflows/build-onpremise.yml'
|
||||||
|
- '.dockerignore'
|
||||||
|
- 'extensions/manifest.json'
|
||||||
- 'docker/prod/**'
|
- 'docker/prod/**'
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
@@ -35,7 +37,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: "Check out code"
|
- name: "Check out code"
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v7
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0 # Required for WyriHaximus/github-action-get-previous-tag
|
fetch-depth: 0 # Required for WyriHaximus/github-action-get-previous-tag
|
||||||
|
|
||||||
@@ -91,14 +93,23 @@ jobs:
|
|||||||
if: steps.cache-vendor.outputs.cache-hit != 'true' # Skip if cache hit
|
if: steps.cache-vendor.outputs.cache-hit != 'true' # Skip if cache hit
|
||||||
|
|
||||||
- name: "Use Node.js"
|
- name: "Use Node.js"
|
||||||
uses: actions/setup-node@v6
|
uses: actions/setup-node@v7
|
||||||
with:
|
with:
|
||||||
node-version: '20.x'
|
node-version: '20.x'
|
||||||
|
|
||||||
|
- name: "Read extension manifest"
|
||||||
|
id: extension-manifest
|
||||||
|
run: |
|
||||||
|
{
|
||||||
|
echo "invoicing_repository=$(jq -r '.Invoicing.repository' extensions/manifest.json)"
|
||||||
|
echo "invoicing_ref=$(jq -r '.Invoicing.ref' extensions/manifest.json)"
|
||||||
|
} >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
- name: "Checkout invoicing extension"
|
- name: "Checkout invoicing extension"
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v7
|
||||||
with:
|
with:
|
||||||
repository: solidtime-io/extension-invoicing
|
repository: ${{ steps.extension-manifest.outputs.invoicing_repository }}
|
||||||
|
ref: ${{ steps.extension-manifest.outputs.invoicing_ref }}
|
||||||
path: extensions/Invoicing
|
path: extensions/Invoicing
|
||||||
ssh-key: ${{ secrets.SSH_PRIVATE_KEY_INVOICING_EXTENSION }}
|
ssh-key: ${{ secrets.SSH_PRIVATE_KEY_INVOICING_EXTENSION }}
|
||||||
|
|
||||||
|
|||||||
33
.github/workflows/build-private.yml
vendored
33
.github/workflows/build-private.yml
vendored
@@ -8,6 +8,8 @@ on:
|
|||||||
pull_request:
|
pull_request:
|
||||||
paths:
|
paths:
|
||||||
- '.github/workflows/build-private.yml'
|
- '.github/workflows/build-private.yml'
|
||||||
|
- '.dockerignore'
|
||||||
|
- 'extensions/manifest.json'
|
||||||
- 'docker/prod/**'
|
- 'docker/prod/**'
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
permissions:
|
permissions:
|
||||||
@@ -22,7 +24,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: "Check out code"
|
- name: "Check out code"
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v7
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0 # Required for WyriHaximus/github-action-get-previous-tag
|
fetch-depth: 0 # Required for WyriHaximus/github-action-get-previous-tag
|
||||||
|
|
||||||
@@ -68,14 +70,27 @@ jobs:
|
|||||||
run: cat .env
|
run: cat .env
|
||||||
|
|
||||||
- name: "Use Node.js"
|
- name: "Use Node.js"
|
||||||
uses: actions/setup-node@v6
|
uses: actions/setup-node@v7
|
||||||
with:
|
with:
|
||||||
node-version: '20.x'
|
node-version: '20.x'
|
||||||
|
|
||||||
|
- name: "Read extension manifest"
|
||||||
|
id: extension-manifest
|
||||||
|
run: |
|
||||||
|
{
|
||||||
|
echo "billing_repository=$(jq -r '.Billing.repository' extensions/manifest.json)"
|
||||||
|
echo "billing_ref=$(jq -r '.Billing.ref' extensions/manifest.json)"
|
||||||
|
echo "services_repository=$(jq -r '.Services.repository' extensions/manifest.json)"
|
||||||
|
echo "services_ref=$(jq -r '.Services.ref' extensions/manifest.json)"
|
||||||
|
echo "invoicing_repository=$(jq -r '.Invoicing.repository' extensions/manifest.json)"
|
||||||
|
echo "invoicing_ref=$(jq -r '.Invoicing.ref' extensions/manifest.json)"
|
||||||
|
} >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
- name: "Checkout billing extension"
|
- name: "Checkout billing extension"
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v7
|
||||||
with:
|
with:
|
||||||
repository: solidtime-io/extension-billing
|
repository: ${{ steps.extension-manifest.outputs.billing_repository }}
|
||||||
|
ref: ${{ steps.extension-manifest.outputs.billing_ref }}
|
||||||
path: extensions/Billing
|
path: extensions/Billing
|
||||||
ssh-key: ${{ secrets.SSH_PRIVATE_KEY_BILLING_EXTENSION }}
|
ssh-key: ${{ secrets.SSH_PRIVATE_KEY_BILLING_EXTENSION }}
|
||||||
|
|
||||||
@@ -93,9 +108,10 @@ jobs:
|
|||||||
run: cd extensions/Billing && npm ci
|
run: cd extensions/Billing && npm ci
|
||||||
|
|
||||||
- name: "Checkout services extension"
|
- name: "Checkout services extension"
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v7
|
||||||
with:
|
with:
|
||||||
repository: solidtime-io/extension-services
|
repository: ${{ steps.extension-manifest.outputs.services_repository }}
|
||||||
|
ref: ${{ steps.extension-manifest.outputs.services_ref }}
|
||||||
path: extensions/Services
|
path: extensions/Services
|
||||||
ssh-key: ${{ secrets.SSH_PRIVATE_KEY_SERVICES_EXTENSION }}
|
ssh-key: ${{ secrets.SSH_PRIVATE_KEY_SERVICES_EXTENSION }}
|
||||||
|
|
||||||
@@ -111,9 +127,10 @@ jobs:
|
|||||||
run: cd extensions/Services && npm ci
|
run: cd extensions/Services && npm ci
|
||||||
|
|
||||||
- name: "Checkout invoicing extension"
|
- name: "Checkout invoicing extension"
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v7
|
||||||
with:
|
with:
|
||||||
repository: solidtime-io/extension-invoicing
|
repository: ${{ steps.extension-manifest.outputs.invoicing_repository }}
|
||||||
|
ref: ${{ steps.extension-manifest.outputs.invoicing_ref }}
|
||||||
path: extensions/Invoicing
|
path: extensions/Invoicing
|
||||||
ssh-key: ${{ secrets.SSH_PRIVATE_KEY_INVOICING_EXTENSION }}
|
ssh-key: ${{ secrets.SSH_PRIVATE_KEY_INVOICING_EXTENSION }}
|
||||||
|
|
||||||
|
|||||||
5
.github/workflows/build-public.yml
vendored
5
.github/workflows/build-public.yml
vendored
@@ -8,6 +8,7 @@ on:
|
|||||||
pull_request:
|
pull_request:
|
||||||
paths:
|
paths:
|
||||||
- '.github/workflows/build-public.yml'
|
- '.github/workflows/build-public.yml'
|
||||||
|
- '.dockerignore'
|
||||||
- 'docker/prod/**'
|
- 'docker/prod/**'
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
@@ -36,7 +37,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: "Check out code"
|
- name: "Check out code"
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v7
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0 # Required for WyriHaximus/github-action-get-previous-tag
|
fetch-depth: 0 # Required for WyriHaximus/github-action-get-previous-tag
|
||||||
|
|
||||||
@@ -92,7 +93,7 @@ jobs:
|
|||||||
if: steps.cache-vendor.outputs.cache-hit != 'true' # Skip if cache hit
|
if: steps.cache-vendor.outputs.cache-hit != 'true' # Skip if cache hit
|
||||||
|
|
||||||
- name: "Use Node.js"
|
- name: "Use Node.js"
|
||||||
uses: actions/setup-node@v6
|
uses: actions/setup-node@v7
|
||||||
with:
|
with:
|
||||||
node-version: '20.x'
|
node-version: '20.x'
|
||||||
|
|
||||||
|
|||||||
2
.github/workflows/generate-api-docs.yml
vendored
2
.github/workflows/generate-api-docs.yml
vendored
@@ -29,7 +29,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: "Checkout code"
|
- name: "Checkout code"
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v7
|
||||||
|
|
||||||
- name: "Setup PHP"
|
- name: "Setup PHP"
|
||||||
uses: shivammathur/setup-php@v2
|
uses: shivammathur/setup-php@v2
|
||||||
|
|||||||
4
.github/workflows/npm-build.yml
vendored
4
.github/workflows/npm-build.yml
vendored
@@ -11,7 +11,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: "Checkout code"
|
- name: "Checkout code"
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v7
|
||||||
|
|
||||||
- name: "Setup PHP (for Ziggy)"
|
- name: "Setup PHP (for Ziggy)"
|
||||||
uses: shivammathur/setup-php@v2
|
uses: shivammathur/setup-php@v2
|
||||||
@@ -24,7 +24,7 @@ jobs:
|
|||||||
run: composer install -n --prefer-dist
|
run: composer install -n --prefer-dist
|
||||||
|
|
||||||
- name: "Use Node.js"
|
- name: "Use Node.js"
|
||||||
uses: actions/setup-node@v6
|
uses: actions/setup-node@v7
|
||||||
with:
|
with:
|
||||||
node-version: '20.x'
|
node-version: '20.x'
|
||||||
|
|
||||||
|
|||||||
4
.github/workflows/npm-format-check.yml
vendored
4
.github/workflows/npm-format-check.yml
vendored
@@ -9,10 +9,10 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: "Checkout code"
|
- name: "Checkout code"
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v7
|
||||||
|
|
||||||
- name: "Use Node.js"
|
- name: "Use Node.js"
|
||||||
uses: actions/setup-node@v6
|
uses: actions/setup-node@v7
|
||||||
with:
|
with:
|
||||||
node-version: '20.x'
|
node-version: '20.x'
|
||||||
|
|
||||||
|
|||||||
4
.github/workflows/npm-lint.yml
vendored
4
.github/workflows/npm-lint.yml
vendored
@@ -11,10 +11,10 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: "Checkout code"
|
- name: "Checkout code"
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v7
|
||||||
|
|
||||||
- name: "Use Node.js"
|
- name: "Use Node.js"
|
||||||
uses: actions/setup-node@v6
|
uses: actions/setup-node@v7
|
||||||
with:
|
with:
|
||||||
node-version: '20.x'
|
node-version: '20.x'
|
||||||
|
|
||||||
|
|||||||
4
.github/workflows/npm-publish-api.yml
vendored
4
.github/workflows/npm-publish-api.yml
vendored
@@ -11,11 +11,11 @@ jobs:
|
|||||||
id-token: write
|
id-token: write
|
||||||
steps:
|
steps:
|
||||||
- name: "Checkout code"
|
- name: "Checkout code"
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v7
|
||||||
# Setup .npmrc file to publish to npm
|
# Setup .npmrc file to publish to npm
|
||||||
- name: Install root project dependencies
|
- name: Install root project dependencies
|
||||||
run: npm ci
|
run: npm ci
|
||||||
- uses: actions/setup-node@v6
|
- uses: actions/setup-node@v7
|
||||||
with:
|
with:
|
||||||
node-version: '20.x'
|
node-version: '20.x'
|
||||||
registry-url: 'https://registry.npmjs.org'
|
registry-url: 'https://registry.npmjs.org'
|
||||||
|
|||||||
4
.github/workflows/npm-publish-ui.yml
vendored
4
.github/workflows/npm-publish-ui.yml
vendored
@@ -11,9 +11,9 @@ jobs:
|
|||||||
id-token: write
|
id-token: write
|
||||||
steps:
|
steps:
|
||||||
- name: "Checkout code"
|
- name: "Checkout code"
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v7
|
||||||
# Setup .npmrc file to publish to npm
|
# Setup .npmrc file to publish to npm
|
||||||
- uses: actions/setup-node@v6
|
- uses: actions/setup-node@v7
|
||||||
with:
|
with:
|
||||||
node-version: '20.x'
|
node-version: '20.x'
|
||||||
registry-url: 'https://registry.npmjs.org'
|
registry-url: 'https://registry.npmjs.org'
|
||||||
|
|||||||
4
.github/workflows/npm-test-unit.yml
vendored
4
.github/workflows/npm-test-unit.yml
vendored
@@ -13,10 +13,10 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: "Checkout code"
|
- name: "Checkout code"
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v7
|
||||||
|
|
||||||
- name: "Use Node.js"
|
- name: "Use Node.js"
|
||||||
uses: actions/setup-node@v6
|
uses: actions/setup-node@v7
|
||||||
with:
|
with:
|
||||||
node-version: '20.x'
|
node-version: '20.x'
|
||||||
|
|
||||||
|
|||||||
4
.github/workflows/npm-typecheck.yml
vendored
4
.github/workflows/npm-typecheck.yml
vendored
@@ -10,7 +10,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: "Checkout code"
|
- name: "Checkout code"
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v7
|
||||||
|
|
||||||
- name: "Setup PHP (for Ziggy)"
|
- name: "Setup PHP (for Ziggy)"
|
||||||
uses: shivammathur/setup-php@v2
|
uses: shivammathur/setup-php@v2
|
||||||
@@ -23,7 +23,7 @@ jobs:
|
|||||||
run: composer install -n --prefer-dist
|
run: composer install -n --prefer-dist
|
||||||
|
|
||||||
- name: "Use Node.js"
|
- name: "Use Node.js"
|
||||||
uses: actions/setup-node@v6
|
uses: actions/setup-node@v7
|
||||||
with:
|
with:
|
||||||
node-version: '20.x'
|
node-version: '20.x'
|
||||||
|
|
||||||
|
|||||||
2
.github/workflows/phpstan.yml
vendored
2
.github/workflows/phpstan.yml
vendored
@@ -9,7 +9,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: "Checkout code"
|
- name: "Checkout code"
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v7
|
||||||
|
|
||||||
- name: "Setup PHP"
|
- name: "Setup PHP"
|
||||||
uses: shivammathur/setup-php@v2
|
uses: shivammathur/setup-php@v2
|
||||||
|
|||||||
4
.github/workflows/phpunit.yml
vendored
4
.github/workflows/phpunit.yml
vendored
@@ -36,7 +36,7 @@ jobs:
|
|||||||
--health-retries 5
|
--health-retries 5
|
||||||
steps:
|
steps:
|
||||||
- name: "Checkout code"
|
- name: "Checkout code"
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v7
|
||||||
|
|
||||||
- name: "Setup PHP"
|
- name: "Setup PHP"
|
||||||
uses: shivammathur/setup-php@v2
|
uses: shivammathur/setup-php@v2
|
||||||
@@ -48,7 +48,7 @@ jobs:
|
|||||||
- name: "Run composer install"
|
- name: "Run composer install"
|
||||||
run: composer install -n --prefer-dist
|
run: composer install -n --prefer-dist
|
||||||
|
|
||||||
- uses: actions/setup-node@v6
|
- uses: actions/setup-node@v7
|
||||||
with:
|
with:
|
||||||
node-version: '20.x'
|
node-version: '20.x'
|
||||||
|
|
||||||
|
|||||||
2
.github/workflows/pint.yml
vendored
2
.github/workflows/pint.yml
vendored
@@ -9,7 +9,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: "Checkout code"
|
- name: "Checkout code"
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v7
|
||||||
|
|
||||||
- name: "Check code style"
|
- name: "Check code style"
|
||||||
uses: aglipanci/laravel-pint-action@2.6
|
uses: aglipanci/laravel-pint-action@2.6
|
||||||
|
|||||||
8
.github/workflows/playwright.yml
vendored
8
.github/workflows/playwright.yml
vendored
@@ -35,10 +35,10 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: "Checkout code"
|
- name: "Checkout code"
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v7
|
||||||
|
|
||||||
- name: "Setup node"
|
- name: "Setup node"
|
||||||
uses: actions/setup-node@v6
|
uses: actions/setup-node@v7
|
||||||
with:
|
with:
|
||||||
node-version: '20.x'
|
node-version: '20.x'
|
||||||
|
|
||||||
@@ -99,10 +99,10 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: "Checkout code"
|
- name: "Checkout code"
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v7
|
||||||
|
|
||||||
- name: "Setup node"
|
- name: "Setup node"
|
||||||
uses: actions/setup-node@v6
|
uses: actions/setup-node@v7
|
||||||
with:
|
with:
|
||||||
node-version: '20.x'
|
node-version: '20.x'
|
||||||
|
|
||||||
|
|||||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -26,9 +26,10 @@ yarn-error.log
|
|||||||
/blob-report/
|
/blob-report/
|
||||||
/playwright/.cache/
|
/playwright/.cache/
|
||||||
/coverage
|
/coverage
|
||||||
/extensions
|
/extensions/*
|
||||||
!/extensions/.gitkeep
|
!/extensions/.gitkeep
|
||||||
!/extensions/extensions_autoload.php
|
!/extensions/extensions_autoload.php
|
||||||
|
!/extensions/manifest.json
|
||||||
/auth.json
|
/auth.json
|
||||||
/modules_statuses.json
|
/modules_statuses.json
|
||||||
/k8s
|
/k8s
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ class TimeEntryController extends Controller
|
|||||||
|
|
||||||
$query = TimeEntry::query()
|
$query = TimeEntry::query()
|
||||||
->where('organization_id', $organization->getKey())
|
->where('organization_id', $organization->getKey())
|
||||||
->where('user_id', $member->user_id)
|
->where('member_id', $member->getKey())
|
||||||
->when($exclude !== null, function (Builder $q) use ($exclude): void {
|
->when($exclude !== null, function (Builder $q) use ($exclude): void {
|
||||||
$q->where('id', '!=', $exclude->getKey());
|
$q->where('id', '!=', $exclude->getKey());
|
||||||
})
|
})
|
||||||
@@ -107,8 +107,8 @@ class TimeEntryController extends Controller
|
|||||||
/**
|
/**
|
||||||
* Get time entries in organization
|
* Get time entries in organization
|
||||||
*
|
*
|
||||||
* If you only need time entries for a specific user, you can filter by `user_id`.
|
* If you only need time entries for a specific user, you can filter by `member_id`.
|
||||||
* Users with the permission `time-entries:view:own` can only use this endpoint with their own user ID in the user_id filter.
|
* Users with the permission `time-entries:view:own` can only use this endpoint with their own member ID in the member_id filter.
|
||||||
*
|
*
|
||||||
* @return TimeEntryCollection<TimeEntryResource>
|
* @return TimeEntryCollection<TimeEntryResource>
|
||||||
*
|
*
|
||||||
@@ -118,16 +118,17 @@ class TimeEntryController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function index(Organization $organization, TimeEntryIndexRequest $request): JsonResource
|
public function index(Organization $organization, TimeEntryIndexRequest $request): JsonResource
|
||||||
{
|
{
|
||||||
/** @var Member|null $member */
|
$member = $this->member($organization);
|
||||||
$member = $request->has('member_id') ? Member::query()->findOrFail($request->input('member_id')) : null;
|
/** @var Member|null $memberFilter */
|
||||||
if ($member !== null && $member->user_id === Auth::id()) {
|
$memberFilter = $request->has('member_id') ? Member::query()->findOrFail($request->input('member_id')) : null;
|
||||||
|
if ($memberFilter !== null && $memberFilter->getKey() === $member->getKey()) {
|
||||||
$this->checkPermission($organization, 'time-entries:view:own');
|
$this->checkPermission($organization, 'time-entries:view:own');
|
||||||
} else {
|
} else {
|
||||||
$this->checkPermission($organization, 'time-entries:view:all');
|
$this->checkPermission($organization, 'time-entries:view:all');
|
||||||
}
|
}
|
||||||
|
|
||||||
$canAccessPremiumFeatures = $this->canAccessPremiumFeatures($organization);
|
$canAccessPremiumFeatures = $this->canAccessPremiumFeatures($organization);
|
||||||
$timeEntriesQuery = $this->getTimeEntriesQuery($organization, $request, $member, $canAccessPremiumFeatures);
|
$timeEntriesQuery = $this->getTimeEntriesQuery($organization, $request, $memberFilter, $canAccessPremiumFeatures);
|
||||||
|
|
||||||
$totalCount = $timeEntriesQuery->count();
|
$totalCount = $timeEntriesQuery->count();
|
||||||
|
|
||||||
@@ -158,7 +159,7 @@ class TimeEntryController extends Controller
|
|||||||
if ($timeEntries->count() === 0) {
|
if ($timeEntries->count() === 0) {
|
||||||
Log::warning('User has has more than '.$limit.' time entries on one date', [
|
Log::warning('User has has more than '.$limit.' time entries on one date', [
|
||||||
'date' => $lastDate->toDateString(),
|
'date' => $lastDate->toDateString(),
|
||||||
'user_id' => $request->input('user_id'),
|
'member_id' => $request->input('member_id'),
|
||||||
'auth_user_id' => Auth::id(),
|
'auth_user_id' => Auth::id(),
|
||||||
'limit' => $limit,
|
'limit' => $limit,
|
||||||
]);
|
]);
|
||||||
@@ -221,9 +222,10 @@ class TimeEntryController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function indexExport(Organization $organization, TimeEntryIndexExportRequest $request, TimeEntryAggregationService $timeEntryAggregationService): JsonResponse
|
public function indexExport(Organization $organization, TimeEntryIndexExportRequest $request, TimeEntryAggregationService $timeEntryAggregationService): JsonResponse
|
||||||
{
|
{
|
||||||
/** @var Member|null $member */
|
$member = $this->member($organization);
|
||||||
$member = $request->has('member_id') ? Member::query()->findOrFail($request->input('member_id')) : null;
|
/** @var Member|null $memberFilter */
|
||||||
if ($member !== null && $member->user_id === Auth::id()) {
|
$memberFilter = $request->has('member_id') ? Member::query()->findOrFail($request->input('member_id')) : null;
|
||||||
|
if ($memberFilter !== null && $memberFilter->getKey() === $member->getKey()) {
|
||||||
$this->checkPermission($organization, 'time-entries:view:own');
|
$this->checkPermission($organization, 'time-entries:view:own');
|
||||||
} else {
|
} else {
|
||||||
$this->checkPermission($organization, 'time-entries:view:all');
|
$this->checkPermission($organization, 'time-entries:view:all');
|
||||||
@@ -240,7 +242,7 @@ class TimeEntryController extends Controller
|
|||||||
$roundingType = $canAccessPremiumFeatures ? $request->getRoundingType() : null;
|
$roundingType = $canAccessPremiumFeatures ? $request->getRoundingType() : null;
|
||||||
$roundingMinutes = $canAccessPremiumFeatures ? $request->getRoundingMinutes() : null;
|
$roundingMinutes = $canAccessPremiumFeatures ? $request->getRoundingMinutes() : null;
|
||||||
|
|
||||||
$timeEntriesQuery = $this->getTimeEntriesQuery($organization, $request, $member, $canAccessPremiumFeatures);
|
$timeEntriesQuery = $this->getTimeEntriesQuery($organization, $request, $memberFilter, $canAccessPremiumFeatures);
|
||||||
$timeEntriesQuery->with([
|
$timeEntriesQuery->with([
|
||||||
'task',
|
'task',
|
||||||
'client',
|
'client',
|
||||||
@@ -263,7 +265,7 @@ class TimeEntryController extends Controller
|
|||||||
if ($viewFile === false) {
|
if ($viewFile === false) {
|
||||||
throw new \LogicException('View file not found');
|
throw new \LogicException('View file not found');
|
||||||
}
|
}
|
||||||
$timeEntriesAggregateQuery = $this->getTimeEntriesAggregateQuery($organization, $request, $member);
|
$timeEntriesAggregateQuery = $this->getTimeEntriesAggregateQuery($organization, $request, $memberFilter);
|
||||||
$aggregatedData = $timeEntryAggregationService->getAggregatedTimeEntries(
|
$aggregatedData = $timeEntryAggregationService->getAggregatedTimeEntries(
|
||||||
$timeEntriesAggregateQuery,
|
$timeEntriesAggregateQuery,
|
||||||
null,
|
null,
|
||||||
@@ -370,9 +372,10 @@ class TimeEntryController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function aggregate(Organization $organization, TimeEntryAggregateRequest $request, TimeEntryAggregationService $timeEntryAggregationService): array
|
public function aggregate(Organization $organization, TimeEntryAggregateRequest $request, TimeEntryAggregationService $timeEntryAggregationService): array
|
||||||
{
|
{
|
||||||
/** @var Member|null $member */
|
$member = $this->member($organization);
|
||||||
$member = $request->has('member_id') ? Member::query()->findOrFail($request->input('member_id')) : null;
|
/** @var Member|null $memberFilter */
|
||||||
if ($member !== null && $member->user_id === Auth::id()) {
|
$memberFilter = $request->has('member_id') ? Member::query()->findOrFail($request->input('member_id')) : null;
|
||||||
|
if ($memberFilter !== null && $memberFilter->getKey() === $member->getKey()) {
|
||||||
$this->checkPermission($organization, 'time-entries:view:own');
|
$this->checkPermission($organization, 'time-entries:view:own');
|
||||||
} else {
|
} else {
|
||||||
$this->checkPermission($organization, 'time-entries:view:all');
|
$this->checkPermission($organization, 'time-entries:view:all');
|
||||||
@@ -383,7 +386,7 @@ class TimeEntryController extends Controller
|
|||||||
|
|
||||||
$group1Type = $request->getGroup();
|
$group1Type = $request->getGroup();
|
||||||
$group2Type = $request->getSubGroup();
|
$group2Type = $request->getSubGroup();
|
||||||
$timeEntriesAggregateQuery = $this->getTimeEntriesAggregateQuery($organization, $request, $member);
|
$timeEntriesAggregateQuery = $this->getTimeEntriesAggregateQuery($organization, $request, $memberFilter);
|
||||||
$roundingType = $canAccessPremiumFeatures ? $request->getRoundingType() : null;
|
$roundingType = $canAccessPremiumFeatures ? $request->getRoundingType() : null;
|
||||||
$roundingMinutes = $canAccessPremiumFeatures ? $request->getRoundingMinutes() : null;
|
$roundingMinutes = $canAccessPremiumFeatures ? $request->getRoundingMinutes() : null;
|
||||||
|
|
||||||
@@ -419,9 +422,10 @@ class TimeEntryController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function aggregateExport(Organization $organization, TimeEntryAggregateExportRequest $request, TimeEntryAggregationService $timeEntryAggregationService): JsonResponse
|
public function aggregateExport(Organization $organization, TimeEntryAggregateExportRequest $request, TimeEntryAggregationService $timeEntryAggregationService): JsonResponse
|
||||||
{
|
{
|
||||||
/** @var Member|null $member */
|
$member = $this->member($organization);
|
||||||
$member = $request->has('member_id') ? Member::query()->findOrFail($request->input('member_id')) : null;
|
/** @var Member|null $memberFilter */
|
||||||
if ($member !== null && $member->user_id === Auth::id()) {
|
$memberFilter = $request->has('member_id') ? Member::query()->findOrFail($request->input('member_id')) : null;
|
||||||
|
if ($memberFilter !== null && $memberFilter->getKey() === $member->getKey()) {
|
||||||
$this->checkPermission($organization, 'time-entries:view:own');
|
$this->checkPermission($organization, 'time-entries:view:own');
|
||||||
} else {
|
} else {
|
||||||
$this->checkPermission($organization, 'time-entries:view:all');
|
$this->checkPermission($organization, 'time-entries:view:all');
|
||||||
@@ -437,7 +441,7 @@ class TimeEntryController extends Controller
|
|||||||
|
|
||||||
$group = $request->getGroup();
|
$group = $request->getGroup();
|
||||||
$subGroup = $request->getSubGroup();
|
$subGroup = $request->getSubGroup();
|
||||||
$timeEntriesAggregateQuery = $this->getTimeEntriesAggregateQuery($organization, $request, $member);
|
$timeEntriesAggregateQuery = $this->getTimeEntriesAggregateQuery($organization, $request, $memberFilter);
|
||||||
$roundingType = $canAccessPremiumFeatures ? $request->getRoundingType() : null;
|
$roundingType = $canAccessPremiumFeatures ? $request->getRoundingType() : null;
|
||||||
$roundingMinutes = $canAccessPremiumFeatures ? $request->getRoundingMinutes() : null;
|
$roundingMinutes = $canAccessPremiumFeatures ? $request->getRoundingMinutes() : null;
|
||||||
|
|
||||||
@@ -580,7 +584,7 @@ class TimeEntryController extends Controller
|
|||||||
{
|
{
|
||||||
/** @var Member $member */
|
/** @var Member $member */
|
||||||
$member = Member::query()->findOrFail($request->input('member_id'));
|
$member = Member::query()->findOrFail($request->input('member_id'));
|
||||||
if ($member->user_id === Auth::id()) {
|
if ($member->getKey() === $this->member($organization)->getKey()) {
|
||||||
$this->checkPermission($organization, 'time-entries:create:own');
|
$this->checkPermission($organization, 'time-entries:create:own');
|
||||||
} else {
|
} else {
|
||||||
$this->checkPermission($organization, 'time-entries:create:all');
|
$this->checkPermission($organization, 'time-entries:create:all');
|
||||||
@@ -627,9 +631,10 @@ class TimeEntryController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function update(Organization $organization, TimeEntry $timeEntry, TimeEntryUpdateRequest $request): JsonResource
|
public function update(Organization $organization, TimeEntry $timeEntry, TimeEntryUpdateRequest $request): JsonResource
|
||||||
{
|
{
|
||||||
/** @var Member|null $member */
|
$member = $this->member($organization);
|
||||||
$member = $request->has('member_id') ? Member::query()->findOrFail($request->input('member_id')) : null;
|
/** @var Member|null $newMember */
|
||||||
if ($timeEntry->member->user_id === Auth::id() && ($member === null || $member->user_id === Auth::id())) {
|
$newMember = $request->has('member_id') ? Member::query()->findOrFail($request->input('member_id')) : null;
|
||||||
|
if ($timeEntry->member_id === $member->getKey() && ($newMember === null || $newMember->getKey() === $member->getKey())) {
|
||||||
$this->checkPermission($organization, 'time-entries:update:own', $timeEntry);
|
$this->checkPermission($organization, 'time-entries:update:own', $timeEntry);
|
||||||
} else {
|
} else {
|
||||||
$this->checkPermission($organization, 'time-entries:update:all', $timeEntry);
|
$this->checkPermission($organization, 'time-entries:update:all', $timeEntry);
|
||||||
@@ -661,6 +666,10 @@ class TimeEntryController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
$timeEntry->fill($request->validated());
|
$timeEntry->fill($request->validated());
|
||||||
|
if ($newMember !== null) {
|
||||||
|
$timeEntry->member()->associate($newMember);
|
||||||
|
$timeEntry->user()->associate($newMember->user);
|
||||||
|
}
|
||||||
$timeEntry->description = $request->input('description', $timeEntry->description) ?? '';
|
$timeEntry->description = $request->input('description', $timeEntry->description) ?? '';
|
||||||
$timeEntry->setComputedAttributeValue('billable_rate');
|
$timeEntry->setComputedAttributeValue('billable_rate');
|
||||||
$timeEntry->save();
|
$timeEntry->save();
|
||||||
@@ -690,6 +699,7 @@ class TimeEntryController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function updateMultiple(Organization $organization, TimeEntryUpdateMultipleRequest $request): JsonResponse
|
public function updateMultiple(Organization $organization, TimeEntryUpdateMultipleRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
|
$member = $this->member($organization);
|
||||||
$this->checkAnyPermission($organization, ['time-entries:update:all', 'time-entries:update:own']);
|
$this->checkAnyPermission($organization, ['time-entries:update:all', 'time-entries:update:own']);
|
||||||
$canAccessAll = $this->hasPermission($organization, 'time-entries:update:all');
|
$canAccessAll = $this->hasPermission($organization, 'time-entries:update:all');
|
||||||
|
|
||||||
@@ -714,6 +724,9 @@ class TimeEntryController extends Controller
|
|||||||
throw new AuthorizationException;
|
throw new AuthorizationException;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @var Member|null $newMember */
|
||||||
|
$newMember = isset($changes['member_id']) ? Member::query()->findOrFail($changes['member_id']) : null;
|
||||||
|
|
||||||
$project = null;
|
$project = null;
|
||||||
$client = null;
|
$client = null;
|
||||||
$overwriteClient = false;
|
$overwriteClient = false;
|
||||||
@@ -740,7 +753,7 @@ class TimeEntryController extends Controller
|
|||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (! $canAccessAll && $timeEntry->user_id !== Auth::id()) {
|
if (! $canAccessAll && $timeEntry->member_id !== $member->getKey()) {
|
||||||
$error->push($id);
|
$error->push($id);
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
@@ -750,6 +763,10 @@ class TimeEntryController extends Controller
|
|||||||
$oldTask = $timeEntry->task;
|
$oldTask = $timeEntry->task;
|
||||||
|
|
||||||
$timeEntry->fill($changes);
|
$timeEntry->fill($changes);
|
||||||
|
if ($newMember !== null) {
|
||||||
|
$timeEntry->member()->associate($newMember);
|
||||||
|
$timeEntry->user_id = $newMember->user_id;
|
||||||
|
}
|
||||||
// If project is changed, but task is not, we remove the old task from the time entry
|
// If project is changed, but task is not, we remove the old task from the time entry
|
||||||
if ($oldProject !== null && $project !== null && $oldProject->isNot($project) && $task === null) {
|
if ($oldProject !== null && $project !== null && $oldProject->isNot($project) && $task === null) {
|
||||||
$timeEntry->task()->disassociate();
|
$timeEntry->task()->disassociate();
|
||||||
@@ -790,7 +807,8 @@ class TimeEntryController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function destroy(Organization $organization, TimeEntry $timeEntry): JsonResponse
|
public function destroy(Organization $organization, TimeEntry $timeEntry): JsonResponse
|
||||||
{
|
{
|
||||||
if ($timeEntry->member->user_id === Auth::id()) {
|
$member = $this->member($organization);
|
||||||
|
if ($timeEntry->member_id === $member->getKey()) {
|
||||||
$this->checkPermission($organization, 'time-entries:delete:own', $timeEntry);
|
$this->checkPermission($organization, 'time-entries:delete:own', $timeEntry);
|
||||||
} else {
|
} else {
|
||||||
$this->checkPermission($organization, 'time-entries:delete:all', $timeEntry);
|
$this->checkPermission($organization, 'time-entries:delete:all', $timeEntry);
|
||||||
@@ -847,7 +865,7 @@ class TimeEntryController extends Controller
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! $canDeleteAll && $timeEntry->user_id !== Auth::id()) {
|
if (! $canDeleteAll && $timeEntry->member_id !== $this->member($organization)->getKey()) {
|
||||||
$error->push($id);
|
$error->push($id);
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -189,7 +189,9 @@ ENV WITH_HORIZON=false \
|
|||||||
WITH_SCHEDULER=false \
|
WITH_SCHEDULER=false \
|
||||||
WITH_REVERB=false
|
WITH_REVERB=false
|
||||||
|
|
||||||
COPY --link --chown=${WWWUSER}:${WWWUSER} . .
|
COPY --link --chown=${WWWUSER}:${WWWUSER} . ./
|
||||||
|
|
||||||
|
RUN test -z "$(find . -name .git -print -quit)"
|
||||||
#COPY --link --chown=${WWWUSER}:${WWWUSER} --from=build ${ROOT}/public public
|
#COPY --link --chown=${WWWUSER}:${WWWUSER} --from=build ${ROOT}/public public
|
||||||
|
|
||||||
RUN mkdir -p \
|
RUN mkdir -p \
|
||||||
|
|||||||
14
extensions/manifest.json
Normal file
14
extensions/manifest.json
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"Billing": {
|
||||||
|
"repository": "solidtime-io/extension-billing",
|
||||||
|
"ref": "v0.0.3"
|
||||||
|
},
|
||||||
|
"Services": {
|
||||||
|
"repository": "solidtime-io/extension-services",
|
||||||
|
"ref": "v0.0.1"
|
||||||
|
},
|
||||||
|
"Invoicing": {
|
||||||
|
"repository": "solidtime-io/extension-invoicing",
|
||||||
|
"ref": "v0.0.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
376
package-lock.json
generated
376
package-lock.json
generated
@@ -13,7 +13,7 @@
|
|||||||
"@floating-ui/core": "^1.8.0",
|
"@floating-ui/core": "^1.8.0",
|
||||||
"@floating-ui/vue": "^1.1.11",
|
"@floating-ui/vue": "^1.1.11",
|
||||||
"@heroicons/vue": "^2.2.0",
|
"@heroicons/vue": "^2.2.0",
|
||||||
"@lucide/vue": "^1.24.0",
|
"@lucide/vue": "^1.25.0",
|
||||||
"@rushstack/eslint-patch": "^1.16.1",
|
"@rushstack/eslint-patch": "^1.16.1",
|
||||||
"@tailwindcss/container-queries": "^0.1.1",
|
"@tailwindcss/container-queries": "^0.1.1",
|
||||||
"@tanstack/vue-form": "^1.33.2",
|
"@tanstack/vue-form": "^1.33.2",
|
||||||
@@ -51,16 +51,16 @@
|
|||||||
"@tailwindcss/typography": "^0.5.20",
|
"@tailwindcss/typography": "^0.5.20",
|
||||||
"@types/chroma-js": "^3.1.2",
|
"@types/chroma-js": "^3.1.2",
|
||||||
"@types/node": "^22.19.19",
|
"@types/node": "^22.19.19",
|
||||||
"@vitejs/plugin-vue": "^6.0.7",
|
"@vitejs/plugin-vue": "^6.0.8",
|
||||||
"@vue/test-utils": "^2.4.11",
|
"@vue/test-utils": "^2.4.11",
|
||||||
"@vue/tsconfig": "^0.9.1",
|
"@vue/tsconfig": "^0.9.1",
|
||||||
"autoprefixer": "^10.5.2",
|
"autoprefixer": "^10.5.4",
|
||||||
"axios": "^1.18.1",
|
"axios": "^1.18.1",
|
||||||
"eslint-plugin-unused-imports": "^4.4.1",
|
"eslint-plugin-unused-imports": "^4.4.1",
|
||||||
"happy-dom": "^20.10.6",
|
"happy-dom": "^20.11.0",
|
||||||
"laravel-vite-plugin": "^2.1.0",
|
"laravel-vite-plugin": "^2.1.0",
|
||||||
"openapi-zod-client": "^1.18.3",
|
"openapi-zod-client": "^1.18.3",
|
||||||
"postcss": "^8.5.18",
|
"postcss": "^8.5.20",
|
||||||
"postcss-import": "^15.1.0",
|
"postcss-import": "^15.1.0",
|
||||||
"postcss-nesting": "^12.1.5",
|
"postcss-nesting": "^12.1.5",
|
||||||
"tailwindcss": "^3.4.19",
|
"tailwindcss": "^3.4.19",
|
||||||
@@ -68,7 +68,7 @@
|
|||||||
"vite": "^7.3.3",
|
"vite": "^7.3.3",
|
||||||
"vite-plugin-checker": "^0.14.4",
|
"vite-plugin-checker": "^0.14.4",
|
||||||
"vitest": "^4.1.10",
|
"vitest": "^4.1.10",
|
||||||
"vue": "^3.5.39",
|
"vue": "^3.5.40",
|
||||||
"vue-tsc": "^3.3.7"
|
"vue-tsc": "^3.3.7"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -1244,9 +1244,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@lucide/vue": {
|
"node_modules/@lucide/vue": {
|
||||||
"version": "1.24.0",
|
"version": "1.25.0",
|
||||||
"resolved": "https://registry.npmjs.org/@lucide/vue/-/vue-1.24.0.tgz",
|
"resolved": "https://registry.npmjs.org/@lucide/vue/-/vue-1.25.0.tgz",
|
||||||
"integrity": "sha512-5bNPX0G2YEWdUlBYk7pE8SgDg/f1mkIFpJ9vtE44pW/cwRz7Ioc0tOTESoVJAPvxIELSmYekX+XXIJMjsswNIg==",
|
"integrity": "sha512-hkEetV+v48ScIn3uwqwWQ66sI8foeP2q6OMI09GzLFH4SfvBlfe3JHYlMBdBCqFC7WRlhFsndyDn/awRKRc2OQ==",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"vue": ">=3.0.1"
|
"vue": ">=3.0.1"
|
||||||
@@ -2513,16 +2513,16 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/eslint-plugin": {
|
"node_modules/@typescript-eslint/eslint-plugin": {
|
||||||
"version": "8.63.0",
|
"version": "8.64.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.63.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.64.0.tgz",
|
||||||
"integrity": "sha512-rvwSgqT+DHpWdzfSzPatRLm02a0GlESt++9iy3hLCDY4BgkaLcl8LBi9Yh7XGFBpwcBE/K3024QuXWTpbz4FfQ==",
|
"integrity": "sha512-CGvQPBxN3wZLu6Rz2kFUpZeoCm78xUic92ck39KPePkO1NPOwjCqdQnm5Q87tpWw9vcBvW8XLrDXjH9PWYtJ3Q==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint-community/regexpp": "^4.12.2",
|
"@eslint-community/regexpp": "^4.12.2",
|
||||||
"@typescript-eslint/scope-manager": "8.63.0",
|
"@typescript-eslint/scope-manager": "8.64.0",
|
||||||
"@typescript-eslint/type-utils": "8.63.0",
|
"@typescript-eslint/type-utils": "8.64.0",
|
||||||
"@typescript-eslint/utils": "8.63.0",
|
"@typescript-eslint/utils": "8.64.0",
|
||||||
"@typescript-eslint/visitor-keys": "8.63.0",
|
"@typescript-eslint/visitor-keys": "8.64.0",
|
||||||
"ignore": "^7.0.5",
|
"ignore": "^7.0.5",
|
||||||
"natural-compare": "^1.4.0",
|
"natural-compare": "^1.4.0",
|
||||||
"ts-api-utils": "^2.5.0"
|
"ts-api-utils": "^2.5.0"
|
||||||
@@ -2535,7 +2535,7 @@
|
|||||||
"url": "https://opencollective.com/typescript-eslint"
|
"url": "https://opencollective.com/typescript-eslint"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@typescript-eslint/parser": "^8.63.0",
|
"@typescript-eslint/parser": "^8.64.0",
|
||||||
"eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
|
"eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
|
||||||
"typescript": ">=4.8.4 <6.1.0"
|
"typescript": ">=4.8.4 <6.1.0"
|
||||||
}
|
}
|
||||||
@@ -2550,15 +2550,15 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/parser": {
|
"node_modules/@typescript-eslint/parser": {
|
||||||
"version": "8.63.0",
|
"version": "8.64.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.63.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.64.0.tgz",
|
||||||
"integrity": "sha512-gwh4gvvlaVDKKxyfxMG+Gnu1u9X0OQBwyGLkbwB65dIzBKnxeRiJlNFqlI3zwVhNXJIs6qV7mlFCn/BIajlVig==",
|
"integrity": "sha512-KA0OshtlcCCXmbfqyZkM5pV3/WNraJf7DkJRLpyrmwPtud57H5BDX7C3k0LPSPxpprfRL+cJDGabF10mvNCoCw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/scope-manager": "8.63.0",
|
"@typescript-eslint/scope-manager": "8.64.0",
|
||||||
"@typescript-eslint/types": "8.63.0",
|
"@typescript-eslint/types": "8.64.0",
|
||||||
"@typescript-eslint/typescript-estree": "8.63.0",
|
"@typescript-eslint/typescript-estree": "8.64.0",
|
||||||
"@typescript-eslint/visitor-keys": "8.63.0",
|
"@typescript-eslint/visitor-keys": "8.64.0",
|
||||||
"debug": "^4.4.3"
|
"debug": "^4.4.3"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -2574,13 +2574,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/project-service": {
|
"node_modules/@typescript-eslint/project-service": {
|
||||||
"version": "8.63.0",
|
"version": "8.64.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.63.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.64.0.tgz",
|
||||||
"integrity": "sha512-e5dh0/UI0ok53AlZ5wRkXCB32z/f2jUZqPR/ygAw5WYaSw8j9EoJWlS7wQjr/dmOaqWjnPIn2m+HhVPCMWGZVQ==",
|
"integrity": "sha512-tk4WpOJ6IEbGrVHaNmM0YRrwAD3exZlIK3iadQNAxh4YKk6jvUQ4ecq18n+v7+meh+cJ3j+D8nbk8sRKhlwLQg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/tsconfig-utils": "^8.63.0",
|
"@typescript-eslint/tsconfig-utils": "^8.64.0",
|
||||||
"@typescript-eslint/types": "^8.63.0",
|
"@typescript-eslint/types": "^8.64.0",
|
||||||
"debug": "^4.4.3"
|
"debug": "^4.4.3"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -2595,13 +2595,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/scope-manager": {
|
"node_modules/@typescript-eslint/scope-manager": {
|
||||||
"version": "8.63.0",
|
"version": "8.64.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.63.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.64.0.tgz",
|
||||||
"integrity": "sha512-uUyfMWCnDSN8bCpcrY8nGP2BLkQ9Xn0GsipcONcpIDWhwhO4ZSyHvyS14U3X75mzxWxL3I2UZIrenTzdzcJO8A==",
|
"integrity": "sha512-CXEaFdYXjSTgKhisNkwCcJwTP8Pl+fmRrEQrri4nm3vU743bALrxzLmq7fHG/7e6a5xO0lDYeURpZmBuhHk54w==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/types": "8.63.0",
|
"@typescript-eslint/types": "8.64.0",
|
||||||
"@typescript-eslint/visitor-keys": "8.63.0"
|
"@typescript-eslint/visitor-keys": "8.64.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
@@ -2612,9 +2612,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/tsconfig-utils": {
|
"node_modules/@typescript-eslint/tsconfig-utils": {
|
||||||
"version": "8.63.0",
|
"version": "8.64.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.63.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.64.0.tgz",
|
||||||
"integrity": "sha512-sUAbkulqBAsncKnbRP3+7CtQFRKicexnj7ZwNC6ddCR7EmrXvjvdCYMJbUIqMd6lwoEriZjwLo08aS5tSjVMHg==",
|
"integrity": "sha512-2yo8rRNKuzbVWQp5kslhANqZ2uDAeROQHBRZNPu8JDsHmeFNj/XJJhX/FhNUWmkHHvoNsKa6+tHJiig87EzsQw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
@@ -2628,14 +2628,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/type-utils": {
|
"node_modules/@typescript-eslint/type-utils": {
|
||||||
"version": "8.63.0",
|
"version": "8.64.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.63.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.64.0.tgz",
|
||||||
"integrity": "sha512-Nzzh/OGxVCOjObjaj1CQF2RUasyYy2Jfuh+zZ3PjLzG2fYRriAiZLib9UKtO+CpQAS3YHiAS+ckZDclwqI1TPA==",
|
"integrity": "sha512-XWG4Fmmv/6SvyS9nH8jWrKs6terwJvE8cyRt1CzYYqzp9OrPhCT4cMc/f7C6RZCwG+qMmiffJS1/qJP8G1URtg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/types": "8.63.0",
|
"@typescript-eslint/types": "8.64.0",
|
||||||
"@typescript-eslint/typescript-estree": "8.63.0",
|
"@typescript-eslint/typescript-estree": "8.64.0",
|
||||||
"@typescript-eslint/utils": "8.63.0",
|
"@typescript-eslint/utils": "8.64.0",
|
||||||
"debug": "^4.4.3",
|
"debug": "^4.4.3",
|
||||||
"ts-api-utils": "^2.5.0"
|
"ts-api-utils": "^2.5.0"
|
||||||
},
|
},
|
||||||
@@ -2652,9 +2652,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/types": {
|
"node_modules/@typescript-eslint/types": {
|
||||||
"version": "8.63.0",
|
"version": "8.64.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.63.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.64.0.tgz",
|
||||||
"integrity": "sha512-xyLtl9DUBBFrcJS4x2pIqGLH68/tC2uOa4Z7pUteW09D3bXnnXUom4dyPikzWgB7llmIc1zoeI3aoUdC4rPK/Q==",
|
"integrity": "sha512-qjhfuTfLXjA4IOzXvz0rTjT01BqEiIgPoUeMwiEjnaHKJMTNo8rH5pYW1a2L/0Dnux2fPC85AeyJoWaGa8WxTA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
@@ -2665,15 +2665,15 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/typescript-estree": {
|
"node_modules/@typescript-eslint/typescript-estree": {
|
||||||
"version": "8.63.0",
|
"version": "8.64.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.63.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.64.0.tgz",
|
||||||
"integrity": "sha512-ygBkU+B7ex5UI/gKhaqexWev79uISfIv7XQCRNYO/jmD8rGLPyWLAb3KMRT6nd8Gt9bmUBi9+iX6tBdYfOY81Q==",
|
"integrity": "sha512-Pztpsn1aCE1oWDvDEfUk31nngvvF7vUB5SwHFEaZIFpvw7WJtqUHHL4plBZDA9HfWJJjL13BdG0YrJInTUvoVA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/project-service": "8.63.0",
|
"@typescript-eslint/project-service": "8.64.0",
|
||||||
"@typescript-eslint/tsconfig-utils": "8.63.0",
|
"@typescript-eslint/tsconfig-utils": "8.64.0",
|
||||||
"@typescript-eslint/types": "8.63.0",
|
"@typescript-eslint/types": "8.64.0",
|
||||||
"@typescript-eslint/visitor-keys": "8.63.0",
|
"@typescript-eslint/visitor-keys": "8.64.0",
|
||||||
"debug": "^4.4.3",
|
"debug": "^4.4.3",
|
||||||
"minimatch": "^10.2.2",
|
"minimatch": "^10.2.2",
|
||||||
"semver": "^7.7.3",
|
"semver": "^7.7.3",
|
||||||
@@ -2728,15 +2728,15 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/utils": {
|
"node_modules/@typescript-eslint/utils": {
|
||||||
"version": "8.63.0",
|
"version": "8.64.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.63.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.64.0.tgz",
|
||||||
"integrity": "sha512-fUKaeAvrTuQg/Tgt3nliAUSZHJM6DlCcfyEmxCvlX8kieWSStBX+5O5Fnidtc3i2JrH+9c/GL4RY2iasd/GPTA==",
|
"integrity": "sha512-aJUGVB3+U0htrrCjoA8qukw8cm8fNCGAxK/tVoS70k8aeb7DETKeFozRiVFIwEeN9WJLsjaP3ph8I60tY2XZoQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint-community/eslint-utils": "^4.9.1",
|
"@eslint-community/eslint-utils": "^4.9.1",
|
||||||
"@typescript-eslint/scope-manager": "8.63.0",
|
"@typescript-eslint/scope-manager": "8.64.0",
|
||||||
"@typescript-eslint/types": "8.63.0",
|
"@typescript-eslint/types": "8.64.0",
|
||||||
"@typescript-eslint/typescript-estree": "8.63.0"
|
"@typescript-eslint/typescript-estree": "8.64.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
@@ -2751,12 +2751,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/visitor-keys": {
|
"node_modules/@typescript-eslint/visitor-keys": {
|
||||||
"version": "8.63.0",
|
"version": "8.64.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.63.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.64.0.tgz",
|
||||||
"integrity": "sha512-UexrHGnGTpbuQHct2ExOc2ZcFbGUS9FOesCxxqdBGcpI1BxYu/LZ6U8Aq6/72XtF/qRBk9nhuGHFJIXXMhPMdw==",
|
"integrity": "sha512-mrtuL8Nsn6gi2H4mo5KMTp823M+3Q19Ew/i+Zlikq20tIMm99C3Ez0dCmkWWnxut20esQvTg8aUSEhMcAOXhEw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/types": "8.63.0",
|
"@typescript-eslint/types": "8.64.0",
|
||||||
"eslint-visitor-keys": "^5.0.0"
|
"eslint-visitor-keys": "^5.0.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -2780,9 +2780,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vitejs/plugin-vue": {
|
"node_modules/@vitejs/plugin-vue": {
|
||||||
"version": "6.0.7",
|
"version": "6.0.8",
|
||||||
"resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-6.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-6.0.8.tgz",
|
||||||
"integrity": "sha512-km+p+XdSz9Sxm5rqUbqcSfZYaAniKxWBj1KURl+Jr7UaPvvX7BmaWMdP69I5rrFDeQGyxAG7NXdc57vz+snhWg==",
|
"integrity": "sha512-0ZjgOg7oO6farnNGup7yvoM/YXZV84OZxHAwtflItNa/6zzQyVb5LNxyea3FEKEX2XlagIKzrlH7wwxkKgtiew==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@rolldown/pluginutils": "^1.0.1"
|
"@rolldown/pluginutils": "^1.0.1"
|
||||||
@@ -2968,19 +2968,19 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/compiler-sfc": {
|
"node_modules/@vue/compiler-sfc": {
|
||||||
"version": "3.5.39",
|
"version": "3.5.40",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.39.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.40.tgz",
|
||||||
"integrity": "sha512-d0ki86iOyN8LoZPBmk5SJWNwHP19CnDDCfuo//+2WJa2g5Ke0Jay983PIBIcSSzldC68I8DrD5GrHV3OSDfodg==",
|
"integrity": "sha512-gIf497P4kpuALcvs5n3AEg1Vdn0pSY4XbjASIfHNYF1/MP3T2Mf2STERTubysBxCRxzJGJYtF/O7vwJrxFB3Vw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/parser": "^7.29.7",
|
"@babel/parser": "^7.29.7",
|
||||||
"@vue/compiler-core": "3.5.39",
|
"@vue/compiler-core": "3.5.40",
|
||||||
"@vue/compiler-dom": "3.5.39",
|
"@vue/compiler-dom": "3.5.40",
|
||||||
"@vue/compiler-ssr": "3.5.39",
|
"@vue/compiler-ssr": "3.5.40",
|
||||||
"@vue/shared": "3.5.39",
|
"@vue/shared": "3.5.40",
|
||||||
"estree-walker": "^2.0.2",
|
"estree-walker": "^2.0.2",
|
||||||
"magic-string": "^0.30.21",
|
"magic-string": "^0.30.21",
|
||||||
"postcss": "^8.5.15",
|
"postcss": "^8.5.19",
|
||||||
"source-map-js": "^1.2.1"
|
"source-map-js": "^1.2.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -3013,42 +3013,42 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/compiler-sfc/node_modules/@vue/compiler-core": {
|
"node_modules/@vue/compiler-sfc/node_modules/@vue/compiler-core": {
|
||||||
"version": "3.5.39",
|
"version": "3.5.40",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.39.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.40.tgz",
|
||||||
"integrity": "sha512-16KBTEXAJCpDr0mwlw+AZyhu8iyC7R3S2vBwsI7QnWJU6X3WKc9VKeNEZpiMdZ569qWhz9574L3vV55qRL0Vtw==",
|
"integrity": "sha512-39E8IgOhTbVDnoJFMKc2DvYnypcZwUqgUhQkccva/0m6FUwtIKSGV7n1hpVmYcFaoRAwf9pBcwnKlCEsN63ZEQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/parser": "^7.29.7",
|
"@babel/parser": "^7.29.7",
|
||||||
"@vue/shared": "3.5.39",
|
"@vue/shared": "3.5.40",
|
||||||
"entities": "^7.0.1",
|
"entities": "^7.0.1",
|
||||||
"estree-walker": "^2.0.2",
|
"estree-walker": "^2.0.2",
|
||||||
"source-map-js": "^1.2.1"
|
"source-map-js": "^1.2.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/compiler-sfc/node_modules/@vue/compiler-dom": {
|
"node_modules/@vue/compiler-sfc/node_modules/@vue/compiler-dom": {
|
||||||
"version": "3.5.39",
|
"version": "3.5.40",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.39.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.40.tgz",
|
||||||
"integrity": "sha512-oQPigALqYbNxTNPvNgSOe+czwVExfbVF02lz8jP0S3AXJiu3jxYDygNUiqSep4ezzW8XgnubqH63My2A7JR/vg==",
|
"integrity": "sha512-pwkx4vqlqOspFstrcmzwkKLePVMD3PT65imRzLhanU2V1Fj4K13g6OXjanOyzw3aTAuRk84BOmY8f3rEHqPaVA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/compiler-core": "3.5.39",
|
"@vue/compiler-core": "3.5.40",
|
||||||
"@vue/shared": "3.5.39"
|
"@vue/shared": "3.5.40"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/compiler-sfc/node_modules/@vue/shared": {
|
"node_modules/@vue/compiler-sfc/node_modules/@vue/shared": {
|
||||||
"version": "3.5.39",
|
"version": "3.5.40",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.39.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.40.tgz",
|
||||||
"integrity": "sha512-l1rrBtBfTnmxvtsvdQDXltUUy8S1Y+ZaqdfUzmAnJkTd8Z8rv5v/ytW+TKiqEOWyHPoqtPlNFSs0lhRmYVSHVA==",
|
"integrity": "sha512-WxnBtruIqOoV3rA4jeKDWzrYI5h7Cp4+pjwDi8kWGHz+IslhiN+wguLVVhtv2l8VoU02rzDCVfDjgCl1lNpZVg==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@vue/compiler-ssr": {
|
"node_modules/@vue/compiler-ssr": {
|
||||||
"version": "3.5.39",
|
"version": "3.5.40",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.39.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.40.tgz",
|
||||||
"integrity": "sha512-Ce7/wvwMHai74bdszfXExdazFigYnlF9zgCmEQUcM1j0fOymlouZ7XilTYNo8oUjhlnjYOZbGrcYKuqjz89Ucw==",
|
"integrity": "sha512-rrE5xiXG663+vHCHa3J9p2z5OcBRjXmoqenprJxAFQxg5pSshzeBiCE6pu46axapRJ2Adk0YDA2BRZVjiHXnhg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/compiler-dom": "3.5.39",
|
"@vue/compiler-dom": "3.5.40",
|
||||||
"@vue/shared": "3.5.39"
|
"@vue/shared": "3.5.40"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/compiler-ssr/node_modules/@babel/parser": {
|
"node_modules/@vue/compiler-ssr/node_modules/@babel/parser": {
|
||||||
@@ -3080,32 +3080,32 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/compiler-ssr/node_modules/@vue/compiler-core": {
|
"node_modules/@vue/compiler-ssr/node_modules/@vue/compiler-core": {
|
||||||
"version": "3.5.39",
|
"version": "3.5.40",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.39.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.40.tgz",
|
||||||
"integrity": "sha512-16KBTEXAJCpDr0mwlw+AZyhu8iyC7R3S2vBwsI7QnWJU6X3WKc9VKeNEZpiMdZ569qWhz9574L3vV55qRL0Vtw==",
|
"integrity": "sha512-39E8IgOhTbVDnoJFMKc2DvYnypcZwUqgUhQkccva/0m6FUwtIKSGV7n1hpVmYcFaoRAwf9pBcwnKlCEsN63ZEQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/parser": "^7.29.7",
|
"@babel/parser": "^7.29.7",
|
||||||
"@vue/shared": "3.5.39",
|
"@vue/shared": "3.5.40",
|
||||||
"entities": "^7.0.1",
|
"entities": "^7.0.1",
|
||||||
"estree-walker": "^2.0.2",
|
"estree-walker": "^2.0.2",
|
||||||
"source-map-js": "^1.2.1"
|
"source-map-js": "^1.2.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/compiler-ssr/node_modules/@vue/compiler-dom": {
|
"node_modules/@vue/compiler-ssr/node_modules/@vue/compiler-dom": {
|
||||||
"version": "3.5.39",
|
"version": "3.5.40",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.39.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.40.tgz",
|
||||||
"integrity": "sha512-oQPigALqYbNxTNPvNgSOe+czwVExfbVF02lz8jP0S3AXJiu3jxYDygNUiqSep4ezzW8XgnubqH63My2A7JR/vg==",
|
"integrity": "sha512-pwkx4vqlqOspFstrcmzwkKLePVMD3PT65imRzLhanU2V1Fj4K13g6OXjanOyzw3aTAuRk84BOmY8f3rEHqPaVA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/compiler-core": "3.5.39",
|
"@vue/compiler-core": "3.5.40",
|
||||||
"@vue/shared": "3.5.39"
|
"@vue/shared": "3.5.40"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/compiler-ssr/node_modules/@vue/shared": {
|
"node_modules/@vue/compiler-ssr/node_modules/@vue/shared": {
|
||||||
"version": "3.5.39",
|
"version": "3.5.40",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.39.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.40.tgz",
|
||||||
"integrity": "sha512-l1rrBtBfTnmxvtsvdQDXltUUy8S1Y+ZaqdfUzmAnJkTd8Z8rv5v/ytW+TKiqEOWyHPoqtPlNFSs0lhRmYVSHVA==",
|
"integrity": "sha512-WxnBtruIqOoV3rA4jeKDWzrYI5h7Cp4+pjwDi8kWGHz+IslhiN+wguLVVhtv2l8VoU02rzDCVfDjgCl1lNpZVg==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@vue/compiler-vue2": {
|
"node_modules/@vue/compiler-vue2": {
|
||||||
@@ -3219,71 +3219,69 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/reactivity": {
|
"node_modules/@vue/reactivity": {
|
||||||
"version": "3.5.39",
|
"version": "3.5.40",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.39.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.40.tgz",
|
||||||
"integrity": "sha512-TpsuBJ9gGlZa5d23XcM2y8EXanz9dZeVDQBXRwzy46ItgvM+rWpzs+UVM0wcRLxGvcav0HE5jz2gNL53xlRAog==",
|
"integrity": "sha512-B7ot9UlUZOi1zbq61/LvE88ZLTV8IlajTdiZTAEiDQgrnIMIZoPr9kGw0Zw46ObW62O9+H/Be3kMbfb7kYPQZA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/shared": "3.5.39"
|
"@vue/shared": "3.5.40"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/reactivity/node_modules/@vue/shared": {
|
"node_modules/@vue/reactivity/node_modules/@vue/shared": {
|
||||||
"version": "3.5.39",
|
"version": "3.5.40",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.39.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.40.tgz",
|
||||||
"integrity": "sha512-l1rrBtBfTnmxvtsvdQDXltUUy8S1Y+ZaqdfUzmAnJkTd8Z8rv5v/ytW+TKiqEOWyHPoqtPlNFSs0lhRmYVSHVA==",
|
"integrity": "sha512-WxnBtruIqOoV3rA4jeKDWzrYI5h7Cp4+pjwDi8kWGHz+IslhiN+wguLVVhtv2l8VoU02rzDCVfDjgCl1lNpZVg==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@vue/runtime-core": {
|
"node_modules/@vue/runtime-core": {
|
||||||
"version": "3.5.39",
|
"version": "3.5.40",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.39.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.40.tgz",
|
||||||
"integrity": "sha512-9GLtNyRvPAUMbX+7ono0RC2j0guo2LXVi8LvcmAooImACUKm0oFf0jjwbX8/H0AE/t1nxhAkn8RSl9PMCzzxZw==",
|
"integrity": "sha512-KAZLweuZ6uUJPK1PMSQPgBU5gCjgrrfjUhSglmU9NhH+Zjepa8cnwSydPWDWHDwOgY4g3VcZ+PljbiHlURNCbw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/reactivity": "3.5.39",
|
"@vue/reactivity": "3.5.40",
|
||||||
"@vue/shared": "3.5.39"
|
"@vue/shared": "3.5.40"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/runtime-core/node_modules/@vue/shared": {
|
"node_modules/@vue/runtime-core/node_modules/@vue/shared": {
|
||||||
"version": "3.5.39",
|
"version": "3.5.40",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.39.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.40.tgz",
|
||||||
"integrity": "sha512-l1rrBtBfTnmxvtsvdQDXltUUy8S1Y+ZaqdfUzmAnJkTd8Z8rv5v/ytW+TKiqEOWyHPoqtPlNFSs0lhRmYVSHVA==",
|
"integrity": "sha512-WxnBtruIqOoV3rA4jeKDWzrYI5h7Cp4+pjwDi8kWGHz+IslhiN+wguLVVhtv2l8VoU02rzDCVfDjgCl1lNpZVg==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@vue/runtime-dom": {
|
"node_modules/@vue/runtime-dom": {
|
||||||
"version": "3.5.39",
|
"version": "3.5.40",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.39.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.40.tgz",
|
||||||
"integrity": "sha512-7Y6aAGboKcXAZ3ECuUy7RrS5yy2r47dhTp2SKaJmYxjopImaVFaNa5Ne66NwGovsrxVAl5S5rwc7m22UG7Lmww==",
|
"integrity": "sha512-ZfrX8ssZQds900L9pr8AuK05ddnMsR4MPMZr8cPN9GoqoPWcXLhjvvbIA2SMv+7a97sJ1vv9pj/zxK0Cq/eEFQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/reactivity": "3.5.39",
|
"@vue/reactivity": "3.5.40",
|
||||||
"@vue/runtime-core": "3.5.39",
|
"@vue/runtime-core": "3.5.40",
|
||||||
"@vue/shared": "3.5.39",
|
"@vue/shared": "3.5.40",
|
||||||
"csstype": "^3.2.3"
|
"csstype": "^3.2.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/runtime-dom/node_modules/@vue/shared": {
|
"node_modules/@vue/runtime-dom/node_modules/@vue/shared": {
|
||||||
"version": "3.5.39",
|
"version": "3.5.40",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.39.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.40.tgz",
|
||||||
"integrity": "sha512-l1rrBtBfTnmxvtsvdQDXltUUy8S1Y+ZaqdfUzmAnJkTd8Z8rv5v/ytW+TKiqEOWyHPoqtPlNFSs0lhRmYVSHVA==",
|
"integrity": "sha512-WxnBtruIqOoV3rA4jeKDWzrYI5h7Cp4+pjwDi8kWGHz+IslhiN+wguLVVhtv2l8VoU02rzDCVfDjgCl1lNpZVg==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@vue/server-renderer": {
|
"node_modules/@vue/server-renderer": {
|
||||||
"version": "3.5.39",
|
"version": "3.5.40",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.39.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.40.tgz",
|
||||||
"integrity": "sha512-yZSakiAGw85rZfG7UM8akMnIF+FmeiNk47uvHf2nVBBSe+dIKUhZuZq9+XgJhbV3nS5Z4ALH23/MpXofW+mbcw==",
|
"integrity": "sha512-XNJym9WpevhTVt1HuwOrCRJ5Q+9z4BjTMrDtjTrvx74SmUll8spNTw6whWJa9mEkO4PKn5TihI/bm/8ds2QVJw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/compiler-ssr": "3.5.39",
|
"@vue/compiler-ssr": "3.5.40",
|
||||||
"@vue/shared": "3.5.39"
|
"@vue/runtime-dom": "3.5.40",
|
||||||
},
|
"@vue/shared": "3.5.40"
|
||||||
"peerDependencies": {
|
|
||||||
"vue": "3.5.39"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/server-renderer/node_modules/@vue/shared": {
|
"node_modules/@vue/server-renderer/node_modules/@vue/shared": {
|
||||||
"version": "3.5.39",
|
"version": "3.5.40",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.39.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.40.tgz",
|
||||||
"integrity": "sha512-l1rrBtBfTnmxvtsvdQDXltUUy8S1Y+ZaqdfUzmAnJkTd8Z8rv5v/ytW+TKiqEOWyHPoqtPlNFSs0lhRmYVSHVA==",
|
"integrity": "sha512-WxnBtruIqOoV3rA4jeKDWzrYI5h7Cp4+pjwDi8kWGHz+IslhiN+wguLVVhtv2l8VoU02rzDCVfDjgCl1lNpZVg==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@vue/shared": {
|
"node_modules/@vue/shared": {
|
||||||
@@ -3641,9 +3639,9 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/autoprefixer": {
|
"node_modules/autoprefixer": {
|
||||||
"version": "10.5.2",
|
"version": "10.5.4",
|
||||||
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.5.4.tgz",
|
||||||
"integrity": "sha512-rD5t5DwOjJdmSORcTq64j8MawTC+tbQ+HHqjR4NDumamy/ambn1UJrlKL+KdwujWxMkFjPM3pPHOEA9tl4767Q==",
|
"integrity": "sha512-MaU0U/za7N3r6brxD4YB/l4NSrFzLPlANv6wEuQVaIPlD3L4W9rFcQPbL/EilY9BHhHvhfcz3gInDLrEtWT4EA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -3661,8 +3659,8 @@
|
|||||||
],
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"browserslist": "^4.28.4",
|
"browserslist": "^4.28.6",
|
||||||
"caniuse-lite": "^1.0.30001799",
|
"caniuse-lite": "^1.0.30001806",
|
||||||
"fraction.js": "^5.3.4",
|
"fraction.js": "^5.3.4",
|
||||||
"picocolors": "^1.1.1",
|
"picocolors": "^1.1.1",
|
||||||
"postcss-value-parser": "^4.2.0"
|
"postcss-value-parser": "^4.2.0"
|
||||||
@@ -3871,9 +3869,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/caniuse-lite": {
|
"node_modules/caniuse-lite": {
|
||||||
"version": "1.0.30001805",
|
"version": "1.0.30001806",
|
||||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001805.tgz",
|
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001806.tgz",
|
||||||
"integrity": "sha512-52noaS3DubycKSXaU30TwPGIp+POyQSUVa5jBEq3vkRkY0kjyb3LQgvhU6WGyCcyXqVLWO0Cw0Q6BSdD0kUfVA==",
|
"integrity": "sha512-72Cuvd95zbSYPKq6Fhg8eDJRlzgWDf7/mtoZv6Qe/DYNCEBdNxoA3+rZAU2ZhGCpZlns3EssFavaZomckT5Uuw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -4266,9 +4264,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/electron-to-chromium": {
|
"node_modules/electron-to-chromium": {
|
||||||
"version": "1.5.389",
|
"version": "1.5.393",
|
||||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.389.tgz",
|
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.393.tgz",
|
||||||
"integrity": "sha512-cEto7aeOqBfU1D+c5py5pE+ooscKE75JifxLBdFUZsqAxRS6y7kebtxAZvICszSl05gPjYHDTjY+lXpyGvpJbg==",
|
"integrity": "sha512-kiDJdIUawuEIcp9XoICKp1iTYDEbgguIPq526N1Q7jIQDeQ3CqoMx71025PI/7E48Ddtw2HuWsVjY7afEgNxmg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
@@ -5134,9 +5132,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/happy-dom": {
|
"node_modules/happy-dom": {
|
||||||
"version": "20.10.6",
|
"version": "20.11.0",
|
||||||
"resolved": "https://registry.npmjs.org/happy-dom/-/happy-dom-20.10.6.tgz",
|
"resolved": "https://registry.npmjs.org/happy-dom/-/happy-dom-20.11.0.tgz",
|
||||||
"integrity": "sha512-6QD0ilzDDt93tX44y8tbmZdAcdTRYDhUP+Asgi6pC8Pp5IA3cvaZGyoVN/EGtlq9ziT65iPuBBn3ASLr6hCgVw==",
|
"integrity": "sha512-XogN4asPd1a56di9prVG6bZxteNcXsZxxKmAvcEfc5Px5Ca2hMyMgk8wvqK2K1V8zXg40j9VANXsDaJYh9DeNA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -5821,9 +5819,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/nanoid": {
|
"node_modules/nanoid": {
|
||||||
"version": "3.3.12",
|
"version": "3.3.16",
|
||||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz",
|
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.16.tgz",
|
||||||
"integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==",
|
"integrity": "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==",
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "github",
|
"type": "github",
|
||||||
@@ -6316,9 +6314,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/postcss": {
|
"node_modules/postcss": {
|
||||||
"version": "8.5.18",
|
"version": "8.5.20",
|
||||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.18.tgz",
|
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.20.tgz",
|
||||||
"integrity": "sha512-xdB1oSLHbz1vRWgCDalrCqEFTWzFlhqFC5tIHLMOSUIjhm3XXQ1qrFy8S/ESr1JYRRXqM3c1QFiMZUJdUTqyMQ==",
|
"integrity": "sha512-lW616l85ucIQL+FocMmL7pQFPqBmwejrCMg+iPxyImlrANNJG9NHq/RkyCZopDhd8C3LA03PHRJDjkbGu8vvug==",
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
@@ -6335,7 +6333,7 @@
|
|||||||
],
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"nanoid": "^3.3.12",
|
"nanoid": "^3.3.16",
|
||||||
"picocolors": "^1.1.1",
|
"picocolors": "^1.1.1",
|
||||||
"source-map-js": "^1.2.1"
|
"source-map-js": "^1.2.1"
|
||||||
},
|
},
|
||||||
@@ -7708,15 +7706,15 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/typescript-eslint": {
|
"node_modules/typescript-eslint": {
|
||||||
"version": "8.63.0",
|
"version": "8.64.0",
|
||||||
"resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.63.0.tgz",
|
"resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.64.0.tgz",
|
||||||
"integrity": "sha512-xgwXyzG4sK9ALkBxbyGkTMMOS+imnW65iPhxCQMK83KhxyoDNW7l+IDqEf9vMdoUidHpOoS967RCq4eMiTexwQ==",
|
"integrity": "sha512-0qg+pDNMnqYzqH9AnNK+39tejHvsShUOUUoRUgtnTGE7QuMZhiFDnozq8nHJVq+Wae6NMLKNWLg5WmkcC/ndyQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/eslint-plugin": "8.63.0",
|
"@typescript-eslint/eslint-plugin": "8.64.0",
|
||||||
"@typescript-eslint/parser": "8.63.0",
|
"@typescript-eslint/parser": "8.64.0",
|
||||||
"@typescript-eslint/typescript-estree": "8.63.0",
|
"@typescript-eslint/typescript-estree": "8.64.0",
|
||||||
"@typescript-eslint/utils": "8.63.0"
|
"@typescript-eslint/utils": "8.64.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
@@ -8249,16 +8247,16 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/vue": {
|
"node_modules/vue": {
|
||||||
"version": "3.5.39",
|
"version": "3.5.40",
|
||||||
"resolved": "https://registry.npmjs.org/vue/-/vue-3.5.39.tgz",
|
"resolved": "https://registry.npmjs.org/vue/-/vue-3.5.40.tgz",
|
||||||
"integrity": "sha512-xmZCYabFGcirU8r0fTuvl/LICc1OU620rnqepaJDL/a141ZigkG7AyaxQLdqJ02ZRYzWe6YPaDHeQx7MfknQfA==",
|
"integrity": "sha512-+8PJ4SJXdn/cHGImF4CKdxlWHIN5Dkt7DoufRREM6h6uVCx2m7QxgcEQmmzyOK8A9mcafg7sFbJFYsdFVubTig==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/compiler-dom": "3.5.39",
|
"@vue/compiler-dom": "3.5.40",
|
||||||
"@vue/compiler-sfc": "3.5.39",
|
"@vue/compiler-sfc": "3.5.40",
|
||||||
"@vue/runtime-dom": "3.5.39",
|
"@vue/runtime-dom": "3.5.40",
|
||||||
"@vue/server-renderer": "3.5.39",
|
"@vue/server-renderer": "3.5.40",
|
||||||
"@vue/shared": "3.5.39"
|
"@vue/shared": "3.5.40"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"typescript": "*"
|
"typescript": "*"
|
||||||
@@ -8383,32 +8381,32 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/vue/node_modules/@vue/compiler-core": {
|
"node_modules/vue/node_modules/@vue/compiler-core": {
|
||||||
"version": "3.5.39",
|
"version": "3.5.40",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.39.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.40.tgz",
|
||||||
"integrity": "sha512-16KBTEXAJCpDr0mwlw+AZyhu8iyC7R3S2vBwsI7QnWJU6X3WKc9VKeNEZpiMdZ569qWhz9574L3vV55qRL0Vtw==",
|
"integrity": "sha512-39E8IgOhTbVDnoJFMKc2DvYnypcZwUqgUhQkccva/0m6FUwtIKSGV7n1hpVmYcFaoRAwf9pBcwnKlCEsN63ZEQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/parser": "^7.29.7",
|
"@babel/parser": "^7.29.7",
|
||||||
"@vue/shared": "3.5.39",
|
"@vue/shared": "3.5.40",
|
||||||
"entities": "^7.0.1",
|
"entities": "^7.0.1",
|
||||||
"estree-walker": "^2.0.2",
|
"estree-walker": "^2.0.2",
|
||||||
"source-map-js": "^1.2.1"
|
"source-map-js": "^1.2.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/vue/node_modules/@vue/compiler-dom": {
|
"node_modules/vue/node_modules/@vue/compiler-dom": {
|
||||||
"version": "3.5.39",
|
"version": "3.5.40",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.39.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.40.tgz",
|
||||||
"integrity": "sha512-oQPigALqYbNxTNPvNgSOe+czwVExfbVF02lz8jP0S3AXJiu3jxYDygNUiqSep4ezzW8XgnubqH63My2A7JR/vg==",
|
"integrity": "sha512-pwkx4vqlqOspFstrcmzwkKLePVMD3PT65imRzLhanU2V1Fj4K13g6OXjanOyzw3aTAuRk84BOmY8f3rEHqPaVA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/compiler-core": "3.5.39",
|
"@vue/compiler-core": "3.5.40",
|
||||||
"@vue/shared": "3.5.39"
|
"@vue/shared": "3.5.40"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/vue/node_modules/@vue/shared": {
|
"node_modules/vue/node_modules/@vue/shared": {
|
||||||
"version": "3.5.39",
|
"version": "3.5.40",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.39.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.40.tgz",
|
||||||
"integrity": "sha512-l1rrBtBfTnmxvtsvdQDXltUUy8S1Y+ZaqdfUzmAnJkTd8Z8rv5v/ytW+TKiqEOWyHPoqtPlNFSs0lhRmYVSHVA==",
|
"integrity": "sha512-WxnBtruIqOoV3rA4jeKDWzrYI5h7Cp4+pjwDi8kWGHz+IslhiN+wguLVVhtv2l8VoU02rzDCVfDjgCl1lNpZVg==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/whatwg-mimetype": {
|
"node_modules/whatwg-mimetype": {
|
||||||
@@ -8580,9 +8578,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/ws": {
|
"node_modules/ws": {
|
||||||
"version": "8.21.0",
|
"version": "8.21.1",
|
||||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.21.0.tgz",
|
"resolved": "https://registry.npmjs.org/ws/-/ws-8.21.1.tgz",
|
||||||
"integrity": "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==",
|
"integrity": "sha512-+0NTnW77fFN/DjQi6k/Sq/Yvk4Sgajw7urW8V+asjXnRgDs9gyGkdb7EzgfhA4goXsRIZKE28fzIXBHEzhuiWw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
|
|||||||
12
package.json
12
package.json
@@ -33,16 +33,16 @@
|
|||||||
"@tailwindcss/typography": "^0.5.20",
|
"@tailwindcss/typography": "^0.5.20",
|
||||||
"@types/chroma-js": "^3.1.2",
|
"@types/chroma-js": "^3.1.2",
|
||||||
"@types/node": "^22.19.19",
|
"@types/node": "^22.19.19",
|
||||||
"@vitejs/plugin-vue": "^6.0.7",
|
"@vitejs/plugin-vue": "^6.0.8",
|
||||||
"@vue/test-utils": "^2.4.11",
|
"@vue/test-utils": "^2.4.11",
|
||||||
"@vue/tsconfig": "^0.9.1",
|
"@vue/tsconfig": "^0.9.1",
|
||||||
"autoprefixer": "^10.5.2",
|
"autoprefixer": "^10.5.4",
|
||||||
"axios": "^1.18.1",
|
"axios": "^1.18.1",
|
||||||
"eslint-plugin-unused-imports": "^4.4.1",
|
"eslint-plugin-unused-imports": "^4.4.1",
|
||||||
"happy-dom": "^20.10.6",
|
"happy-dom": "^20.11.0",
|
||||||
"laravel-vite-plugin": "^2.1.0",
|
"laravel-vite-plugin": "^2.1.0",
|
||||||
"openapi-zod-client": "^1.18.3",
|
"openapi-zod-client": "^1.18.3",
|
||||||
"postcss": "^8.5.18",
|
"postcss": "^8.5.20",
|
||||||
"postcss-import": "^15.1.0",
|
"postcss-import": "^15.1.0",
|
||||||
"postcss-nesting": "^12.1.5",
|
"postcss-nesting": "^12.1.5",
|
||||||
"tailwindcss": "^3.4.19",
|
"tailwindcss": "^3.4.19",
|
||||||
@@ -50,14 +50,14 @@
|
|||||||
"vite": "^7.3.3",
|
"vite": "^7.3.3",
|
||||||
"vite-plugin-checker": "^0.14.4",
|
"vite-plugin-checker": "^0.14.4",
|
||||||
"vitest": "^4.1.10",
|
"vitest": "^4.1.10",
|
||||||
"vue": "^3.5.39",
|
"vue": "^3.5.40",
|
||||||
"vue-tsc": "^3.3.7"
|
"vue-tsc": "^3.3.7"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@floating-ui/core": "^1.8.0",
|
"@floating-ui/core": "^1.8.0",
|
||||||
"@floating-ui/vue": "^1.1.11",
|
"@floating-ui/vue": "^1.1.11",
|
||||||
"@heroicons/vue": "^2.2.0",
|
"@heroicons/vue": "^2.2.0",
|
||||||
"@lucide/vue": "^1.24.0",
|
"@lucide/vue": "^1.25.0",
|
||||||
"@rushstack/eslint-patch": "^1.16.1",
|
"@rushstack/eslint-patch": "^1.16.1",
|
||||||
"@tailwindcss/container-queries": "^0.1.1",
|
"@tailwindcss/container-queries": "^0.1.1",
|
||||||
"@tanstack/vue-form": "^1.33.2",
|
"@tanstack/vue-form": "^1.33.2",
|
||||||
|
|||||||
@@ -92,6 +92,30 @@ class TimeEntryEndpointTest extends ApiEndpointTestAbstract
|
|||||||
$response->assertJsonPath('data.0.id', $timeEntry->getKey());
|
$response->assertJsonPath('data.0.id', $timeEntry->getKey());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function test_index_endpoint_filters_by_member_id_instead_of_legacy_user_id(): void
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
$data = $this->createUserWithPermission([
|
||||||
|
'time-entries:view:own',
|
||||||
|
]);
|
||||||
|
$legacyUser = User::factory()->create();
|
||||||
|
$timeEntry = TimeEntry::factory()->forMember($data->member)->create([
|
||||||
|
'user_id' => $legacyUser->getKey(),
|
||||||
|
]);
|
||||||
|
Passport::actingAs($data->user);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
$response = $this->getJson(route('api.v1.time-entries.index', [
|
||||||
|
$data->organization->getKey(),
|
||||||
|
'member_id' => $data->member->getKey(),
|
||||||
|
]));
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
$this->assertResponseCode($response, 200);
|
||||||
|
$response->assertJsonCount(1, 'data');
|
||||||
|
$response->assertJsonPath('data.0.id', $timeEntry->getKey());
|
||||||
|
}
|
||||||
|
|
||||||
public function test_index_endpoint_fails_if_user_filter_is_from_different_organization(): void
|
public function test_index_endpoint_fails_if_user_filter_is_from_different_organization(): void
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
@@ -126,7 +150,10 @@ class TimeEntryEndpointTest extends ApiEndpointTestAbstract
|
|||||||
Passport::actingAs($data->user);
|
Passport::actingAs($data->user);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
$response = $this->getJson(route('api.v1.time-entries.index', [$data->organization->getKey(), 'user_id' => $user->getKey()]));
|
$response = $this->getJson(route('api.v1.time-entries.index', [
|
||||||
|
$data->organization->getKey(),
|
||||||
|
'member_id' => $member->getKey(),
|
||||||
|
]));
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
$this->assertResponseCode($response, 200);
|
$this->assertResponseCode($response, 200);
|
||||||
@@ -1772,6 +1799,29 @@ class TimeEntryEndpointTest extends ApiEndpointTestAbstract
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function test_aggregate_endpoint_filters_by_member_id_instead_of_legacy_user_id(): void
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
$data = $this->createUserWithPermission([
|
||||||
|
'time-entries:view:own',
|
||||||
|
]);
|
||||||
|
$legacyUser = User::factory()->create();
|
||||||
|
TimeEntry::factory()->forMember($data->member)->startWithDuration(Carbon::now(), 100)->create([
|
||||||
|
'user_id' => $legacyUser->getKey(),
|
||||||
|
]);
|
||||||
|
Passport::actingAs($data->user);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
$response = $this->getJson(route('api.v1.time-entries.aggregate', [
|
||||||
|
$data->organization->getKey(),
|
||||||
|
'member_id' => $data->member->getKey(),
|
||||||
|
]));
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
$response->assertSuccessful();
|
||||||
|
$response->assertJsonPath('data.seconds', 100);
|
||||||
|
}
|
||||||
|
|
||||||
public function test_aggregate_endpoint_groups_by_two_groups(): void
|
public function test_aggregate_endpoint_groups_by_two_groups(): void
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
@@ -2819,6 +2869,32 @@ class TimeEntryEndpointTest extends ApiEndpointTestAbstract
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function test_update_endpoint_updates_user_id_when_member_id_changes(): void
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
$data = $this->createUserWithPermission([
|
||||||
|
'time-entries:update:all',
|
||||||
|
]);
|
||||||
|
$otherUser = User::factory()->create();
|
||||||
|
$otherMember = Member::factory()->forOrganization($data->organization)->forUser($otherUser)->role(Role::Employee)->create();
|
||||||
|
$timeEntry = TimeEntry::factory()->forMember($data->member)->create();
|
||||||
|
Passport::actingAs($data->user);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
$response = $this->putJson(route('api.v1.time-entries.update', [$data->organization->getKey(), $timeEntry->getKey()]), [
|
||||||
|
'member_id' => $otherMember->getKey(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
$response->assertValid();
|
||||||
|
$this->assertResponseCode($response, 200);
|
||||||
|
$this->assertDatabaseHas(TimeEntry::class, [
|
||||||
|
'id' => $timeEntry->getKey(),
|
||||||
|
'member_id' => $otherMember->getKey(),
|
||||||
|
'user_id' => $otherUser->getKey(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
public function test_update_endpoint_can_update_project_and_automatically_set_client(): void
|
public function test_update_endpoint_can_update_project_and_automatically_set_client(): void
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
@@ -3155,6 +3231,40 @@ class TimeEntryEndpointTest extends ApiEndpointTestAbstract
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function test_destroy_multiple_uses_member_id_for_own_permission_checks(): void
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
$data = $this->createUserWithPermission([
|
||||||
|
'time-entries:delete:own',
|
||||||
|
]);
|
||||||
|
$otherUser = User::factory()->create();
|
||||||
|
$otherMember = Member::factory()->forOrganization($data->organization)->forUser($otherUser)->role(Role::Employee)->create();
|
||||||
|
$timeEntry = TimeEntry::factory()->forMember($otherMember)->create([
|
||||||
|
'user_id' => $data->user->getKey(),
|
||||||
|
]);
|
||||||
|
Passport::actingAs($data->user);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
$response = $this->deleteJson(route('api.v1.time-entries.destroy-multiple', [$data->organization->getKey()]), [
|
||||||
|
'ids' => [
|
||||||
|
$timeEntry->getKey(),
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
$response->assertValid();
|
||||||
|
$this->assertResponseCode($response, 200);
|
||||||
|
$response->assertExactJson([
|
||||||
|
'success' => [],
|
||||||
|
'error' => [
|
||||||
|
$timeEntry->getKey(),
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
$this->assertDatabaseHas(TimeEntry::class, [
|
||||||
|
'id' => $timeEntry->getKey(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
public function test_destroy_multiple_deletes_all_time_entries_and_fails_for_time_entries_of_other_users_and_and_other_organizations_with_all_time_entries_permission(): void
|
public function test_destroy_multiple_deletes_all_time_entries_and_fails_for_time_entries_of_other_users_and_and_other_organizations_with_all_time_entries_permission(): void
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
@@ -3566,6 +3676,46 @@ class TimeEntryEndpointTest extends ApiEndpointTestAbstract
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function test_update_multiple_uses_member_id_for_own_permission_checks(): void
|
||||||
|
{
|
||||||
|
// 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();
|
||||||
|
$timeEntry = TimeEntry::factory()->forMember($otherMember)->create([
|
||||||
|
'user_id' => $data->user->getKey(),
|
||||||
|
]);
|
||||||
|
$timeEntriesFake = TimeEntry::factory()->forOrganization($data->organization)->make();
|
||||||
|
Passport::actingAs($data->user);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
$response = $this->patchJson(route('api.v1.time-entries.update-multiple', [$data->organization->getKey()]), [
|
||||||
|
'ids' => [
|
||||||
|
$timeEntry->getKey(),
|
||||||
|
],
|
||||||
|
'changes' => [
|
||||||
|
'description' => $timeEntriesFake->description,
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
$response->assertValid();
|
||||||
|
$this->assertResponseCode($response, 200);
|
||||||
|
$response->assertExactJson([
|
||||||
|
'success' => [],
|
||||||
|
'error' => [
|
||||||
|
$timeEntry->getKey(),
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
$this->assertDatabaseHas(TimeEntry::class, [
|
||||||
|
'id' => $timeEntry->getKey(),
|
||||||
|
'description' => $timeEntry->description,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
public function test_update_multiple_updates_sets_description_to_empty_if_the_client_sends_null(): void
|
public function test_update_multiple_updates_sets_description_to_empty_if_the_client_sends_null(): void
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
@@ -3612,6 +3762,51 @@ class TimeEntryEndpointTest extends ApiEndpointTestAbstract
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function test_update_multiple_updates_user_id_when_member_id_changes(): void
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
$data = $this->createUserWithPermission([
|
||||||
|
'time-entries:update:all',
|
||||||
|
]);
|
||||||
|
$otherUser = User::factory()->create();
|
||||||
|
$otherMember = Member::factory()->forOrganization($data->organization)->forUser($otherUser)->role(Role::Employee)->create();
|
||||||
|
$timeEntry1 = TimeEntry::factory()->forMember($data->member)->create();
|
||||||
|
$timeEntry2 = TimeEntry::factory()->forMember($data->member)->create();
|
||||||
|
Passport::actingAs($data->user);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
$response = $this->patchJson(route('api.v1.time-entries.update-multiple', [$data->organization->getKey()]), [
|
||||||
|
'ids' => [
|
||||||
|
$timeEntry1->getKey(),
|
||||||
|
$timeEntry2->getKey(),
|
||||||
|
],
|
||||||
|
'changes' => [
|
||||||
|
'member_id' => $otherMember->getKey(),
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
$response->assertValid();
|
||||||
|
$response->assertStatus(200);
|
||||||
|
$response->assertExactJson([
|
||||||
|
'success' => [
|
||||||
|
$timeEntry1->getKey(),
|
||||||
|
$timeEntry2->getKey(),
|
||||||
|
],
|
||||||
|
'error' => [],
|
||||||
|
]);
|
||||||
|
$this->assertDatabaseHas(TimeEntry::class, [
|
||||||
|
'id' => $timeEntry1->getKey(),
|
||||||
|
'member_id' => $otherMember->getKey(),
|
||||||
|
'user_id' => $otherUser->getKey(),
|
||||||
|
]);
|
||||||
|
$this->assertDatabaseHas(TimeEntry::class, [
|
||||||
|
'id' => $timeEntry2->getKey(),
|
||||||
|
'member_id' => $otherMember->getKey(),
|
||||||
|
'user_id' => $otherUser->getKey(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
public function test_update_multiple_updates_all_time_entries_and_fails_for_time_entries_of_other_users_and_and_other_organizations_with_all_time_entries_permission(): void
|
public function test_update_multiple_updates_all_time_entries_and_fails_for_time_entries_of_other_users_and_and_other_organizations_with_all_time_entries_permission(): void
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
|
|||||||
Reference in New Issue
Block a user