diff --git a/.github/workflows/auto-publish-google-play-on-release.yml b/.github/workflows/auto-publish-google-play-on-release.yml index 81ede3073c..3b3a8deb38 100644 --- a/.github/workflows/auto-publish-google-play-on-release.yml +++ b/.github/workflows/auto-publish-google-play-on-release.yml @@ -13,7 +13,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@f808768d1510423e83855289c910610ca9b43176 # v2.17.0 + uses: step-security/harden-runner@fe104658747b27e96e4f7e80cd0a94068e53901d # v2.16.1 with: egress-policy: audit allowed-endpoints: > diff --git a/.github/workflows/build-android.yml b/.github/workflows/build-android.yml index 686d27b2fe..1c9c549bda 100644 --- a/.github/workflows/build-android.yml +++ b/.github/workflows/build-android.yml @@ -77,7 +77,7 @@ jobs: # APK is now signed automatically by Gradle using signingConfig - name: 'Upload APK files' - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: sup-android-release path: android/app/build/outputs/apk/**/*.apk diff --git a/.github/workflows/build-create-windows-store-on-release.yml b/.github/workflows/build-create-windows-store-on-release.yml index d458efeb60..db7256726b 100644 --- a/.github/workflows/build-create-windows-store-on-release.yml +++ b/.github/workflows/build-create-windows-store-on-release.yml @@ -77,7 +77,7 @@ jobs: github_token: ${{ secrets.github_token }} - name: 'Upload Artifact' - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: WinStoreRelease path: .tmp/app-builds/*.appx diff --git a/.github/workflows/build-ios.yml b/.github/workflows/build-ios.yml index 83f36608a8..7cb617de24 100644 --- a/.github/workflows/build-ios.yml +++ b/.github/workflows/build-ios.yml @@ -200,7 +200,7 @@ jobs: run: ls -la "$RUNNER_TEMP/ipa-output" - name: Upload IPA artifact - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: sup-ios-release path: ${{ runner.temp }}/ipa-output/*.ipa diff --git a/.github/workflows/build-publish-to-mac-store-on-release.yml b/.github/workflows/build-publish-to-mac-store-on-release.yml index d307f0a8ea..e103e60518 100644 --- a/.github/workflows/build-publish-to-mac-store-on-release.yml +++ b/.github/workflows/build-publish-to-mac-store-on-release.yml @@ -15,7 +15,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@f808768d1510423e83855289c910610ca9b43176 # v2.17.0 + uses: step-security/harden-runner@fe104658747b27e96e4f7e80cd0a94068e53901d # v2.16.1 with: egress-policy: audit allowed-endpoints: > diff --git a/.github/workflows/build-update-web-app-on-release.yml b/.github/workflows/build-update-web-app-on-release.yml index 84aff205b1..72378cace3 100644 --- a/.github/workflows/build-update-web-app-on-release.yml +++ b/.github/workflows/build-update-web-app-on-release.yml @@ -15,7 +15,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@f808768d1510423e83855289c910610ca9b43176 # v2.17.0 + uses: step-security/harden-runner@fe104658747b27e96e4f7e80cd0a94068e53901d # v2.16.1 with: egress-policy: audit allowed-endpoints: > @@ -69,7 +69,7 @@ jobs: run: npm run buildFrontend:prodWeb - name: Deploy to Web Server - uses: easingthemes/ssh-deploy@2cc5b27bf3029d0455dd5e09fe02633904031447 # v6.0.3 + uses: easingthemes/ssh-deploy@a1aa0b6cf96ce2406eef90faa35007a4a7bf0ac0 # v5.1.1 env: SSH_PRIVATE_KEY: ${{ secrets.WEB_SERVER_SSH_KEY }} ARGS: '-rltgoDzvO --delete --exclude "news.json"' diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index aacfec7f93..0c39cff29c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -31,7 +31,7 @@ jobs: fi } > /tmp/release-body.md - name: Create Draft Release - uses: softprops/action-gh-release@b4309332981a82ec1c5618f44dd2e27cc8bfbfda # v3.0.0 + uses: softprops/action-gh-release@153bb8e04406b158c6c84fc1615b65b24149a1fe # v2.6.1 with: tag_name: ${{ github.ref_name }} draft: true @@ -102,7 +102,7 @@ jobs: - name: 'Upload E2E results on failure' if: ${{ failure() }} - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: e2eResults path: .tmp/e2e-test-results/**/*.* @@ -314,7 +314,7 @@ jobs: - name: Upload unsigned executables for SignPath id: upload-unsigned - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: unsigned-windows-executables path: .tmp/app-builds/*.exe @@ -322,7 +322,7 @@ jobs: retention-days: 1 - name: Sign Windows executables with SignPath - uses: signpath/github-action-submit-signing-request@bc66d86b015a46e9c6d9700de73143a82f9570ff # v2 + uses: signpath/github-action-submit-signing-request@3f9250c56651ff692d6729a2fbb0603a42d7d322 # v2 with: api-token: ${{ secrets.SIGNPATH_API_TOKEN }} organization-id: ${{ secrets.SIGNPATH_ORGANIZATION_ID }} @@ -474,7 +474,7 @@ jobs: " - name: Publish signed Windows binaries to GitHub Release - uses: softprops/action-gh-release@b4309332981a82ec1c5618f44dd2e27cc8bfbfda # v3.0.0 + uses: softprops/action-gh-release@153bb8e04406b158c6c84fc1615b65b24149a1fe # v2.6.1 with: token: ${{ secrets.GITHUB_TOKEN }} files: | diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9f74513bc9..eee6282d46 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -120,7 +120,7 @@ jobs: run: npm run e2e:ci - name: 'Upload E2E results on failure' if: ${{ failure() }} - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: e2eResults path: .tmp/e2e-test-results/**/*.* diff --git a/.github/workflows/claude.yml b/.github/workflows/claude.yml index b7c75fa373..63e4653092 100644 --- a/.github/workflows/claude.yml +++ b/.github/workflows/claude.yml @@ -32,7 +32,7 @@ jobs: - name: Run Claude Code id: claude - uses: anthropics/claude-code-action@b47fd721da662d48c5680e154ad16a73ed74d2e0 # v1 + uses: anthropics/claude-code-action@6e2bd52842c65e914eba5c8badd17560bd26b5de # v1 with: claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} github_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/e2e-scheduled.yml b/.github/workflows/e2e-scheduled.yml index a879d99d77..37dfe370a2 100644 --- a/.github/workflows/e2e-scheduled.yml +++ b/.github/workflows/e2e-scheduled.yml @@ -50,7 +50,7 @@ jobs: test -f .tmp/angular-dist/browser/assets/bundled-plugins/api-test-plugin/manifest.json || (echo "Plugin assets missing from build" && exit 1) - name: Upload Build Artifact - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: e2e-build-${{ github.run_id }} path: .tmp/angular-dist @@ -86,7 +86,7 @@ jobs: - name: Upload E2E Results on Failure if: ${{ failure() }} - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: e2e-results-regular-${{ github.run_id }} path: .tmp/e2e-test-results/**/*.* @@ -143,7 +143,7 @@ jobs: - name: Upload E2E Results on Failure if: ${{ failure() }} - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: e2e-results-webdav-${{ github.run_id }} path: .tmp/e2e-test-results/**/*.* @@ -205,7 +205,7 @@ jobs: - name: Upload E2E Results on Failure if: ${{ failure() }} - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: e2e-results-supersync-${{ matrix.shard }}-${{ github.run_id }} path: .tmp/e2e-test-results/**/*.* diff --git a/.github/workflows/manual-build.yml b/.github/workflows/manual-build.yml index 77a20a86db..ce3353b999 100644 --- a/.github/workflows/manual-build.yml +++ b/.github/workflows/manual-build.yml @@ -62,7 +62,7 @@ jobs: release: false - name: 'Upload Artifact' - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: WinBuildStuff path: .tmp/app-builds/*.exe @@ -162,7 +162,7 @@ jobs: # if: always() # run: ls -la && cat notarization-error.log - name: 'Upload Artifact' - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: dmg path: .tmp/app-builds/*.dmg diff --git a/.github/workflows/pr-preview-build.yml b/.github/workflows/pr-preview-build.yml index 938ecc095d..6b22e4736e 100644 --- a/.github/workflows/pr-preview-build.yml +++ b/.github/workflows/pr-preview-build.yml @@ -41,7 +41,7 @@ jobs: run: npm run buildFrontend:prodWeb - name: Upload build artifact - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: pr-preview-build path: dist/browser diff --git a/.github/workflows/publish-to-hub-docker.yml b/.github/workflows/publish-to-hub-docker.yml index fb73c5afb1..885086f451 100644 --- a/.github/workflows/publish-to-hub-docker.yml +++ b/.github/workflows/publish-to-hub-docker.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@f808768d1510423e83855289c910610ca9b43176 # v2.17.0 + uses: step-security/harden-runner@fe104658747b27e96e4f7e80cd0a94068e53901d # v2.16.1 with: egress-policy: audit allowed-endpoints: > @@ -55,7 +55,7 @@ jobs: uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0 - name: Build and push Docker image - uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0 + uses: docker/build-push-action@d08e5c354a6adb9ed34480a06d141179aa583294 # v7.0.0 with: context: . push: true diff --git a/.github/workflows/supersync-docker.yml b/.github/workflows/supersync-docker.yml index b80ea5bdf4..8af1cde34b 100644 --- a/.github/workflows/supersync-docker.yml +++ b/.github/workflows/supersync-docker.yml @@ -19,7 +19,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@f808768d1510423e83855289c910610ca9b43176 # v2.17.0 + uses: step-security/harden-runner@fe104658747b27e96e4f7e80cd0a94068e53901d # v2.16.1 with: egress-policy: audit allowed-endpoints: > @@ -59,7 +59,7 @@ jobs: uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0 - name: Build and push Docker image - uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0 + uses: docker/build-push-action@d08e5c354a6adb9ed34480a06d141179aa583294 # v7.0.0 with: context: . file: ./packages/super-sync-server/Dockerfile diff --git a/.github/workflows/test-mac-dmg-build.yml b/.github/workflows/test-mac-dmg-build.yml index 4e827c9da2..7613ccd018 100644 --- a/.github/workflows/test-mac-dmg-build.yml +++ b/.github/workflows/test-mac-dmg-build.yml @@ -117,7 +117,7 @@ jobs: fi - name: Upload DMG artifact - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: mac-dmg-build path: .tmp/app-builds/*.dmg diff --git a/android/app/src/main/java/com/superproductivity/superproductivity/plugins/SafBridgePlugin.kt b/android/app/src/main/java/com/superproductivity/superproductivity/plugins/SafBridgePlugin.kt index 48b72b8fd2..060f3743d8 100644 --- a/android/app/src/main/java/com/superproductivity/superproductivity/plugins/SafBridgePlugin.kt +++ b/android/app/src/main/java/com/superproductivity/superproductivity/plugins/SafBridgePlugin.kt @@ -2,9 +2,7 @@ package com.superproductivity.superproductivity.plugins import android.app.Activity import android.content.Intent -import android.content.pm.PackageManager import android.net.Uri -import android.os.Process import android.provider.DocumentsContract import androidx.activity.result.ActivityResult import androidx.documentfile.provider.DocumentFile @@ -42,26 +40,18 @@ class SafBridgePlugin : Plugin() { @ActivityCallback private fun handleFolderSelectionResult(call: PluginCall, result: ActivityResult) { if (result.resultCode == Activity.RESULT_OK) { - val resultData = result.data - val uri = resultData?.data + val uri = result.data?.data if (uri != null) { - // Use only the flags that were actually granted by the result intent. - // Applying flags not present in the result throws SecurityException on some devices. - // resultData is Intent? but uri != null proves resultData is non-null here; - // Kotlin cannot infer this transitively, so !! is required and safe. - val grantedFlags = resultData!!.flags and - (Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION) + // Take persistable permission try { - context.contentResolver.takePersistableUriPermission(uri, grantedFlags) + val takeFlags = Intent.FLAG_GRANT_READ_URI_PERMISSION or + Intent.FLAG_GRANT_WRITE_URI_PERMISSION + context.contentResolver.takePersistableUriPermission(uri, takeFlags) } catch (e: SecurityException) { - // Some devices/OEM ROMs fail to persist SAF permission even when - // FLAG_GRANT_PERSISTABLE_URI_PERMISSION was requested. Fall through and - // still return the URI — it will work for this session even if it can't - // be persisted across reboots (user will need to re-select next launch). - android.util.Log.w( - "SafBridgePlugin", - "Could not persist URI permission (session-only access): ${e.message}", - ) + // Some devices/Android versions fail to persist SAF permission + android.util.Log.w("SafBridgePlugin", "Failed to persist URI permission: ${e.message}") + call.reject("Failed to persist folder permission: ${e.message}") + return } val ret = JSObject() @@ -218,19 +208,8 @@ class SafBridgePlugin : Plugin() { try { val uri = Uri.parse(uriString) - // Check both persistent grants (survive reboots) and temporary session grants - // (active for current app session only). This is required to support devices/OEM - // ROMs where takePersistableUriPermission throws SecurityException — on those - // devices the session grant is still valid even though it could not be persisted. - val pid = Process.myPid() - val uid = Process.myUid() - val canRead = context.checkUriPermission( - uri, pid, uid, Intent.FLAG_GRANT_READ_URI_PERMISSION, - ) == PackageManager.PERMISSION_GRANTED - val canWrite = context.checkUriPermission( - uri, pid, uid, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, - ) == PackageManager.PERMISSION_GRANTED - val hasPermission = canRead && canWrite + val persistedUris = context.contentResolver.persistedUriPermissions + val hasPermission = persistedUris.any { it.uri == uri && it.isReadPermission && it.isWritePermission } val ret = JSObject() ret.put("hasPermission", hasPermission) diff --git a/docs/long-term-plans/location-based-reminders.md b/docs/long-term-plans/location-based-reminders.md deleted file mode 100644 index 1c53422c43..0000000000 --- a/docs/long-term-plans/location-based-reminders.md +++ /dev/null @@ -1,513 +0,0 @@ -# Location-Based Reminders — Design Document - -> **Status: Planned (Brainstorm)** - -## Overview - -Add location-based reminders to Super Productivity. Users can attach a saved location to a task and receive a notification when they arrive at that place. This is primarily a mobile feature (Android/iOS via Capacitor), with passive location display on desktop/web. - -## Decisions - -| Decision | Choice | Rationale | -|----------|--------|-----------| -| Primary platform | Mobile (Android/iOS) | Geofencing requires GPS + background location. Desktop/web show location info but don't trigger. | -| Trigger type | Arrive only (v1) | Simplest. Leave triggers can be added later. | -| Location management | Saved locations entity | Users revisit the same places. Follows existing Tag entity pattern. | -| Location picker (v1) | "Use current location" + label | No map needed for v1. Map picker is a v2 enhancement. | -| Geofencing approach | Custom native Capacitor plugin | `@capacitor/geolocation` only does point-in-time reads, not geofencing. Need native `GeofencingClient` (Android) / `CLLocationManager` (iOS). | -| Sync | Sync by default | Location data treated like any other entity. Each device manages its own geofences locally after sync. | -| Feature toggle | `isLocationRemindersEnabled` in `AppFeaturesConfig` | Opt-in, default false. | - ---- - -## 1. Data Model - -### 1.1 SavedLocation Entity - -New file: `src/app/features/saved-location/saved-location.model.ts` - -```typescript -import { EntityState } from '@ngrx/entity'; - -export interface SavedLocationCopy { - id: string; - title: string; // "Office", "Grocery Store", "Gym" - lat: number; // latitude - lng: number; // longitude - radius: number; // geofence radius in meters (default 200) - icon?: string | null; // material icon name, e.g. 'home', 'work', 'shopping_cart' - created: number; // creation timestamp - modified?: number; // last update timestamp -} - -export type SavedLocation = Readonly; -export type SavedLocationState = EntityState; -``` - -### 1.2 Task Model Changes - -File: `src/app/features/tasks/task.model.ts` — add to `TaskCopy`: - -```typescript -/** ID of a SavedLocation. When set, a geofence reminder is active for this task. */ -locationReminderId?: string | null; -``` - -### 1.3 Config Changes - -File: `src/app/features/config/global-config.model.ts` — add to `AppFeaturesConfig`: - -```typescript -isLocationRemindersEnabled: boolean; // default false -``` - -File: `src/app/features/config/default-global-config.const.ts` — set default: - -```typescript -isLocationRemindersEnabled: false, -``` - -### 1.4 Platform Capabilities - -File: `src/app/core/platform/platform-capabilities.model.ts` — add: - -```typescript -/** Whether the platform supports native geofencing (background location monitoring). */ -readonly geofencing: boolean; -``` - -| Platform | `geofencing` | -|----------|-------------| -| Android (`ANDROID_CAPABILITIES`) | `true` | -| iOS (`IOS_CAPABILITIES`) | `true` | -| Electron (`ELECTRON_CAPABILITIES`) | `false` | -| Web (`WEB_CAPABILITIES`) | `false` | - ---- - -## 2. Sync & Persistence Registration - -All registration steps required for the new entity, following existing patterns: - -### 2.1 Entity Type - -File: `packages/shared-schema/src/entity-types.ts` - -Add `'SAVED_LOCATION'` to the `ENTITY_TYPES` array. - -### 2.2 Action Types Enum - -File: `src/app/op-log/core/action-types.enum.ts` - -```typescript -// SavedLocation actions -SAVED_LOCATION_ADD = '[SavedLocation] Add SavedLocation', -SAVED_LOCATION_UPDATE = '[SavedLocation] Update SavedLocation', -SAVED_LOCATION_DELETE = '[SavedLocation] Delete SavedLocation', -``` - -These string values are **immutable** once deployed — they are used for encoding/decoding operations in IndexedDB and sync between clients. - -### 2.3 Entity Registry - -File: `src/app/op-log/core/entity-registry.ts` - -Add to `ENTITY_CONFIGS`: - -```typescript -SAVED_LOCATION: { - storagePattern: 'adapter', - featureName: SAVED_LOCATION_FEATURE_NAME, - payloadKey: 'savedLocation', - adapter: savedLocationAdapter, - selectEntities: createSelector( - selectSavedLocationFeatureState, - selectSavedLocationEntitiesFromAdapter, - ), - selectById: selectSavedLocationById, -}, -``` - -### 2.4 Model Config - -File: `src/app/op-log/model/model-config.ts` - -Add to `AllModelConfig` type: - -```typescript -savedLocation: ModelCfg; -``` - -Add to `MODEL_CONFIGS`: - -```typescript -savedLocation: { - defaultData: initialSavedLocationState, - isMainFileModel: true, - repair: fixEntityStateConsistency, -}, -``` - -### 2.5 Root State - -File: `src/app/root-store/root-state.ts` - -```typescript -[SAVED_LOCATION_FEATURE_NAME]: SavedLocationState; -``` - -### 2.6 Feature Store Registration - -File: `src/app/root-store/feature-stores.module.ts` - -```typescript -StoreModule.forFeature(SAVED_LOCATION_FEATURE_NAME, savedLocationReducer), -``` - -### 2.7 Cascading Delete Meta-Reducer - -File: `src/app/root-store/meta/task-shared-meta-reducers/saved-location-shared.reducer.ts` - -When a SavedLocation is deleted, clear `locationReminderId` on all tasks that reference it. This must be a meta-reducer (not an effect) to ensure atomicity — one operation in the sync log. - -Register in `src/app/root-store/meta/meta-reducer-registry.ts` in **Phase 5** (Entity-Specific Cascades), alongside `tagSharedMetaReducer`, `projectSharedMetaReducer`, etc. - ---- - -## 3. NgRx Store - -### 3.1 Actions - -File: `src/app/features/saved-location/store/saved-location.actions.ts` - -Following the Tag action pattern with `PersistentActionMeta`: - -| Action | OpType | Payload | -|--------|--------|---------| -| `addSavedLocation` | `Create` | `{ savedLocation: SavedLocation }` | -| `updateSavedLocation` | `Update` | `{ savedLocation: Update }` | -| `deleteSavedLocation` | `Delete` | `{ id: string }` | - -All include `meta: { isPersistent: true, entityType: 'SAVED_LOCATION', entityId, opType } satisfies PersistentActionMeta`. - -### 3.2 Reducer - -File: `src/app/features/saved-location/store/saved-location.reducer.ts` - -Standard `@ngrx/entity` adapter: - -```typescript -export const SAVED_LOCATION_FEATURE_NAME = 'savedLocation'; -export const savedLocationAdapter = createEntityAdapter({ - sortComparer: (a, b) => a.title.localeCompare(b.title), -}); -export const initialSavedLocationState = savedLocationAdapter.getInitialState(); -``` - -### 3.3 Selectors - -File: `src/app/features/saved-location/store/saved-location.selectors.ts` - -| Selector | Returns | -|----------|---------| -| `selectSavedLocationFeatureState` | Feature state | -| `selectAllSavedLocations` | `SavedLocation[]` | -| `selectSavedLocationById` | `SavedLocation \| undefined` | -| `selectSavedLocationEntities` | `Dictionary` | - -Task-side selector (in task selectors or a cross-feature selector): - -| Selector | Returns | -|----------|---------| -| `selectTasksWithLocationReminder` | All undone tasks that have `locationReminderId` set | - -### 3.4 Service - -File: `src/app/features/saved-location/saved-location.service.ts` - -Thin wrapper dispatching actions to the store. Methods: `addSavedLocation()`, `updateSavedLocation()`, `deleteSavedLocation()`, `getById$()`. - ---- - -## 4. Geofencing Service - -### 4.1 Architecture - -New file: `src/app/features/saved-location/geofence.service.ts` - -``` -Store (undone tasks with locationReminderId) - → GeofenceService watches selector (distinctUntilChanged) - → Computes which locations need active geofences - → Registers/unregisters via custom Capacitor plugin - → Receives geofence enter events - → Emits to ReminderService for dialog/notification -``` - -### 4.2 Why a Custom Capacitor Plugin - -`@capacitor/geolocation` only provides one-time and continuous position reads — it does **not** support geofencing. Native geofencing requires: - -- **Android:** `com.google.android.gms.location.GeofencingClient` (Google Play Services). Supports up to 100 geofences. Fires `BroadcastReceiver` on enter/exit. -- **iOS:** `CLLocationManager.startMonitoring(for: CLCircularRegion)`. Supports up to 20 monitored regions. Fires delegate callbacks on enter/exit. - -Implementation: Create `GeofencePlugin.kt` (Android) and `GeofencePlugin.swift` (iOS) extending Capacitor's `Plugin` class. Register in `CapacitorMainActivity.onCreate()` following the pattern of `SafBridgePlugin`, `WebDavHttpPlugin`, etc. - -### 4.3 Lifecycle Rules - -**Register geofence when:** -- Feature is enabled + a task gets `locationReminderId` assigned -- App starts with existing location-reminded tasks - -**Unregister geofence when:** -- Task is completed, deleted, or `locationReminderId` cleared -- SavedLocation is deleted -- No more undone tasks reference that location -- Feature is disabled - -**iOS 20-region limit:** Only register geofences for the 20 locations with the most active tasks. Re-evaluate when tasks change. - -### 4.4 Effects - -Effects MUST use `inject(LOCAL_ACTIONS)` — geofence registration should never happen during remote sync replay. Each device manages its own geofences based on local state after sync. - -### 4.5 Background Behavior - -When geofence fires while app is in background: -- **Android:** `BroadcastReceiver` shows native notification directly (same pattern as `ReminderAlarmReceiver`). Tapping opens app + reminder dialog. -- **iOS:** `CLLocationManager` delegate fires local notification. Tapping opens app + reminder dialog. - -### 4.6 Permission Flow - -On first use: -1. Check `CapacitorPlatformService.hasCapability('geofencing')` -2. Request `ACCESS_FINE_LOCATION` + `ACCESS_BACKGROUND_LOCATION` (Android) or "Always" location access (iOS) -3. If denied: feature degrades to display-only, show explanation - ---- - -## 5. Reminder Integration - -### 5.1 Integration Point - -The existing `ReminderService.onRemindersActive$` is a derived observable — external code cannot emit to it directly. Two approaches: - -**Option A (recommended):** Add a new public subject on `ReminderService`: - -```typescript -// In ReminderService -private _onLocationReminders$ = new Subject(); -locationReminders$ = this._onLocationReminders$.asObservable(); -``` - -Then merge in `ReminderModule`: - -```typescript -merge( - this._reminderService.onRemindersActive$, - this._reminderService.locationReminders$, -).subscribe(reminders => /* existing dialog handling */); -``` - -**Option B:** Add a public method `emitLocationReminders()` that pushes to the private `_onRemindersActive$` subject. - -### 5.2 Data Shape - -Location-triggered reminders must satisfy `TaskWithReminderData`: - -```typescript -interface TaskWithReminderData extends Task { - readonly reminderData: { remindAt: number }; // use trigger timestamp - readonly parentData?: Task; - readonly isDeadlineReminder?: boolean; // false for location -} -``` - -Consider adding `isLocationReminder?: boolean` for UI differentiation. - -### 5.3 Dialog UX Changes - -The existing `DialogViewTaskRemindersComponent` works as-is with minor additions: -- Show location name/icon in header (e.g., "At: Grocery Store") -- **Snooze** = suppress this location reminder for 1 hour (temporary geofence pause) -- **Dismiss** = clear `locationReminderId` on the task -- **Done** = mark task complete (same as today) -- Hide "Edit Reminder" time picker for location-triggered reminders - -### 5.4 Native Notifications (Background) - -Reuse `CapacitorReminderService` patterns: -- Android: native notification via `ReminderNotificationHelper` triggered from geofence `BroadcastReceiver` -- iOS: `LocalNotifications.schedule()` triggered from `CLLocationManager` delegate -- Both support Done/Snooze action buttons - ---- - -## 6. UI Components - -### 6.1 New Components - -| Component | Path | Purpose | -|-----------|------|---------| -| `saved-location-settings` | `src/app/features/saved-location/saved-location-settings/` | CRUD list in settings page | -| `location-picker-dialog` | `src/app/features/saved-location/location-picker-dialog/` | Assign location to task (dropdown + "Use current location") | - -### 6.2 Modified Components - -| Component | Change | -|-----------|--------| -| Task detail panel | Add "Location" field showing assigned location | -| Task schedule dialog | Add location option alongside time-based reminder | -| Settings page | Add "Locations" section | -| Reminder dialog | Show location name when triggered by geofence | - -### 6.3 Location Picker UX - -``` -┌─────────────────────────────────┐ -│ Set Location Reminder │ -├─────────────────────────────────┤ -│ │ -│ 📍 Use Current Location │ ← gets GPS, prompts for label -│ │ -│ ─── Saved Locations ────────── │ -│ │ -│ 🏠 Home │ -│ 🏢 Office │ -│ 🛒 Grocery Store │ -│ │ -│ [ Remove Location ] [ Cancel ] │ -└─────────────────────────────────┘ -``` - -### 6.4 Settings Section - -``` -┌─────────────────────────────────┐ -│ Location Reminders │ -├─────────────────────────────────┤ -│ [Toggle] Enable location │ -│ reminders │ -│ │ -│ Saved Locations: │ -│ ┌─────────────────────────┐ │ -│ │ 🏠 Home 200m [✏️][🗑]│ │ -│ │ 🏢 Office 150m [✏️][🗑]│ │ -│ │ 🛒 Grocery 200m [✏️][🗑]│ │ -│ └─────────────────────────┘ │ -│ [ + Add Location ] │ -└─────────────────────────────────┘ -``` - ---- - -## 7. Cross-Platform Behavior - -| Platform | Geofencing | Location Display | Notifications | -|----------|-----------|-----------------|---------------| -| **Android** | Native `GeofencingClient`, up to 100 fences, background | Yes | Native via `BroadcastReceiver` | -| **iOS** | Native `CLLocationManager`, up to 20 regions, background | Yes | Native via `LocalNotifications` | -| **Electron** | None | Yes (label only) | None | -| **Web** | None | Yes (label only) | None | - ---- - -## 8. File Structure - -``` -src/app/features/saved-location/ -├── saved-location.model.ts -├── saved-location.const.ts # DEFAULT_RADIUS = 200 -├── saved-location.service.ts -├── geofence.service.ts # Capacitor geofencing bridge -├── store/ -│ ├── saved-location.actions.ts -│ ├── saved-location.reducer.ts -│ └── saved-location.selectors.ts -├── saved-location-settings/ -│ ├── saved-location-settings.component.ts -│ └── saved-location-settings.component.html -└── location-picker-dialog/ - ├── location-picker-dialog.component.ts - └── location-picker-dialog.component.html - -src/app/root-store/meta/task-shared-meta-reducers/ -└── saved-location-shared.reducer.ts # Cascading delete - -android/app/src/main/java/.../ -└── GeofencePlugin.kt # Native Android geofencing - GeofenceBroadcastReceiver.kt # Handles fence enter events - -ios/App/App/ -└── GeofencePlugin.swift # Native iOS geofencing -``` - ---- - -## 9. All Files to Touch - -### New Files - -| File | Purpose | -|------|---------| -| `src/app/features/saved-location/saved-location.model.ts` | Entity interface | -| `src/app/features/saved-location/saved-location.const.ts` | Defaults | -| `src/app/features/saved-location/saved-location.service.ts` | Service | -| `src/app/features/saved-location/geofence.service.ts` | Capacitor bridge | -| `src/app/features/saved-location/store/saved-location.actions.ts` | Actions | -| `src/app/features/saved-location/store/saved-location.reducer.ts` | Reducer + adapter | -| `src/app/features/saved-location/store/saved-location.selectors.ts` | Selectors | -| `src/app/features/saved-location/saved-location-settings/*` | Settings UI | -| `src/app/features/saved-location/location-picker-dialog/*` | Picker dialog | -| `src/app/root-store/meta/task-shared-meta-reducers/saved-location-shared.reducer.ts` | Cascading deletes | -| `android/.../GeofencePlugin.kt` | Android native geofencing | -| `android/.../GeofenceBroadcastReceiver.kt` | Android fence event handler | -| `ios/App/App/GeofencePlugin.swift` | iOS native geofencing | - -### Modified Files - -| File | Change | -|------|--------| -| `packages/shared-schema/src/entity-types.ts` | Add `'SAVED_LOCATION'` | -| `src/app/op-log/core/action-types.enum.ts` | Add `SAVED_LOCATION_ADD/UPDATE/DELETE` | -| `src/app/op-log/core/entity-registry.ts` | Add `SAVED_LOCATION` config | -| `src/app/op-log/model/model-config.ts` | Add to `AllModelConfig` + `MODEL_CONFIGS` | -| `src/app/root-store/root-state.ts` | Add to `RootState` | -| `src/app/root-store/feature-stores.module.ts` | Register feature store | -| `src/app/root-store/meta/meta-reducer-registry.ts` | Register cascading delete in Phase 5 | -| `src/app/features/tasks/task.model.ts` | Add `locationReminderId` field | -| `src/app/features/config/global-config.model.ts` | Add `isLocationRemindersEnabled` | -| `src/app/features/config/default-global-config.const.ts` | Set default `false` | -| `src/app/core/platform/platform-capabilities.model.ts` | Add `geofencing` capability | -| `src/app/features/reminder/reminder.service.ts` | Add `locationReminders$` subject | -| `src/app/features/reminder/reminder.module.ts` | Merge location reminders into dialog flow | -| `android/app/src/main/AndroidManifest.xml` | Add location permissions | -| `android/.../CapacitorMainActivity.kt` | Register `GeofencePlugin` | - ---- - -## 10. Future Enhancements (Out of Scope) - -- Map picker with OpenStreetMap tiles -- Address search / geocoding (Nominatim) -- Leave triggers ("remind when I leave the office") -- Time + location combos ("at the store, but only after 5 PM") -- Project default locations -- Location-based task views ("show tasks for where I am now") -- WiFi-based triggers (alternative to GPS, works indoors) -- Bluetooth beacon triggers - ---- - -## 11. Verification Plan - -1. **Unit tests:** SavedLocation reducer, selectors, service, cascading delete meta-reducer -2. **Manual mobile testing:** - - Create location from "Use current location" - - Assign to a task, verify geofence registration - - Move in/out of geofence, verify notification fires - - Complete task, verify geofence unregistered - - Delete location, verify `locationReminderId` cleared on tasks -3. **Desktop/web:** Verify location label displays on tasks, no geofencing attempted -4. **Sync:** Create location on device A, verify it appears on device B -5. **Lint/format:** `npm run lint`, `npm run prettier`, `npm test` diff --git a/e2e/fixtures/supersync.fixture.ts b/e2e/fixtures/supersync.fixture.ts index 1c91d4dbff..ad7013f1bc 100644 --- a/e2e/fixtures/supersync.fixture.ts +++ b/e2e/fixtures/supersync.fixture.ts @@ -47,18 +47,9 @@ export const test = base.extend({ * Also checks server health and skips test if server unavailable. */ testRunId: async ({}, use, testInfo) => { - // Check server health once per worker. - // Prefer the result pre-computed in globalSetup (stored as an env var before workers - // were forked) to avoid a stampede of concurrent HTTP requests from all workers - // simultaneously — which can overload the server and produce false negatives. + // Check server health once per worker if (serverHealthyCache === null) { - if (process.env.SUPERSYNC_SERVER_HEALTHY !== undefined) { - serverHealthyCache = process.env.SUPERSYNC_SERVER_HEALTHY === 'true'; - } else { - // Fallback for when tests are run directly without going through globalSetup - // (e.g., `npx playwright test --config ... e2e/tests/sync/foo.spec.ts`) - serverHealthyCache = await isServerHealthy(); - } + serverHealthyCache = await isServerHealthy(); if (!serverHealthyCache) { console.warn( 'SuperSync server not healthy at http://localhost:1901 - skipping tests', @@ -78,13 +69,9 @@ export const test = base.extend({ * Tests are automatically skipped if the server is not healthy. */ serverHealthy: async ({}, use, testInfo) => { - // Only check once per worker — use globalSetup env var if available (see testRunId above) + // Only check once per worker if (serverHealthyCache === null) { - if (process.env.SUPERSYNC_SERVER_HEALTHY !== undefined) { - serverHealthyCache = process.env.SUPERSYNC_SERVER_HEALTHY === 'true'; - } else { - serverHealthyCache = await isServerHealthy(); - } + serverHealthyCache = await isServerHealthy(); if (!serverHealthyCache) { console.warn( 'SuperSync server not healthy at http://localhost:1901 - skipping tests', diff --git a/e2e/global-setup.ts b/e2e/global-setup.ts index b390d4cb6e..9217ded795 100644 --- a/e2e/global-setup.ts +++ b/e2e/global-setup.ts @@ -2,7 +2,6 @@ import { FullConfig } from '@playwright/test'; import { execSync } from 'child_process'; import * as fs from 'fs'; import * as path from 'path'; -import { isServerHealthy } from './utils/supersync-helpers'; /** * Warm up the dev server by fetching the app once before any tests start. @@ -70,20 +69,6 @@ const globalSetup = async (config: FullConfig): Promise => { config.projects[0]?.use?.baseURL || 'http://localhost:4242'; await warmUpDevServer(baseURL); - - // Check SuperSync server health ONCE here, before workers start. - // Without this, each worker checks independently on startup — with many workers - // running simultaneously, the concurrent health-check requests can overload the - // supersync server and cause false negatives, making workers skip all their tests. - // By storing the result in an env var set before workers are forked, every worker - // reads the cached result instantly instead of making HTTP requests. - const healthy = await isServerHealthy().catch(() => false); - process.env.SUPERSYNC_SERVER_HEALTHY = healthy ? 'true' : 'false'; - if (healthy) { - console.log('SuperSync server healthy — supersync tests will run'); - } else { - console.log('SuperSync server not available — supersync tests will be skipped'); - } }; export default globalSetup; diff --git a/e2e/pages/supersync.page.ts b/e2e/pages/supersync.page.ts index b7a7551a93..63cec5a2d8 100644 --- a/e2e/pages/supersync.page.ts +++ b/e2e/pages/supersync.page.ts @@ -191,14 +191,8 @@ export class SuperSyncPage extends BasePage { // piggybacked ops in the response, causing data to sync between clients // outside of explicit syncAndWait(). Set here (not in createSimulatedClient) // so tests using enableWebSocket:true still get immediate uploads. - // 3. Block WsTriggeredDownloadService: Even when routeWebSocket() closes the - // connection, a WS notification can slip through the moment the connection - // opens (before it's closed). Setting __SP_E2E_BLOCK_WS_DOWNLOAD ensures - // WsTriggeredDownloadService ignores any such notifications, preventing - // uncontrolled background syncs that race with explicit syncAndWait() calls. await this.page.evaluate(() => { (globalThis as any).__SP_E2E_BLOCK_IMMEDIATE_UPLOAD = true; - (globalThis as any).__SP_E2E_BLOCK_WS_DOWNLOAD = true; }); } diff --git a/e2e/tests/sync/supersync-archive-conflict.spec.ts b/e2e/tests/sync/supersync-archive-conflict.spec.ts index 6d78366117..2b738507bb 100644 --- a/e2e/tests/sync/supersync-archive-conflict.spec.ts +++ b/e2e/tests/sync/supersync-archive-conflict.spec.ts @@ -9,7 +9,6 @@ import { renameTask, archiveDoneTasks, expectTaskInWorklog, - hasTaskInWorklog, navigateToWorkView, type SimulatedE2EClient, } from '../../utils/supersync-helpers'; @@ -268,30 +267,10 @@ test.describe('@supersync Archive Conflict Resolution', () => { console.log('[BugB] Client B: task not visible in active list'); // ============ PHASE 7: Verify task IN worklog ============ - // After archive-wins conflict + sync rounds, the archived task may appear under - // either the original title (if archive applied first) or the renamed title (if - // the rename op was also synced). Accept either to avoid brittleness. - const clientAFound = - (await hasTaskInWorklog(clientA, taskName)) || - (await hasTaskInWorklog(clientA, taskRenamed)); - if (!clientAFound) { - throw new Error( - `[BugB] Client A: Expected task to be in worklog under "${taskName}" or "${taskRenamed}"`, - ); - } + await expectTaskInWorklog(clientA, taskName); console.log('[BugB] Client A: task found in worklog'); - // Client B applied the rename locally before archive was received, so the task - // is archived under the renamed title. But also accept the original in case the - // archive was applied before the rename reached Client B. - const clientBFound = - (await hasTaskInWorklog(clientB, taskRenamed)) || - (await hasTaskInWorklog(clientB, taskName)); - if (!clientBFound) { - throw new Error( - `[BugB] Client B: Expected task to be in worklog under "${taskRenamed}" or "${taskName}"`, - ); - } + await expectTaskInWorklog(clientB, taskName); console.log('[BugB] Client B: task found in worklog'); console.log('[BugB] ✓ Test B passed: LWW Update did not resurrect archived task'); diff --git a/e2e/tests/sync/supersync.spec.ts b/e2e/tests/sync/supersync.spec.ts index 548a6470ea..b078240a3b 100644 --- a/e2e/tests/sync/supersync.spec.ts +++ b/e2e/tests/sync/supersync.spec.ts @@ -672,11 +672,8 @@ test.describe('@supersync SuperSync E2E', () => { await saveAndGoHomeBtn.click(); console.log('[Archive Test] Client B clicked Save and go home (archiving)'); - // Wait for navigation back to work view. - // Use negative lookahead to avoid matching /tag/TODAY/daily-summary prematurely. - await clientB.page.waitForURL(/(tag\/TODAY(?!\/daily-summary))/, { - timeout: 10000, - }); + // Wait for navigation back to work view + await clientB.page.waitForURL(/tag\/TODAY/, { timeout: 10000 }); await clientB.page.waitForLoadState('networkidle'); console.log('[Archive Test] Client B back on work view after archiving'); diff --git a/e2e/utils/supersync-helpers.ts b/e2e/utils/supersync-helpers.ts index af68ed6797..f824347100 100644 --- a/e2e/utils/supersync-helpers.ts +++ b/e2e/utils/supersync-helpers.ts @@ -239,34 +239,8 @@ export const createSimulatedClient = async ( } }); - // Navigate to app with retry for transient ERR_CONNECTION_REFUSED. - // Under parallel load (many workers × 2-3 browser contexts each), the Angular - // dev server can temporarily refuse connections. Retrying recovers from this - // without failing the test outright. - let lastGotoError: Error | null = null; - for (let attempt = 0; attempt < 3; attempt++) { - try { - await page.goto('/'); - lastGotoError = null; - break; - } catch (e) { - lastGotoError = e as Error; - const isConnectionRefused = lastGotoError.message.includes( - 'ERR_CONNECTION_REFUSED', - ); - if (attempt < 2 && isConnectionRefused) { - const delay = 1000 * (attempt + 1); - console.log( - `[Client ${clientName}] page.goto('/') failed (attempt ${attempt + 1}/3): ERR_CONNECTION_REFUSED — retrying in ${delay}ms`, - ); - await new Promise((r) => setTimeout(r, delay)); - } else { - break; // Non-connection error or last attempt — let it throw below - } - } - } - if (lastGotoError) throw lastGotoError; - + // Navigate to app and wait for ready + await page.goto('/'); await waitForAppReady(page); const workView = new WorkViewPage(page, `${clientName}-${testPrefix}`); @@ -527,10 +501,6 @@ export const markTaskDone = async ( const task = getTaskElement(client, taskName); await task.hover(); await task.locator('done-toggle').click(); - // Wait for the 200ms animation delay in toggleDoneWithAnimation to complete. - // During CDK drag animation the task may temporarily resolve to 2 elements; - // use .first() to avoid strict-mode violations. - await expect(task.first()).toHaveClass(/isDone/, { timeout: UI_VISIBLE_TIMEOUT }); }; /** @@ -547,8 +517,6 @@ export const markSubtaskDone = async ( const subtask = getSubtaskElement(client, subtaskName); await subtask.hover(); await subtask.locator('done-toggle').click(); - // Wait for the 200ms animation delay in toggleDoneWithAnimation to complete - await expect(subtask).toHaveClass(/isDone/, { timeout: UI_VISIBLE_TIMEOUT }); }; /** diff --git a/electron/clear-stale-idb-locks.ts b/electron/clear-stale-idb-locks.ts deleted file mode 100644 index 47138c52fa..0000000000 --- a/electron/clear-stale-idb-locks.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { join } from 'path'; -import { readdir, unlink } from 'fs/promises'; -import { log, warn } from 'electron-log/main'; - -/** - * Deletes stale LevelDB LOCK files left in the IndexedDB directory. - * - * When Electron (Chromium) exits uncleanly (e.g., session logout with autostart), - * the LevelDB LOCK files inside the IndexedDB backing stores are sometimes not - * cleaned up. On the next launch these orphaned files block IndexedDB from opening, - * producing the "Internal error opening backing store for indexedDB.open" error. - * - * This is safe to call because by the time it runs, `requestSingleInstanceLock()` - * has already ensured we are the only running instance, so no legitimate process - * can hold those locks. - * - * Only runs on Linux, where this startup race condition has been observed. - * - * @see https://github.com/electron/electron/issues/18263 - * @see https://github.com/super-productivity/super-productivity/issues/7191 - */ -export const clearStaleLevelDbLocks = async (userDataPath: string): Promise => { - if (process.platform !== 'linux') { - return; - } - - const idbDir = join(userDataPath, 'IndexedDB'); - - let entries: string[]; - try { - entries = await readdir(idbDir); - } catch (e: unknown) { - // Directory doesn't exist yet (fresh install) — nothing to clean up. - // Any other error (e.g., EACCES, EPERM) is unexpected and worth logging. - if ((e as NodeJS.ErrnoException).code !== 'ENOENT') { - warn(`[clearStaleLevelDbLocks] Could not read IndexedDB directory:`, e); - } - return; - } - - const leveldbDirs = entries.filter((e) => e.endsWith('.leveldb')); - - await Promise.all( - leveldbDirs.map(async (dir) => { - const lockPath = join(idbDir, dir, 'LOCK'); - try { - await unlink(lockPath); - log(`[clearStaleLevelDbLocks] Removed stale lock: ${lockPath}`); - } catch (e: unknown) { - // LOCK file doesn't exist or is already released — this is the normal case - if ((e as NodeJS.ErrnoException).code !== 'ENOENT') { - warn(`[clearStaleLevelDbLocks] Could not remove ${lockPath}:`, e); - } - } - }), - ); -}; diff --git a/electron/electronAPI.d.ts b/electron/electronAPI.d.ts index 3c70d155c2..7b7f906a42 100644 --- a/electron/electronAPI.d.ts +++ b/electron/electronAPI.d.ts @@ -48,7 +48,7 @@ export interface ElectronAPI { fileSyncRemove(args: { filePath: string }): Promise; - fileSyncListFiles(args: { dirPath: string }): Promise; + fileSyncListFiles(args: { dirPath: string }): Promise; // NEW checkDirExists(args: { dirPath: string }): Promise; diff --git a/electron/local-file-sync.ts b/electron/local-file-sync.ts index 63c69d0a03..100abfc7d5 100644 --- a/electron/local-file-sync.ts +++ b/electron/local-file-sync.ts @@ -112,36 +112,6 @@ export const initLocalFileSyncAdapter = (): void => { return true; } catch (e) { log('ERR: error while checking dir ' + dirPath); - if ((e as NodeJS.ErrnoException).code === 'EACCES') { - log( - 'ERR: Permission denied. If running as a snap, ensure the "home" or "removable-media" interface is connected.', - ); - } - error(e); - return e instanceof Error ? e : new Error(String(e)); - } - }, - ); - - ipcMain.handle( - IPC.FILE_SYNC_LIST_FILES, - ( - ev, - { - dirPath, - }: { - dirPath: string; - }, - ): string[] | Error => { - try { - return readdirSync(dirPath); - } catch (e) { - log('ERR: Sync error while listing files in ' + dirPath); - if ((e as NodeJS.ErrnoException).code === 'EACCES') { - log( - 'ERR: Permission denied. If running as a snap, ensure the "home" or "removable-media" interface is connected.', - ); - } error(e); return e instanceof Error ? e : new Error(String(e)); } diff --git a/electron/main-window.ts b/electron/main-window.ts index 71aa46cffb..e967e20204 100644 --- a/electron/main-window.ts +++ b/electron/main-window.ts @@ -455,7 +455,7 @@ const appCloseHandler = (app: App): void => { mainWin.on('close', (event) => { // NOTE: this might not work if we run a second instance of the app - log('close event: isQuiting=', getIsQuiting(), 'pendingBeforeCloseIds=', ids); + log('close, isQuiting:', getIsQuiting()); if (!getIsQuiting()) { event.preventDefault(); if (getIsMinimizeToTray()) { diff --git a/electron/preload.ts b/electron/preload.ts index e5ff6b287b..990dab9349 100644 --- a/electron/preload.ts +++ b/electron/preload.ts @@ -49,8 +49,8 @@ const ea: ElectronAPI = { dataStr: string | undefined; }>, fileSyncRemove: (filePath) => _invoke('FILE_SYNC_REMOVE', filePath) as Promise, - fileSyncListFiles: (args) => - _invoke('FILE_SYNC_LIST_FILES', args) as Promise, + fileSyncListFiles: ({ dirPath }) => + _invoke('FILE_SYNC_LIST_FILES', dirPath) as Promise, checkDirExists: (dirPath) => _invoke('CHECK_DIR_EXISTS', dirPath) as Promise, diff --git a/electron/shared-with-frontend/ipc-events.const.ts b/electron/shared-with-frontend/ipc-events.const.ts index 85998c2cee..b0d5ac251d 100644 --- a/electron/shared-with-frontend/ipc-events.const.ts +++ b/electron/shared-with-frontend/ipc-events.const.ts @@ -43,7 +43,7 @@ export enum IPC { FILE_SYNC_LOAD = 'FILE_SYNC_LOAD', FILE_SYNC_SAVE = 'FILE_SYNC_SAVE', FILE_SYNC_REMOVE = 'FILE_SYNC_REMOVE', - FILE_SYNC_LIST_FILES = 'FILE_SYNC_LIST_FILES', + FILE_SYNC_LIST_FILES = 'FILE_SYNC_LIST_FILES', // NEW FILE_SYNC_GET_REV_AND_CLIENT_UPDATE = 'FILE_SYNC_GET_REV_AND_CLIENT_UPDATE', CHECK_DIR_EXISTS = 'CHECK_DIR_EXISTS', diff --git a/electron/start-app.ts b/electron/start-app.ts index ff7b1d215c..d95c77f1c5 100644 --- a/electron/start-app.ts +++ b/electron/start-app.ts @@ -21,15 +21,14 @@ import { CONFIG } from './CONFIG'; import { lazySetInterval } from './shared-with-frontend/lazy-set-interval'; import { initIndicator } from './indicator'; import { quitApp, showOrFocus } from './various-shared'; -import { createWindow, getWin } from './main-window'; +import { createWindow } from './main-window'; import { IdleTimeHandler } from './idle-time-handler'; import { destroyTaskWidget } from './task-widget/task-widget'; import { initializeProtocolHandling, processPendingProtocolUrls, } from './protocol-handler'; -import { getIsQuiting, setIsQuiting, setIsLocked } from './shared-state'; -import { clearStaleLevelDbLocks } from './clear-stale-idb-locks'; +import { getIsQuiting, setIsLocked } from './shared-state'; const ICONS_FOLDER = __dirname + '/assets/icons/'; const IS_MAC = process.platform === 'darwin'; @@ -300,32 +299,18 @@ export const startApp = (): void => { appIN.on('will-quit', () => { // un-register all shortcuts. globalShortcut.unregisterAll(); - // Safe to remove IPC listeners here: all windows are closed and before-close - // IPC flows (sync, finish-day) are guaranteed to have completed. - ipcMain.removeAllListeners(); }); - appIN.on('before-quit', (event) => { - log('App before-quit: isQuiting=', getIsQuiting()); - if (!getIsQuiting()) { - // Native quit path (Cmd+Q, Dock > Quit on macOS): app.quit() was called - // by the OS without going through quitApp(), so isQuiting was never set. - // Prevent the immediate quit and delegate to the window close handler, - // which manages the before-close callback flow (sync, finish-day, etc.) - // and sets isQuiting=true before re-quitting. - event.preventDefault(); - const win = getWin(); - if (win && !win.isDestroyed()) { - win.close(); - } else { - // No window to close — set flag and re-trigger quit directly. - setIsQuiting(true); - app.quit(); - } - return; - } - // isQuiting=true: all before-close IPC work is complete — safe to clean up. + appIN.on('before-quit', () => { + log('App before-quit: cleaning up resources'); + + // Clean up task widget before quitting destroyTaskWidget(); + + // Remove all IPC listeners to prevent memory leaks + ipcMain.removeAllListeners(); + + // Clear any pending timeouts/intervals if (global.gc) { global.gc(); } @@ -383,10 +368,6 @@ export const startApp = (): void => { // eslint-disable-next-line prefer-arrow/prefer-arrow-functions async function createMainWin(): Promise { - // Remove stale LevelDB LOCK files before the renderer opens IndexedDB. - // Orphaned locks from unclean session shutdowns block the backing store open. - await clearStaleLevelDbLocks(app.getPath('userData')); - mainWin = await createWindow({ app, IS_DEV, diff --git a/package-lock.json b/package-lock.json index 57936887c5..ae63458a3c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -98,7 +98,7 @@ "cross-env": "^7.0.3", "detect-it": "^4.0.1", "dotenv": "^17.3.1", - "electron": "41.2.0", + "electron": "37.10.3", "electron-builder": "^26.7.0", "eslint": "^9.39.2", "eslint-config-prettier": "^10.1.8", @@ -645,720 +645,6 @@ "vite": "^6.0.0 || ^7.0.0" } }, - "node_modules/@angular-devkit/build-angular/node_modules/@oxc-project/types": { - "version": "0.124.0", - "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.124.0.tgz", - "integrity": "sha512-VBFWMTBvHxS11Z5Lvlr3IWgrwhMTXV+Md+EQF0Xf60+wAdsGFTBx7X7K/hP4pi8N7dcm1RvcHwDxZ16Qx8keUg==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "funding": { - "url": "https://github.com/sponsors/Boshen" - } - }, - "node_modules/@angular-devkit/build-angular/node_modules/@rolldown/binding-android-arm64": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-rc.15.tgz", - "integrity": "sha512-YYe6aWruPZDtHNpwu7+qAHEMbQ/yRl6atqb/AhznLTnD3UY99Q1jE7ihLSahNWkF4EqRPVC4SiR4O0UkLK02tA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "peer": true, - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@angular-devkit/build-angular/node_modules/@rolldown/binding-darwin-arm64": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-rc.15.tgz", - "integrity": "sha512-oArR/ig8wNTPYsXL+Mzhs0oxhxfuHRfG7Ikw7jXsw8mYOtk71W0OkF2VEVh699pdmzjPQsTjlD1JIOoHkLP1Fg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "peer": true, - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@angular-devkit/build-angular/node_modules/@rolldown/binding-darwin-x64": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-rc.15.tgz", - "integrity": "sha512-YzeVqOqjPYvUbJSWJ4EDL8ahbmsIXQpgL3JVipmN+MX0XnXMeWomLN3Fb+nwCmP/jfyqte5I3XRSm7OfQrbyxw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "peer": true, - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@angular-devkit/build-angular/node_modules/@rolldown/binding-freebsd-x64": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-rc.15.tgz", - "integrity": "sha512-9Erhx956jeQ0nNTyif1+QWAXDRD38ZNjr//bSHrt6wDwB+QkAfl2q6Mn1k6OBPerznjRmbM10lgRb1Pli4xZPw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "peer": true, - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@angular-devkit/build-angular/node_modules/@rolldown/binding-linux-arm-gnueabihf": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-rc.15.tgz", - "integrity": "sha512-cVwk0w8QbZJGTnP/AHQBs5yNwmpgGYStL88t4UIaqcvYJWBfS0s3oqVLZPwsPU6M0zlW4GqjP0Zq5MnAGwFeGA==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@angular-devkit/build-angular/node_modules/@rolldown/binding-linux-arm64-gnu": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-rc.15.tgz", - "integrity": "sha512-eBZ/u8iAK9SoHGanqe/jrPnY0JvBN6iXbVOsbO38mbz+ZJsaobExAm1Iu+rxa4S1l2FjG0qEZn4Rc6X8n+9M+w==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@angular-devkit/build-angular/node_modules/@rolldown/binding-linux-arm64-musl": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-rc.15.tgz", - "integrity": "sha512-ZvRYMGrAklV9PEkgt4LQM6MjQX2P58HPAuecwYObY2DhS2t35R0I810bKi0wmaYORt6m/2Sm+Z+nFgb0WhXNcQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@angular-devkit/build-angular/node_modules/@rolldown/binding-linux-x64-gnu": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-rc.15.tgz", - "integrity": "sha512-023bTPBod7J3Y/4fzAN6QtpkSABR0rigtrwaP+qSEabUh5zf6ELr9Nc7GujaROuPY3uwdSIXWrvhn1KxOvurWA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@angular-devkit/build-angular/node_modules/@rolldown/binding-linux-x64-musl": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-rc.15.tgz", - "integrity": "sha512-witB2O0/hU4CgfOOKUoeFgQ4GktPi1eEbAhaLAIpgD6+ZnhcPkUtPsoKKHRzmOoWPZue46IThdSgdo4XneOLYw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@angular-devkit/build-angular/node_modules/@rolldown/binding-openharmony-arm64": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-rc.15.tgz", - "integrity": "sha512-UCL68NJ0Ud5zRipXZE9dF5PmirzJE4E4BCIOOssEnM7wLDsxjc6Qb0sGDxTNRTP53I6MZpygyCpY8Aa8sPfKPg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "peer": true, - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@angular-devkit/build-angular/node_modules/@rolldown/binding-wasm32-wasi": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-rc.15.tgz", - "integrity": "sha512-ApLruZq/ig+nhaE7OJm4lDjayUnOHVUa77zGeqnqZ9pn0ovdVbbNPerVibLXDmWeUZXjIYIT8V3xkT58Rm9u5Q==", - "cpu": [ - "wasm32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "@emnapi/core": "1.9.2", - "@emnapi/runtime": "1.9.2", - "@napi-rs/wasm-runtime": "^1.1.3" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@angular-devkit/build-angular/node_modules/@rolldown/binding-win32-arm64-msvc": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-rc.15.tgz", - "integrity": "sha512-KmoUoU7HnN+Si5YWJigfTws1jz1bKBYDQKdbLspz0UaqjjFkddHsqorgiW1mxcAj88lYUE6NC/zJNwT+SloqtA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "peer": true, - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@angular-devkit/build-angular/node_modules/@rolldown/binding-win32-x64-msvc": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-rc.15.tgz", - "integrity": "sha512-3P2A8L+x75qavWLe/Dll3EYBJLQmtkJN8rfh+U/eR3MqMgL/h98PhYI+JFfXuDPgPeCB7iZAKiqii5vqOvnA0g==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "peer": true, - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@angular-devkit/build-angular/node_modules/@rolldown/pluginutils": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.15.tgz", - "integrity": "sha512-UromN0peaE53IaBRe9W7CjrZgXl90fqGpK+mIZbA3qSTeYqg3pqpROBdIPvOG3F5ereDHNwoHBI2e50n1BDr1g==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true - }, - "node_modules/@angular-devkit/build-angular/node_modules/@vitest/expect": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.4.tgz", - "integrity": "sha512-iPBpra+VDuXmBFI3FMKHSFXp3Gx5HfmSCE8X67Dn+bwephCnQCaB7qWK2ldHa+8ncN8hJU8VTMcxjPpyMkUjww==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "@standard-schema/spec": "^1.1.0", - "@types/chai": "^5.2.2", - "@vitest/spy": "4.1.4", - "@vitest/utils": "4.1.4", - "chai": "^6.2.2", - "tinyrainbow": "^3.1.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@angular-devkit/build-angular/node_modules/@vitest/pretty-format": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.4.tgz", - "integrity": "sha512-ddmDHU0gjEUyEVLxtZa7xamrpIefdEETu3nZjWtHeZX4QxqJ7tRxSteHVXJOcr8jhiLoGAhkK4WJ3WqBpjx42A==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "tinyrainbow": "^3.1.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@angular-devkit/build-angular/node_modules/@vitest/runner": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.4.tgz", - "integrity": "sha512-xTp7VZ5aXP5ZJrn15UtJUWlx6qXLnGtF6jNxHepdPHpMfz/aVPx+htHtgcAL2mDXJgKhpoo2e9/hVJsIeFbytQ==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "@vitest/utils": "4.1.4", - "pathe": "^2.0.3" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@angular-devkit/build-angular/node_modules/@vitest/snapshot": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.4.tgz", - "integrity": "sha512-MCjCFgaS8aZz+m5nTcEcgk/xhWv0rEH4Yl53PPlMXOZ1/Ka2VcZU6CJ+MgYCZbcJvzGhQRjVrGQNZqkGPttIKw==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "@vitest/pretty-format": "4.1.4", - "@vitest/utils": "4.1.4", - "magic-string": "^0.30.21", - "pathe": "^2.0.3" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@angular-devkit/build-angular/node_modules/@vitest/spy": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.4.tgz", - "integrity": "sha512-XxNdAsKW7C+FLydqFJLb5KhJtl3PGCMmYwFRfhvIgxJvLSXhhVI1zM8f1qD3Zg7RCjTSzDVyct6sghs9UEgBEQ==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@angular-devkit/build-angular/node_modules/@vitest/utils": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.4.tgz", - "integrity": "sha512-13QMT+eysM5uVGa1rG4kegGYNp6cnQcsTc67ELFbhNLQO+vgsygtYJx2khvdt4gVQqSSpC/KT5FZZxUpP3Oatw==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "@vitest/pretty-format": "4.1.4", - "convert-source-map": "^2.0.0", - "tinyrainbow": "^3.1.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@angular-devkit/build-angular/node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true - }, - "node_modules/@angular-devkit/build-angular/node_modules/es-module-lexer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.0.0.tgz", - "integrity": "sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true - }, - "node_modules/@angular-devkit/build-angular/node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "peer": true, - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/@angular-devkit/build-angular/node_modules/nanoid": { - "version": "3.3.11", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", - "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "optional": true, - "peer": true, - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/@angular-devkit/build-angular/node_modules/std-env": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.0.0.tgz", - "integrity": "sha512-zUMPtQ/HBY3/50VbpkupYHbRroTRZJPRLvreamgErJVys0ceuzMkD44J/QjqhHjOzK42GQ3QZIeFG1OYfOtKqQ==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true - }, - "node_modules/@angular-devkit/build-angular/node_modules/tinyrainbow": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.0.tgz", - "integrity": "sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@angular-devkit/build-angular/node_modules/vitest": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.4.tgz", - "integrity": "sha512-tFuJqTxKb8AvfyqMfnavXdzfy3h3sWZRWwfluGbkeR7n0HUev+FmNgZ8SDrRBTVrVCjgH5cA21qGbCffMNtWvg==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "@vitest/expect": "4.1.4", - "@vitest/mocker": "4.1.4", - "@vitest/pretty-format": "4.1.4", - "@vitest/runner": "4.1.4", - "@vitest/snapshot": "4.1.4", - "@vitest/spy": "4.1.4", - "@vitest/utils": "4.1.4", - "es-module-lexer": "^2.0.0", - "expect-type": "^1.3.0", - "magic-string": "^0.30.21", - "obug": "^2.1.1", - "pathe": "^2.0.3", - "picomatch": "^4.0.3", - "std-env": "^4.0.0-rc.1", - "tinybench": "^2.9.0", - "tinyexec": "^1.0.2", - "tinyglobby": "^0.2.15", - "tinyrainbow": "^3.1.0", - "vite": "^6.0.0 || ^7.0.0 || ^8.0.0", - "why-is-node-running": "^2.3.0" - }, - "bin": { - "vitest": "vitest.mjs" - }, - "engines": { - "node": "^20.0.0 || ^22.0.0 || >=24.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - }, - "peerDependencies": { - "@edge-runtime/vm": "*", - "@opentelemetry/api": "^1.9.0", - "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", - "@vitest/browser-playwright": "4.1.4", - "@vitest/browser-preview": "4.1.4", - "@vitest/browser-webdriverio": "4.1.4", - "@vitest/coverage-istanbul": "4.1.4", - "@vitest/coverage-v8": "4.1.4", - "@vitest/ui": "4.1.4", - "happy-dom": "*", - "jsdom": "*", - "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "@edge-runtime/vm": { - "optional": true - }, - "@opentelemetry/api": { - "optional": true - }, - "@types/node": { - "optional": true - }, - "@vitest/browser-playwright": { - "optional": true - }, - "@vitest/browser-preview": { - "optional": true - }, - "@vitest/browser-webdriverio": { - "optional": true - }, - "@vitest/coverage-istanbul": { - "optional": true - }, - "@vitest/coverage-v8": { - "optional": true - }, - "@vitest/ui": { - "optional": true - }, - "happy-dom": { - "optional": true - }, - "jsdom": { - "optional": true - }, - "vite": { - "optional": false - } - } - }, - "node_modules/@angular-devkit/build-angular/node_modules/vitest/node_modules/@vitest/mocker": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.4.tgz", - "integrity": "sha512-R9HTZBhW6yCSGbGQnDnH3QHfJxokKN4KB+Yvk9Q1le7eQNYwiCyKxmLmurSpFy6BzJanSLuEUDrD+j97Q+ZLPg==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "@vitest/spy": "4.1.4", - "estree-walker": "^3.0.3", - "magic-string": "^0.30.21" - }, - "funding": { - "url": "https://opencollective.com/vitest" - }, - "peerDependencies": { - "msw": "^2.4.9", - "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "msw": { - "optional": true - }, - "vite": { - "optional": true - } - } - }, - "node_modules/@angular-devkit/build-angular/node_modules/vitest/node_modules/picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/@angular-devkit/build-angular/node_modules/vitest/node_modules/postcss": { - "version": "8.5.9", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.9.tgz", - "integrity": "sha512-7a70Nsot+EMX9fFU3064K/kdHWZqGVY+BADLyXc8Dfv+mTLLVl6JzJpPaCZ2kQL9gIJvKXSLMHhqdRRjwQeFtw==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "nanoid": "^3.3.11", - "picocolors": "^1.1.1", - "source-map-js": "^1.2.1" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/@angular-devkit/build-angular/node_modules/vitest/node_modules/rolldown": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-rc.15.tgz", - "integrity": "sha512-Ff31guA5zT6WjnGp0SXw76X6hzGRk/OQq2hE+1lcDe+lJdHSgnSX6nK3erbONHyCbpSj9a9E+uX/OvytZoWp2g==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "@oxc-project/types": "=0.124.0", - "@rolldown/pluginutils": "1.0.0-rc.15" - }, - "bin": { - "rolldown": "bin/cli.mjs" - }, - "engines": { - "node": "^20.19.0 || >=22.12.0" - }, - "optionalDependencies": { - "@rolldown/binding-android-arm64": "1.0.0-rc.15", - "@rolldown/binding-darwin-arm64": "1.0.0-rc.15", - "@rolldown/binding-darwin-x64": "1.0.0-rc.15", - "@rolldown/binding-freebsd-x64": "1.0.0-rc.15", - "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.15", - "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.15", - "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.15", - "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.15", - "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.15", - "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.15", - "@rolldown/binding-linux-x64-musl": "1.0.0-rc.15", - "@rolldown/binding-openharmony-arm64": "1.0.0-rc.15", - "@rolldown/binding-wasm32-wasi": "1.0.0-rc.15", - "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.15", - "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.15" - } - }, - "node_modules/@angular-devkit/build-angular/node_modules/vitest/node_modules/vite": { - "version": "8.0.8", - "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.8.tgz", - "integrity": "sha512-dbU7/iLVa8KZALJyLOBOQ88nOXtNG8vxKuOT4I2mD+Ya70KPceF4IAmDsmU0h1Qsn5bPrvsY9HJstCRh3hG6Uw==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "lightningcss": "^1.32.0", - "picomatch": "^4.0.4", - "postcss": "^8.5.8", - "rolldown": "1.0.0-rc.15", - "tinyglobby": "^0.2.15" - }, - "bin": { - "vite": "bin/vite.js" - }, - "engines": { - "node": "^20.19.0 || >=22.12.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - }, - "peerDependencies": { - "@types/node": "^20.19.0 || >=22.12.0", - "@vitejs/devtools": "^0.1.0", - "esbuild": "^0.27.0 || ^0.28.0", - "jiti": ">=1.21.0", - "less": "^4.0.0", - "sass": "^1.70.0", - "sass-embedded": "^1.70.0", - "stylus": ">=0.54.8", - "sugarss": "^5.0.0", - "terser": "^5.16.0", - "tsx": "^4.8.1", - "yaml": "^2.4.2" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "@vitejs/devtools": { - "optional": true - }, - "esbuild": { - "optional": true - }, - "jiti": { - "optional": true - }, - "less": { - "optional": true - }, - "sass": { - "optional": true - }, - "sass-embedded": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - }, - "tsx": { - "optional": true - }, - "yaml": { - "optional": true - } - } - }, "node_modules/@angular-devkit/build-webpack": { "version": "0.2102.3", "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.2102.3.tgz", @@ -1408,13 +694,13 @@ } }, "node_modules/@angular-devkit/schematics": { - "version": "21.2.7", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-21.2.7.tgz", - "integrity": "sha512-LYAjjUI1qM7pR/sd0yYt8OLA6ljOOXjcfzV40I5XQNmhAxq90YYS5xwMcixOmWX+z5zvCYGvPXvJGWjzio6SUg==", + "version": "21.2.3", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-21.2.3.tgz", + "integrity": "sha512-tc/bBloRTVIBWGRiMPln1QbW+2QPj+YnWL/nG79abLKWkdrL9dJLcCRXY7dsPNrxOc/QF+8tVpnr8JofhWL9cQ==", "dev": true, "license": "MIT", "dependencies": { - "@angular-devkit/core": "21.2.7", + "@angular-devkit/core": "21.2.3", "jsonc-parser": "3.3.1", "magic-string": "0.30.21", "ora": "9.3.0", @@ -1426,47 +712,6 @@ "yarn": ">= 1.13.0" } }, - "node_modules/@angular-devkit/schematics/node_modules/@angular-devkit/core": { - "version": "21.2.7", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-21.2.7.tgz", - "integrity": "sha512-DONYY5u4IENO2qpd23mODaE4JI2EIohWV1kuJnsU9HIcm5wN714QB2z9WY/s4gLfUiAMIUu/8lpnW/0kOQZAnQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "8.18.0", - "ajv-formats": "3.0.1", - "jsonc-parser": "3.3.1", - "picomatch": "4.0.4", - "rxjs": "7.8.2", - "source-map": "0.7.6" - }, - "engines": { - "node": "^20.19.0 || ^22.12.0 || >=24.0.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - }, - "peerDependencies": { - "chokidar": "^5.0.0" - }, - "peerDependenciesMeta": { - "chokidar": { - "optional": true - } - } - }, - "node_modules/@angular-devkit/schematics/node_modules/picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/@angular-eslint/builder": { "version": "21.3.1", "resolved": "https://registry.npmjs.org/@angular-eslint/builder/-/builder-21.3.1.tgz", @@ -1610,19 +855,19 @@ } }, "node_modules/@angular/cli": { - "version": "21.2.7", - "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-21.2.7.tgz", - "integrity": "sha512-N/wj8fFRB718efIFYpwnYfy+MecZREZXsUNMTVndFLH6T0jCheb9PVetR6jsyZp6h46USNPOmJYJ/9255lME+Q==", + "version": "21.2.3", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-21.2.3.tgz", + "integrity": "sha512-QzDxnSy8AUOz6ca92xfbNuEmRdWRDi1dfFkxDVr+4l6XUnA9X6VmOi7ioCO1I9oDR73LXHybOqkqHBYDlqt/Ag==", "dev": true, "license": "MIT", "dependencies": { - "@angular-devkit/architect": "0.2102.7", - "@angular-devkit/core": "21.2.7", - "@angular-devkit/schematics": "21.2.7", + "@angular-devkit/architect": "0.2102.3", + "@angular-devkit/core": "21.2.3", + "@angular-devkit/schematics": "21.2.3", "@inquirer/prompts": "7.10.1", "@listr2/prompt-adapter-inquirer": "3.0.5", "@modelcontextprotocol/sdk": "1.26.0", - "@schematics/angular": "21.2.7", + "@schematics/angular": "21.2.3", "@yarnpkg/lockfile": "1.1.0", "algoliasearch": "5.48.1", "ini": "6.0.0", @@ -1644,66 +889,6 @@ "yarn": ">= 1.13.0" } }, - "node_modules/@angular/cli/node_modules/@angular-devkit/architect": { - "version": "0.2102.7", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.2102.7.tgz", - "integrity": "sha512-4K/5hln9iaPEt3F/NyYqncNLvYpzSjRslEkHl2xIgZwQsIFHEvhnDRBYj2/oatURQhBqO/Yu15z/icVOYLxuTg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@angular-devkit/core": "21.2.7", - "rxjs": "7.8.2" - }, - "bin": { - "architect": "bin/cli.js" - }, - "engines": { - "node": "^20.19.0 || ^22.12.0 || >=24.0.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - } - }, - "node_modules/@angular/cli/node_modules/@angular-devkit/core": { - "version": "21.2.7", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-21.2.7.tgz", - "integrity": "sha512-DONYY5u4IENO2qpd23mODaE4JI2EIohWV1kuJnsU9HIcm5wN714QB2z9WY/s4gLfUiAMIUu/8lpnW/0kOQZAnQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "8.18.0", - "ajv-formats": "3.0.1", - "jsonc-parser": "3.3.1", - "picomatch": "4.0.4", - "rxjs": "7.8.2", - "source-map": "0.7.6" - }, - "engines": { - "node": "^20.19.0 || ^22.12.0 || >=24.0.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - }, - "peerDependencies": { - "chokidar": "^5.0.0" - }, - "peerDependenciesMeta": { - "chokidar": { - "optional": true - } - } - }, - "node_modules/@angular/cli/node_modules/picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/@angular/common": { "version": "21.2.5", "resolved": "https://registry.npmjs.org/@angular/common/-/common-21.2.5.tgz", @@ -3902,48 +3087,50 @@ } }, "node_modules/@chevrotain/cst-dts-gen": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/@chevrotain/cst-dts-gen/-/cst-dts-gen-12.0.0.tgz", - "integrity": "sha512-fSL4KXjTl7cDgf0B5Rip9Q05BOrYvkJV/RrBTE/bKDN096E4hN/ySpcBK5B24T76dlQ2i32Zc3PAE27jFnFrKg==", + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/@chevrotain/cst-dts-gen/-/cst-dts-gen-11.1.2.tgz", + "integrity": "sha512-XTsjvDVB5nDZBQB8o0o/0ozNelQtn2KrUVteIHSlPd2VAV2utEb6JzyCJaJ8tGxACR4RiBNWy5uYUHX2eji88Q==", "dev": true, "license": "Apache-2.0", "optional": true, "dependencies": { - "@chevrotain/gast": "12.0.0", - "@chevrotain/types": "12.0.0" + "@chevrotain/gast": "11.1.2", + "@chevrotain/types": "11.1.2", + "lodash-es": "4.17.23" } }, "node_modules/@chevrotain/gast": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/@chevrotain/gast/-/gast-12.0.0.tgz", - "integrity": "sha512-1ne/m3XsIT8aEdrvT33so0GUC+wkctpUPK6zU9IlOyJLUbR0rg4G7ZiApiJbggpgPir9ERy3FRjT6T7lpgetnQ==", + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/@chevrotain/gast/-/gast-11.1.2.tgz", + "integrity": "sha512-Z9zfXR5jNZb1Hlsd/p+4XWeUFugrHirq36bKzPWDSIacV+GPSVXdk+ahVWZTwjhNwofAWg/sZg58fyucKSQx5g==", "dev": true, "license": "Apache-2.0", "optional": true, "dependencies": { - "@chevrotain/types": "12.0.0" + "@chevrotain/types": "11.1.2", + "lodash-es": "4.17.23" } }, "node_modules/@chevrotain/regexp-to-ast": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/@chevrotain/regexp-to-ast/-/regexp-to-ast-12.0.0.tgz", - "integrity": "sha512-p+EW9MaJwgaHguhoqwOtx/FwuGr+DnNn857sXWOi/mClXIkPGl3rn7hGNWvo31HA3vyeQxjqe+H36yZJwYU8cA==", + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/@chevrotain/regexp-to-ast/-/regexp-to-ast-11.1.2.tgz", + "integrity": "sha512-nMU3Uj8naWer7xpZTYJdxbAs6RIv/dxYzkYU8GSwgUtcAAlzjcPfX1w+RKRcYG8POlzMeayOQ/znfwxEGo5ulw==", "dev": true, "license": "Apache-2.0", "optional": true }, "node_modules/@chevrotain/types": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/@chevrotain/types/-/types-12.0.0.tgz", - "integrity": "sha512-S+04vjFQKeuYw0/eW3U52LkAHQsB1ASxsPGsLPUyQgrZ2iNNibQrsidruDzjEX2JYfespXMG0eZmXlhA6z7nWA==", + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/@chevrotain/types/-/types-11.1.2.tgz", + "integrity": "sha512-U+HFai5+zmJCkK86QsaJtoITlboZHBqrVketcO2ROv865xfCMSFpELQoz1GkX5GzME8pTa+3kbKrZHQtI0gdbw==", "dev": true, "license": "Apache-2.0", "optional": true }, "node_modules/@chevrotain/utils": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/@chevrotain/utils/-/utils-12.0.0.tgz", - "integrity": "sha512-lB59uJoaGIfOOL9knQqQRfhl9g7x8/wqFkp13zTdkRu1huG9kg6IJs1O8hqj9rs6h7orGxHJUKb+mX3rPbWGhA==", + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/@chevrotain/utils/-/utils-11.1.2.tgz", + "integrity": "sha512-4mudFAQ6H+MqBTfqLmU7G1ZwRzCLfJEooL/fsF6rCX5eePMbGhoy5n4g+G4vlh2muDcsCTJtL+uKbOzWxs5LHA==", "dev": true, "license": "Apache-2.0", "optional": true @@ -4263,24 +3450,6 @@ "node": ">=10.12.0" } }, - "node_modules/@electron/asar/node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@electron/asar/node_modules/brace-expansion": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", - "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, "node_modules/@electron/asar/node_modules/commander": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", @@ -4314,16 +3483,19 @@ } }, "node_modules/@electron/asar/node_modules/minimatch": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", - "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz", + "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==", "dev": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^1.1.7" + "@isaacs/brace-expansion": "^5.0.0" }, "engines": { - "node": "*" + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/@electron/fuses": { @@ -4740,6 +3912,22 @@ "node": ">=16.4" } }, + "node_modules/@electron/universal/node_modules/minimatch": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz", + "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/brace-expansion": "^5.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@electron/windows-sign": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/@electron/windows-sign/-/windows-sign-1.2.2.tgz", @@ -4763,38 +3951,35 @@ } }, "node_modules/@emnapi/core": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.9.2.tgz", - "integrity": "sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA==", + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.9.1.tgz", + "integrity": "sha512-mukuNALVsoix/w1BJwFzwXBN/dHeejQtuVzcDsfOEsdpCumXb/E9j8w11h5S54tT1xhifGfbbSm/ICrObRb3KA==", "dev": true, "license": "MIT", "optional": true, - "peer": true, "dependencies": { - "@emnapi/wasi-threads": "1.2.1", + "@emnapi/wasi-threads": "1.2.0", "tslib": "^2.4.0" } }, "node_modules/@emnapi/runtime": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.9.2.tgz", - "integrity": "sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw==", + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.9.1.tgz", + "integrity": "sha512-VYi5+ZVLhpgK4hQ0TAjiQiZ6ol0oe4mBx7mVv7IflsiEp0OWoVsp/+f9Vc1hOhE0TtkORVrI1GvzyreqpgWtkA==", "dev": true, "license": "MIT", "optional": true, - "peer": true, "dependencies": { "tslib": "^2.4.0" } }, "node_modules/@emnapi/wasi-threads": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", - "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.0.tgz", + "integrity": "sha512-N10dEJNSsUx41Z6pZsXU8FjPjpBEplgH24sfkmITrBED1/U2Esum9F3lfLrMjKHHjmi557zQn7kR9R+XWXu5Rg==", "dev": true, "license": "MIT", "optional": true, - "peer": true, "dependencies": { "tslib": "^2.4.0" } @@ -5892,9 +5077,9 @@ "license": "MIT" }, "node_modules/@hono/node-server": { - "version": "1.19.14", - "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.14.tgz", - "integrity": "sha512-GwtvgtXxnWsucXvbQXkRgqksiH2Qed37H9xHZocE5sA3N8O8O8/8FA3uclQXxXVzc9XBZuEOMK7+r02FmSpHtw==", + "version": "1.19.11", + "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.11.tgz", + "integrity": "sha512-dr8/3zEaB+p0D2n/IUrlPF1HZm586qgJNXK1a9fhg/PzdtkK7Ksd5l312tJX2yBuALqDYBlG20QEbayqPyxn+g==", "dev": true, "license": "MIT", "engines": { @@ -7748,22 +6933,20 @@ } }, "node_modules/@napi-rs/wasm-runtime": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.3.tgz", - "integrity": "sha512-xK9sGVbJWYb08+mTJt3/YV24WxvxpXcXtP6B172paPZ+Ts69Re9dAr7lKwJoeIx8OoeuimEiRZ7umkiUVClmmQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.1.tgz", + "integrity": "sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A==", "dev": true, "license": "MIT", "optional": true, "dependencies": { + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1", "@tybys/wasm-util": "^0.10.1" }, "funding": { "type": "github", "url": "https://github.com/sponsors/Brooooooklyn" - }, - "peerDependencies": { - "@emnapi/core": "^1.7.1", - "@emnapi/runtime": "^1.7.1" } }, "node_modules/@nextcloud/cdav-library": { @@ -9174,42 +8357,6 @@ "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@rolldown/binding-linux-ppc64-gnu": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.0-rc.15.tgz", - "integrity": "sha512-VDpgGBzgfg5hLg+uBpCLoFG5kVvEyafmfxGUV0UHLcL5irxAK7PKNeC2MwClgk6ZAiNhmo9FLhRYgvMmedLtnQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-linux-s390x-gnu": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.0-rc.15.tgz", - "integrity": "sha512-y1uXY3qQWCzcPgRJATPSOUP4tCemh4uBdY7e3EZbVwCJTY3gLJWnQABgeUetvED+bt1FQ01OeZwvhLS2bpNrAQ==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, "node_modules/@rolldown/binding-linux-x64-gnu": { "version": "1.0.0-rc.4", "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-rc.4.tgz", @@ -9681,14 +8828,14 @@ "license": "MIT" }, "node_modules/@schematics/angular": { - "version": "21.2.7", - "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-21.2.7.tgz", - "integrity": "sha512-aqEj3RyBtmH+41HZvrbfrpCo0e+0NzwyQyNSC/wLDShVqoidBtPbEdHU1FZ4+ni41da7rI3F12gUuAHws27kMA==", + "version": "21.2.3", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-21.2.3.tgz", + "integrity": "sha512-rCEprgpNbJLl9Rm/t92eRYc1eIqD4BAJqB1OO8fzQolyDajCcOBpohjXkuLYSwK9RMyS6f+szNnYGOQawlrPYw==", "dev": true, "license": "MIT", "dependencies": { - "@angular-devkit/core": "21.2.7", - "@angular-devkit/schematics": "21.2.7", + "@angular-devkit/core": "21.2.3", + "@angular-devkit/schematics": "21.2.3", "jsonc-parser": "3.3.1" }, "engines": { @@ -9697,47 +8844,6 @@ "yarn": ">= 1.13.0" } }, - "node_modules/@schematics/angular/node_modules/@angular-devkit/core": { - "version": "21.2.7", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-21.2.7.tgz", - "integrity": "sha512-DONYY5u4IENO2qpd23mODaE4JI2EIohWV1kuJnsU9HIcm5wN714QB2z9WY/s4gLfUiAMIUu/8lpnW/0kOQZAnQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "8.18.0", - "ajv-formats": "3.0.1", - "jsonc-parser": "3.3.1", - "picomatch": "4.0.4", - "rxjs": "7.8.2", - "source-map": "0.7.6" - }, - "engines": { - "node": "^20.19.0 || ^22.12.0 || >=24.0.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - }, - "peerDependencies": { - "chokidar": "^5.0.0" - }, - "peerDependenciesMeta": { - "chokidar": { - "optional": true - } - } - }, - "node_modules/@schematics/angular/node_modules/picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/@sigstore/bundle": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@sigstore/bundle/-/bundle-4.0.0.tgz", @@ -11944,9 +11050,9 @@ "license": "MIT" }, "node_modules/app-builder-lib": { - "version": "26.9.0", - "resolved": "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-26.9.0.tgz", - "integrity": "sha512-f/1GhVrDfBH7sSzhAwiXa1rpR/7pB7Av5woUjmt+QYE0QyNvrOAiY05rngtR/PK4/1BzS6/zVoYobIwDAsrtBA==", + "version": "26.8.1", + "resolved": "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-26.8.1.tgz", + "integrity": "sha512-p0Im/Dx5C4tmz8QEE1Yn4MkuPC8PrnlRneMhWJj7BBXQfNTJUshM/bp3lusdEsDbvvfJZpXWnYesgSLvwtM2Zw==", "dev": true, "license": "MIT", "dependencies": { @@ -11961,15 +11067,15 @@ "@malept/flatpak-bundler": "^0.4.0", "@types/fs-extra": "9.0.13", "async-exit-hook": "^2.0.1", - "builder-util": "26.9.0", - "builder-util-runtime": "9.6.0", + "builder-util": "26.8.1", + "builder-util-runtime": "9.5.1", "chromium-pickle-js": "^0.2.0", "ci-info": "4.3.1", "debug": "^4.3.4", "dotenv": "^16.4.5", "dotenv-expand": "^11.0.6", "ejs": "^3.1.8", - "electron-publish": "26.9.0", + "electron-publish": "26.8.1", "fs-extra": "^10.1.0", "hosted-git-info": "^4.1.0", "isbinaryfile": "^5.0.0", @@ -11991,8 +11097,8 @@ "node": ">=14.0.0" }, "peerDependencies": { - "dmg-builder": "26.9.0", - "electron-builder-squirrel-windows": "26.9.0" + "dmg-builder": "26.8.1", + "electron-builder-squirrel-windows": "26.8.1" } }, "node_modules/app-builder-lib/node_modules/@electron/get": { @@ -12189,6 +11295,22 @@ "node": ">=18" } }, + "node_modules/app-builder-lib/node_modules/minimatch": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz", + "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/brace-expansion": "^5.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/app-builder-lib/node_modules/which": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", @@ -12564,15 +11686,15 @@ } }, "node_modules/axios": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.15.0.tgz", - "integrity": "sha512-wWyJDlAatxk30ZJer+GeCWS209sA42X+N5jU2jy6oHTp7ufw8uzUTVFBX9+wTfAlhiJXGS0Bq7X6efruWjuK9Q==", + "version": "1.13.6", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.6.tgz", + "integrity": "sha512-ChTCHMouEe2kn713WHbQGcuYrr6fXTBiu460OTwWrWob16g1bXn4vtz07Ope7ewMozJAnEquLk5lWQWtBig9DQ==", "dev": true, "license": "MIT", "dependencies": { "follow-redirects": "^1.15.11", "form-data": "^4.0.5", - "proxy-from-env": "^2.1.0" + "proxy-from-env": "^1.1.0" } }, "node_modules/axobject-query": { @@ -12989,16 +12111,16 @@ "license": "MIT" }, "node_modules/builder-util": { - "version": "26.9.0", - "resolved": "https://registry.npmjs.org/builder-util/-/builder-util-26.9.0.tgz", - "integrity": "sha512-+eocmbdisnyb40B9nAp/KREfYLXvGagxV50KZv/Zh4aflsr1fdY9Qxs6QG1Jtx1vH5d5NQ3hIcemUi4RSlFK/Q==", + "version": "26.8.1", + "resolved": "https://registry.npmjs.org/builder-util/-/builder-util-26.8.1.tgz", + "integrity": "sha512-pm1lTYbGyc90DHgCDO7eo8Rl4EqKLciayNbZqGziqnH9jrlKe8ZANGdityLZU+pJh16dfzjAx2xQq9McuIPEtw==", "dev": true, "license": "MIT", "dependencies": { "@types/debug": "^4.1.6", "7zip-bin": "~5.2.0", "app-builder-bin": "5.0.0-alpha.12", - "builder-util-runtime": "9.6.0", + "builder-util-runtime": "9.5.1", "chalk": "^4.1.2", "cross-spawn": "^7.0.6", "debug": "^4.3.4", @@ -13014,9 +12136,9 @@ } }, "node_modules/builder-util-runtime": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.6.0.tgz", - "integrity": "sha512-k9V5I18PXLepLZ8jVmPzsH+gVCVZ+9aMVLyCZ0ZLOkT2KSyiBblDCCN8WxDbjOpfLGNHZqqJPBmW0HYeqxlgkQ==", + "version": "9.5.1", + "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.5.1.tgz", + "integrity": "sha512-qt41tMfgHTllhResqM5DcnHyDIWNgzHvuY2jDcYP9iaGpkWxTUzV6GQjDeLnlR1/DtdlcsWQbA7sByMpmJFTLQ==", "dev": true, "license": "MIT", "dependencies": { @@ -13185,23 +12307,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/cacache/node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true, - "license": "MIT" - }, - "node_modules/cacache/node_modules/brace-expansion": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.0.tgz", - "integrity": "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, "node_modules/cacache/node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", @@ -13231,22 +12336,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/cacache/node_modules/glob/node_modules/minimatch": { - "version": "9.0.9", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", - "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.2" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/cacache/node_modules/jackspeak": { "version": "3.4.3", "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", @@ -13270,6 +12359,22 @@ "dev": true, "license": "ISC" }, + "node_modules/cacache/node_modules/minimatch": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz", + "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/brace-expansion": "^5.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/cacache/node_modules/path-scurry": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", @@ -13561,27 +12666,25 @@ } }, "node_modules/chevrotain": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-12.0.0.tgz", - "integrity": "sha512-csJvb+6kEiQaqo1woTdSAuOWdN0WTLIydkKrBnS+V5gZz0oqBrp4kQ35519QgK6TpBThiG3V1vNSHlIkv4AglQ==", + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-11.1.2.tgz", + "integrity": "sha512-opLQzEVriiH1uUQ4Kctsd49bRoFDXGGSC4GUqj7pGyxM3RehRhvTlZJc1FL/Flew2p5uwxa1tUDWKzI4wNM8pg==", "dev": true, "license": "Apache-2.0", "optional": true, "dependencies": { - "@chevrotain/cst-dts-gen": "12.0.0", - "@chevrotain/gast": "12.0.0", - "@chevrotain/regexp-to-ast": "12.0.0", - "@chevrotain/types": "12.0.0", - "@chevrotain/utils": "12.0.0" - }, - "engines": { - "node": ">=22.0.0" + "@chevrotain/cst-dts-gen": "11.1.2", + "@chevrotain/gast": "11.1.2", + "@chevrotain/regexp-to-ast": "11.1.2", + "@chevrotain/types": "11.1.2", + "@chevrotain/utils": "11.1.2", + "lodash-es": "4.17.23" } }, "node_modules/chevrotain-allstar": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/chevrotain-allstar/-/chevrotain-allstar-0.4.1.tgz", - "integrity": "sha512-PvVJm3oGqrveUVW2Vt/eZGeiAIsJszYweUcYwcskg9e+IubNYKKD+rHHem7A6XVO22eDAL+inxNIGAzZ/VIWlA==", + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/chevrotain-allstar/-/chevrotain-allstar-0.3.1.tgz", + "integrity": "sha512-b7g+y9A0v4mxCW1qUhf3BSVPg+/NvGErk/dOkrDaHA0nQIQGAtrOjlX//9OQtRlSCy+x9rfB5N8yC71lH1nvMw==", "dev": true, "license": "MIT", "optional": true, @@ -13589,7 +12692,7 @@ "lodash-es": "^4.17.21" }, "peerDependencies": { - "chevrotain": "^12.0.0" + "chevrotain": "^11.0.0" } }, "node_modules/chokidar": { @@ -15533,6 +14636,22 @@ "p-limit": "^3.1.0 " } }, + "node_modules/dir-compare/node_modules/minimatch": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz", + "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/brace-expansion": "^5.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -15547,14 +14666,14 @@ } }, "node_modules/dmg-builder": { - "version": "26.9.0", - "resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-26.9.0.tgz", - "integrity": "sha512-5uSyg0yY+JRMMGwFjIweaukYkCGcZSZwvH5VPlBHiKkTEP1a1/uV+bs4y+VAxPMgzg67YB4CF1vD4U/2d3chfg==", + "version": "26.8.1", + "resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-26.8.1.tgz", + "integrity": "sha512-glMJgnTreo8CFINujtAhCgN96QAqApDMZ8Vl1r8f0QT8QprvC1UCltV4CcWj20YoIyLZx6IUskaJZ0NV8fokcg==", "dev": true, "license": "MIT", "dependencies": { - "app-builder-lib": "26.9.0", - "builder-util": "26.9.0", + "app-builder-lib": "26.8.1", + "builder-util": "26.8.1", "fs-extra": "^10.1.0", "iconv-lite": "^0.6.2", "js-yaml": "^4.1.0" @@ -15885,15 +15004,15 @@ } }, "node_modules/electron": { - "version": "41.2.0", - "resolved": "https://registry.npmjs.org/electron/-/electron-41.2.0.tgz", - "integrity": "sha512-0OKLiymqfV0WK68RBXqAm3Myad2TpI5wwxLCBEUcH5Nugo3YfSk7p1Js/AL9266qTz5xZioUnxt9hG8FFwax0g==", + "version": "37.10.3", + "resolved": "https://registry.npmjs.org/electron/-/electron-37.10.3.tgz", + "integrity": "sha512-3IjCGSjQmH50IbW2PFveaTzK+KwcFX9PEhE7KXb9v5IT8cLAiryAN7qezm/XzODhDRlLu0xKG1j8xWBtZ/bx/g==", "dev": true, "hasInstallScript": true, "license": "MIT", "dependencies": { "@electron/get": "^2.0.0", - "@types/node": "^24.9.0", + "@types/node": "^22.7.7", "extract-zip": "^2.0.1" }, "bin": { @@ -15904,18 +15023,18 @@ } }, "node_modules/electron-builder": { - "version": "26.9.0", - "resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-26.9.0.tgz", - "integrity": "sha512-7BEeGz8Xlk7Qvitj70nGAQaq7WQIZ2amsDvsyKSZbxgtL2pM9fm/woZrtn0hoID6Fl7wkn456dK3OmtFNzgiOA==", + "version": "26.8.1", + "resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-26.8.1.tgz", + "integrity": "sha512-uWhx1r74NGpCagG0ULs/P9Nqv2nsoo+7eo4fLUOB8L8MdWltq9odW/uuLXMFCDGnPafknYLZgjNX0ZIFRzOQAw==", "dev": true, "license": "MIT", "dependencies": { - "app-builder-lib": "26.9.0", - "builder-util": "26.9.0", - "builder-util-runtime": "9.6.0", + "app-builder-lib": "26.8.1", + "builder-util": "26.8.1", + "builder-util-runtime": "9.5.1", "chalk": "^4.1.2", "ci-info": "^4.2.0", - "dmg-builder": "26.9.0", + "dmg-builder": "26.8.1", "fs-extra": "^10.1.0", "lazy-val": "^1.0.5", "simple-update-notifier": "2.0.0", @@ -15930,15 +15049,15 @@ } }, "node_modules/electron-builder-squirrel-windows": { - "version": "26.9.0", - "resolved": "https://registry.npmjs.org/electron-builder-squirrel-windows/-/electron-builder-squirrel-windows-26.9.0.tgz", - "integrity": "sha512-Jzsxa3Kjv94ZRZDK7pc8bzu5iglwGsDOBMWTqLpWx2sCEvb3TLW9PMWqOjpDwizqkMBp8GjP6rceLzQYLFIVow==", + "version": "26.8.1", + "resolved": "https://registry.npmjs.org/electron-builder-squirrel-windows/-/electron-builder-squirrel-windows-26.8.1.tgz", + "integrity": "sha512-o288fIdgPLHA76eDrFADHPoo7VyGkDCYbLV1GzndaMSAVBoZrGvM9m2IehdcVMzdAZJ2eV9bgyissQXHv5tGzA==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "app-builder-lib": "26.9.0", - "builder-util": "26.9.0", + "app-builder-lib": "26.8.1", + "builder-util": "26.8.1", "electron-winstaller": "5.4.0" } }, @@ -16077,15 +15196,15 @@ } }, "node_modules/electron-publish": { - "version": "26.9.0", - "resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-26.9.0.tgz", - "integrity": "sha512-gsy+U7JfDuD1lPOrCXeECDQoUsWjFah3s1Fv3pqKnjdJuKYDDvGdvC74kLHVG6nl5G0uQ7YN0eftCQ4rUmhvVw==", + "version": "26.8.1", + "resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-26.8.1.tgz", + "integrity": "sha512-q+jrSTIh/Cv4eGZa7oVR+grEJo/FoLMYBAnSL5GCtqwUpr1T+VgKB/dn1pnzxIxqD8S/jP1yilT9VrwCqINR4w==", "dev": true, "license": "MIT", "dependencies": { "@types/fs-extra": "^9.0.11", - "builder-util": "26.9.0", - "builder-util-runtime": "9.6.0", + "builder-util": "26.8.1", + "builder-util-runtime": "9.5.1", "chalk": "^4.1.2", "form-data": "^4.0.5", "fs-extra": "^10.1.0", @@ -16213,23 +15332,6 @@ "node": ">= 4.0.0" } }, - "node_modules/electron/node_modules/@types/node": { - "version": "24.12.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.12.2.tgz", - "integrity": "sha512-A1sre26ke7HDIuY/M23nd9gfB+nrmhtYyMINbjI1zHJxYteKR6qSMX56FsmjMcDb3SMcjJg5BiRRgOCC/yBD0g==", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~7.16.0" - } - }, - "node_modules/electron/node_modules/undici-types": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", - "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", - "dev": true, - "license": "MIT" - }, "node_modules/elementtree": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/elementtree/-/elementtree-0.1.7.tgz", @@ -17893,6 +16995,22 @@ "minimatch": "^5.0.1" } }, + "node_modules/filelist/node_modules/minimatch": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz", + "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/brace-expansion": "^5.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", @@ -18013,9 +17131,9 @@ "license": "ISC" }, "node_modules/follow-redirects": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz", - "integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==", + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", "dev": true, "funding": [ { @@ -18794,9 +17912,9 @@ } }, "node_modules/hono": { - "version": "4.12.12", - "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.12.tgz", - "integrity": "sha512-p1JfQMKaceuCbpJKAPKVqyqviZdS0eUxH9v82oWo1kb9xjQ5wA6iP3FNVAPDFlz5/p7d45lO+BpSk1tuSZMF4Q==", + "version": "4.12.9", + "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.9.tgz", + "integrity": "sha512-wy3T8Zm2bsEvxKZM5w21VdHDDcwVS1yUFFY6i8UobSsKfFceT7TOwhbhfKsDyx7tYQlmRM5FLpIuYvNFyjctiA==", "dev": true, "license": "MIT", "engines": { @@ -21361,16 +20479,15 @@ "license": "MIT" }, "node_modules/langium": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/langium/-/langium-4.2.2.tgz", - "integrity": "sha512-JUshTRAfHI4/MF9dH2WupvjSXyn8JBuUEWazB8ZVJUtXutT0doDlAv1XKbZ1Pb5sMexa8FF4CFBc0iiul7gbUQ==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/langium/-/langium-4.2.1.tgz", + "integrity": "sha512-zu9QWmjpzJcomzdJQAHgDVhLGq5bLosVak1KVa40NzQHXfqr4eAHupvnPOVXEoLkg6Ocefvf/93d//SB7du4YQ==", "dev": true, "license": "MIT", "optional": true, "dependencies": { - "@chevrotain/regexp-to-ast": "~12.0.0", - "chevrotain": "~12.0.0", - "chevrotain-allstar": "~0.4.1", + "chevrotain": "~11.1.1", + "chevrotain-allstar": "~0.3.1", "vscode-languageserver": "~9.0.1", "vscode-languageserver-textdocument": "~1.0.11", "vscode-uri": "~3.1.0" @@ -21603,280 +20720,6 @@ ], "license": "MIT" }, - "node_modules/lightningcss": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", - "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==", - "dev": true, - "license": "MPL-2.0", - "optional": true, - "peer": true, - "dependencies": { - "detect-libc": "^2.0.3" - }, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - }, - "optionalDependencies": { - "lightningcss-android-arm64": "1.32.0", - "lightningcss-darwin-arm64": "1.32.0", - "lightningcss-darwin-x64": "1.32.0", - "lightningcss-freebsd-x64": "1.32.0", - "lightningcss-linux-arm-gnueabihf": "1.32.0", - "lightningcss-linux-arm64-gnu": "1.32.0", - "lightningcss-linux-arm64-musl": "1.32.0", - "lightningcss-linux-x64-gnu": "1.32.0", - "lightningcss-linux-x64-musl": "1.32.0", - "lightningcss-win32-arm64-msvc": "1.32.0", - "lightningcss-win32-x64-msvc": "1.32.0" - } - }, - "node_modules/lightningcss-android-arm64": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz", - "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "android" - ], - "peer": true, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-darwin-arm64": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz", - "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "darwin" - ], - "peer": true, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-darwin-x64": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz", - "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "darwin" - ], - "peer": true, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-freebsd-x64": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz", - "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "freebsd" - ], - "peer": true, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm-gnueabihf": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz", - "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm64-gnu": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz", - "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm64-musl": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz", - "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-x64-gnu": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz", - "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-x64-musl": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz", - "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-win32-arm64-msvc": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz", - "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "win32" - ], - "peer": true, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-win32-x64-msvc": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz", - "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "win32" - ], - "peer": true, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, "node_modules/lilconfig": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", @@ -22204,16 +21047,16 @@ } }, "node_modules/lodash": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", - "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", + "version": "4.17.23", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", + "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", "dev": true, "license": "MIT" }, "node_modules/lodash-es": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.18.1.tgz", - "integrity": "sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A==", + "version": "4.17.23", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.23.tgz", + "integrity": "sha512-kVI48u3PZr38HdYz98UmfPnXl2DXrpdctLrFLCd3kOx1xUkOmpFPx7gCWWM5MPkL/fD8zb+Ph0QzjGFs4+hHWg==", "dev": true, "license": "MIT", "optional": true @@ -23461,9 +22304,9 @@ "license": "MIT" }, "node_modules/nodemailer": { - "version": "8.0.5", - "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-8.0.5.tgz", - "integrity": "sha512-0PF8Yb1yZuQfQbq+5/pZJrtF6WQcjTd5/S4JOHs9PGFxuTqoB/icwuB44pOdURHJbRKX1PPoJZtY7R4VUoCC8w==", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-8.0.4.tgz", + "integrity": "sha512-k+jf6N8PfQJ0Fe8ZhJlgqU5qJU44Lpvp2yvidH3vp1lPnVQMgi4yEEMPXg5eJS1gFIJTVq1NHBk7Ia9ARdSBdQ==", "license": "MIT-0", "engines": { "node": ">=6.0.0" @@ -24056,19 +22899,6 @@ "dev": true, "license": "MIT" }, - "node_modules/obug": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.1.tgz", - "integrity": "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==", - "dev": true, - "funding": [ - "https://github.com/sponsors/sxzz", - "https://opencollective.com/debug" - ], - "license": "MIT", - "optional": true, - "peer": true - }, "node_modules/on-exit-leak-free": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz", @@ -24666,9 +23496,9 @@ } }, "node_modules/path-to-regexp": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.2.tgz", - "integrity": "sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz", + "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==", "dev": true, "license": "MIT", "funding": { @@ -25388,7 +24218,6 @@ "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, "hasInstallScript": true, "license": "MIT", "optional": true, @@ -25535,14 +24364,11 @@ } }, "node_modules/proxy-from-env": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz", - "integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - } + "license": "MIT" }, "node_modules/prr": { "version": "1.0.1", @@ -28478,6 +27304,23 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/temp/node_modules/minimatch": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz", + "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==", + "dev": true, + "license": "BlueOak-1.0.0", + "peer": true, + "dependencies": { + "@isaacs/brace-expansion": "^5.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/temp/node_modules/rimraf": { "version": "2.6.3", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", @@ -30656,9 +29499,9 @@ } }, "node_modules/webpack-dev-server/node_modules/path-to-regexp": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.13.tgz", - "integrity": "sha512-A/AGNMFN3c8bOlvV9RreMdrv7jsmF9XIfDeCd87+I8RNg6s78BhJxMu69NEMHBSJFxKidViTEdruRwEk/WIKqA==", + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", + "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", "dev": true, "license": "MIT" }, @@ -31470,7 +30313,7 @@ "dotenv": "^17.2.3", "fastify": "^5.8.1", "jsonwebtoken": "^9.0.2", - "nodemailer": "^8.0.5", + "nodemailer": "^8.0.4", "uuidv7": "^1.1.0", "zod": "^4.3.5" }, @@ -31512,12 +30355,496 @@ "devDependencies": { "@types/node": "^22.0.0", "typescript": "^5.0.0", - "vite": "^7.3.2" + "vite": "^6.0.0" }, "peerDependencies": { "vite": "^5.0.0 || ^6.0.0 || ^7.0.0" } }, + "packages/vite-plugin/node_modules/@esbuild/aix-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", + "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "packages/vite-plugin/node_modules/@esbuild/android-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", + "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "packages/vite-plugin/node_modules/@esbuild/android-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", + "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "packages/vite-plugin/node_modules/@esbuild/android-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", + "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "packages/vite-plugin/node_modules/@esbuild/darwin-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", + "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "packages/vite-plugin/node_modules/@esbuild/darwin-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", + "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "packages/vite-plugin/node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", + "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "packages/vite-plugin/node_modules/@esbuild/freebsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", + "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "packages/vite-plugin/node_modules/@esbuild/linux-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", + "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "packages/vite-plugin/node_modules/@esbuild/linux-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", + "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "packages/vite-plugin/node_modules/@esbuild/linux-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", + "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "packages/vite-plugin/node_modules/@esbuild/linux-loong64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", + "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "packages/vite-plugin/node_modules/@esbuild/linux-mips64el": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", + "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "packages/vite-plugin/node_modules/@esbuild/linux-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", + "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "packages/vite-plugin/node_modules/@esbuild/linux-riscv64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", + "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "packages/vite-plugin/node_modules/@esbuild/linux-s390x": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", + "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "packages/vite-plugin/node_modules/@esbuild/linux-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", + "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "packages/vite-plugin/node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", + "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "packages/vite-plugin/node_modules/@esbuild/netbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", + "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "packages/vite-plugin/node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", + "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "packages/vite-plugin/node_modules/@esbuild/openbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", + "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "packages/vite-plugin/node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", + "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "packages/vite-plugin/node_modules/@esbuild/sunos-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", + "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "packages/vite-plugin/node_modules/@esbuild/win32-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", + "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "packages/vite-plugin/node_modules/@esbuild/win32-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", + "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "packages/vite-plugin/node_modules/@esbuild/win32-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", + "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "packages/vite-plugin/node_modules/esbuild": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", + "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.12", + "@esbuild/android-arm": "0.25.12", + "@esbuild/android-arm64": "0.25.12", + "@esbuild/android-x64": "0.25.12", + "@esbuild/darwin-arm64": "0.25.12", + "@esbuild/darwin-x64": "0.25.12", + "@esbuild/freebsd-arm64": "0.25.12", + "@esbuild/freebsd-x64": "0.25.12", + "@esbuild/linux-arm": "0.25.12", + "@esbuild/linux-arm64": "0.25.12", + "@esbuild/linux-ia32": "0.25.12", + "@esbuild/linux-loong64": "0.25.12", + "@esbuild/linux-mips64el": "0.25.12", + "@esbuild/linux-ppc64": "0.25.12", + "@esbuild/linux-riscv64": "0.25.12", + "@esbuild/linux-s390x": "0.25.12", + "@esbuild/linux-x64": "0.25.12", + "@esbuild/netbsd-arm64": "0.25.12", + "@esbuild/netbsd-x64": "0.25.12", + "@esbuild/openbsd-arm64": "0.25.12", + "@esbuild/openbsd-x64": "0.25.12", + "@esbuild/openharmony-arm64": "0.25.12", + "@esbuild/sunos-x64": "0.25.12", + "@esbuild/win32-arm64": "0.25.12", + "@esbuild/win32-ia32": "0.25.12", + "@esbuild/win32-x64": "0.25.12" + } + }, "packages/vite-plugin/node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -31534,24 +30861,24 @@ } }, "packages/vite-plugin/node_modules/vite": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.2.tgz", - "integrity": "sha512-Bby3NOsna2jsjfLVOHKes8sGwgl4TT0E6vvpYgnAYDIF/tie7MRaFthmKuHx1NSXjiTueXH3do80FMQgvEktRg==", + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.1.tgz", + "integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==", "dev": true, "license": "MIT", "dependencies": { - "esbuild": "^0.27.0", - "fdir": "^6.5.0", - "picomatch": "^4.0.3", - "postcss": "^8.5.6", - "rollup": "^4.43.0", - "tinyglobby": "^0.2.15" + "esbuild": "^0.25.0", + "fdir": "^6.4.4", + "picomatch": "^4.0.2", + "postcss": "^8.5.3", + "rollup": "^4.34.9", + "tinyglobby": "^0.2.13" }, "bin": { "vite": "bin/vite.js" }, "engines": { - "node": "^20.19.0 || >=22.12.0" + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" }, "funding": { "url": "https://github.com/vitejs/vite?sponsor=1" @@ -31560,14 +30887,14 @@ "fsevents": "~2.3.3" }, "peerDependencies": { - "@types/node": "^20.19.0 || >=22.12.0", + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "jiti": ">=1.21.0", - "less": "^4.0.0", + "less": "*", "lightningcss": "^1.21.0", - "sass": "^1.70.0", - "sass-embedded": "^1.70.0", - "stylus": ">=0.54.8", - "sugarss": "^5.0.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" diff --git a/package.json b/package.json index 075111dd22..4cfe9b87f2 100644 --- a/package.json +++ b/package.json @@ -230,7 +230,7 @@ "cross-env": "^7.0.3", "detect-it": "^4.0.1", "dotenv": "^17.3.1", - "electron": "41.2.0", + "electron": "37.10.3", "electron-builder": "^26.7.0", "eslint": "^9.39.2", "eslint-config-prettier": "^10.1.8", @@ -282,7 +282,7 @@ }, "overrides": { "app-builder-lib": { - "minimatch": "10.2.5" + "minimatch": "10.1.1" } }, "optionalDependencies": { diff --git a/packages/plugin-dev/automations/package-lock.json b/packages/plugin-dev/automations/package-lock.json index 1273b2816d..85d2384cf4 100644 --- a/packages/plugin-dev/automations/package-lock.json +++ b/packages/plugin-dev/automations/package-lock.json @@ -50,7 +50,7 @@ "devDependencies": { "@types/node": "^22.0.0", "typescript": "^5.0.0", - "vite": "^7.3.2" + "vite": "^6.0.0" }, "peerDependencies": { "vite": "^5.0.0 || ^6.0.0 || ^7.0.0" diff --git a/packages/plugin-dev/github-issue-provider/i18n/en.json b/packages/plugin-dev/github-issue-provider/i18n/en.json index d97589e083..012babeba6 100644 --- a/packages/plugin-dev/github-issue-provider/i18n/en.json +++ b/packages/plugin-dev/github-issue-provider/i18n/en.json @@ -1,7 +1,7 @@ { "CFG": { "REPO": "Repository (owner/repo)", - "TOKEN": "Personal Access Token (required for private repos/optional for public repos)", + "TOKEN": "Personal Access Token (optional, for private repos)", "FILTER_USERNAME": "Filter username (ignore own comments for update detection)", "BACKLOG_QUERY": "Backlog query (default: \"sort:updated state:open assignee:@me\")", "HOW_TO_GET_TOKEN": "How to get a token" diff --git a/packages/plugin-dev/package-lock.json b/packages/plugin-dev/package-lock.json index f9df5bc8d6..3a6110e240 100644 --- a/packages/plugin-dev/package-lock.json +++ b/packages/plugin-dev/package-lock.json @@ -34,7 +34,7 @@ "devDependencies": { "@types/node": "^22.0.0", "typescript": "^5.0.0", - "vite": "^7.3.2" + "vite": "^6.0.0" }, "peerDependencies": { "vite": "^5.0.0 || ^6.0.0 || ^7.0.0" diff --git a/packages/super-sync-server/package.json b/packages/super-sync-server/package.json index 3fd1d6f6a2..ff87c8220e 100644 --- a/packages/super-sync-server/package.json +++ b/packages/super-sync-server/package.json @@ -7,7 +7,7 @@ "build": "tsc", "start": "node dist/src/index.js", "dev": "nodemon --watch src --ext ts --exec ts-node src/index.ts", - "pretest": "npm run build --workspace=@sp/shared-schema && prisma generate", + "pretest": "prisma generate", "test": "vitest run", "docker:build": "./scripts/build-and-push.sh", "docker:deploy": "./scripts/deploy.sh", @@ -43,7 +43,7 @@ "dotenv": "^17.2.3", "fastify": "^5.8.1", "jsonwebtoken": "^9.0.2", - "nodemailer": "^8.0.5", + "nodemailer": "^8.0.4", "uuidv7": "^1.1.0", "zod": "^4.3.5" }, diff --git a/packages/vite-plugin/package.json b/packages/vite-plugin/package.json index 4c4ed5b687..1615a8bd67 100644 --- a/packages/vite-plugin/package.json +++ b/packages/vite-plugin/package.json @@ -13,6 +13,6 @@ "devDependencies": { "@types/node": "^22.0.0", "typescript": "^5.0.0", - "vite": "^7.3.2" + "vite": "^6.0.0" } } diff --git a/src/app/core-ui/mobile-bottom-nav/mobile-bottom-nav.component.html b/src/app/core-ui/mobile-bottom-nav/mobile-bottom-nav.component.html index 7d3542f9fe..e62a17af99 100644 --- a/src/app/core-ui/mobile-bottom-nav/mobile-bottom-nav.component.html +++ b/src/app/core-ui/mobile-bottom-nav/mobile-bottom-nav.component.html @@ -1,7 +1,6 @@