diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 44596b4a8..9ca0d2167 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -183,27 +183,13 @@ jobs: if: always() uses: codecov/test-results-action@v1 with: - token: ${{ secrets.CODECOV_TOKEN }} flags: backend-python-${{ matrix.python-version }} files: junit.xml - name: Upload backend coverage to Codecov uses: codecov/codecov-action@v5 with: - token: ${{ secrets.CODECOV_TOKEN }} flags: backend-python-${{ matrix.python-version }} files: coverage.xml - - name: Upload coverage artifacts - uses: actions/upload-artifact@v4 - if: always() - with: - name: backend-coverage-${{ matrix.python-version }} - path: | - .coverage - coverage.xml - junit.xml - retention-days: 1 - include-hidden-files: true - if-no-files-found: error - name: Stop containers if: always() run: | @@ -277,26 +263,13 @@ jobs: uses: codecov/test-results-action@v1 if: always() with: - token: ${{ secrets.CODECOV_TOKEN }} flags: frontend-node-${{ matrix.node-version }} directory: src-ui/ - name: Upload frontend coverage to Codecov uses: codecov/codecov-action@v5 with: - token: ${{ secrets.CODECOV_TOKEN }} flags: frontend-node-${{ matrix.node-version }} directory: src-ui/coverage/ - - name: Upload coverage artifacts - uses: actions/upload-artifact@v4 - if: always() - with: - name: frontend-coverage-${{ matrix.shard-index }} - path: | - src-ui/coverage/lcov.info - src-ui/coverage/coverage-final.json - src-ui/junit.xml - retention-days: 1 - if-no-files-found: error tests-frontend-e2e: name: "Frontend E2E Tests (Node ${{ matrix.node-version }} - ${{ matrix.shard-index }}/${{ matrix.shard-count }})" runs-on: ubuntu-24.04 @@ -377,74 +350,6 @@ jobs: env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} run: cd src-ui && pnpm run build --configuration=production - sonarqube-analysis: - name: "SonarQube Analysis" - runs-on: ubuntu-24.04 - needs: - - tests-backend - - tests-frontend - if: github.repository_owner == 'paperless-ngx' - steps: - - name: Checkout - uses: actions/checkout@v5 - with: - fetch-depth: 0 - - name: Download all backend coverage - uses: actions/download-artifact@v5.0.0 - with: - pattern: backend-coverage-* - path: ./coverage/ - - name: Download all frontend coverage - uses: actions/download-artifact@v5.0.0 - with: - pattern: frontend-coverage-* - path: ./coverage/ - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: ${{ env.DEFAULT_PYTHON_VERSION }} - - name: Install coverage tools - run: | - pip install coverage - npm install -g nyc - # Merge backend coverage from all Python versions - - name: Merge backend coverage - run: | - coverage combine coverage/backend-coverage-*/.coverage - coverage xml -o merged-backend-coverage.xml - # Merge frontend coverage from all shards - - name: Merge frontend coverage - run: | - # Find all coverage-final.json files from the shards, exit with error if none found - shopt -s nullglob - files=(coverage/frontend-coverage-*/coverage/coverage-final.json) - if [ ${#files[@]} -eq 0 ]; then - echo "No frontend coverage JSON found under coverage/" >&2 - exit 1 - fi - # Create .nyc_output directory and copy each shard's coverage JSON into it with a unique name - mkdir -p .nyc_output - for coverage_json in "${files[@]}"; do - shard=$(basename "$(dirname "$(dirname "$coverage_json")")") - cp "$coverage_json" ".nyc_output/${shard}.json" - done - npx nyc merge .nyc_output .nyc_output/out.json - npx nyc report --reporter=lcovonly --report-dir coverage - - name: Upload coverage artifacts - uses: actions/upload-artifact@v4.6.2 - with: - name: merged-coverage - path: | - merged-backend-coverage.xml - .nyc_output/* - coverage/lcov.info - retention-days: 7 - if-no-files-found: error - include-hidden-files: true - - name: SonarQube Analysis - uses: SonarSource/sonarqube-scan-action@v5 - env: - SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} build-docker-image: name: Build Docker image for ${{ github.ref_name }} runs-on: ubuntu-24.04 diff --git a/Dockerfile b/Dockerfile index 93fd32ee3..8dbfc7119 100644 --- a/Dockerfile +++ b/Dockerfile @@ -32,7 +32,7 @@ RUN set -eux \ # Purpose: Installs s6-overlay and rootfs # Comments: # - Don't leave anything extra in here either -FROM ghcr.io/astral-sh/uv:0.8.17-python3.12-bookworm-slim AS s6-overlay-base +FROM ghcr.io/astral-sh/uv:0.8.22-python3.12-bookworm-slim AS s6-overlay-base WORKDIR /usr/src/s6 diff --git a/pyproject.toml b/pyproject.toml index 4a2e8bcd9..0d37c0a80 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,7 +31,7 @@ dependencies = [ "django-cachalot~=2.8.0", "django-celery-results~=2.6.0", "django-compression-middleware~=0.5.0", - "django-cors-headers~=4.8.0", + "django-cors-headers~=4.9.0", "django-extensions~=4.1", "django-filter~=25.1", "django-guardian~=3.1.2", @@ -257,7 +257,6 @@ PAPERLESS_DISABLE_DBHANDLER = "true" PAPERLESS_CACHE_BACKEND = "django.core.cache.backends.locmem.LocMemCache" [tool.coverage.run] -relative_files = true source = [ "src/", ] diff --git a/sonar-project.properties b/sonar-project.properties deleted file mode 100644 index d9d341e87..000000000 --- a/sonar-project.properties +++ /dev/null @@ -1,24 +0,0 @@ -sonar.projectKey=paperless-ngx_paperless-ngx -sonar.organization=paperless-ngx -sonar.projectName=Paperless-ngx -sonar.projectVersion=1.0 - -# Source and test directories -sonar.sources=src/,src-ui/ -sonar.test.inclusions=**/test_*.py,**/tests.py,**/*.spec.ts,**/*.test.ts - -# Language specific settings -sonar.python.version=3.10,3.11,3.12,3.13 - -# Coverage reports -sonar.python.coverage.reportPaths=merged-backend-coverage.xml -sonar.javascript.lcov.reportPaths=coverage/lcov.info - -# Test execution reports -sonar.junit.reportPaths=**/junit.xml,**/test-results.xml - -# Encoding -sonar.sourceEncoding=UTF-8 - -# Exclusions -sonar.exclusions=**/migrations/**,**/node_modules/**,**/static/**,**/venv/**,**/.venv/**,**/dist/** diff --git a/src-ui/e2e/document-list/document-list.spec.ts b/src-ui/e2e/document-list/document-list.spec.ts index 45857bb09..0a7b54fcb 100644 --- a/src-ui/e2e/document-list/document-list.spec.ts +++ b/src-ui/e2e/document-list/document-list.spec.ts @@ -174,7 +174,7 @@ test('bulk edit', async ({ page }) => { await expect(page.locator('pngx-document-list')).toHaveText( /Selected 61 of 61 documents/i ) - await page.getByRole('button', { name: 'Cancel' }).click() + await page.getByRole('button', { name: 'None' }).click() await page.locator('pngx-document-card-small').nth(1).click() await page.locator('pngx-document-card-small').nth(2).click() diff --git a/src-ui/messages.xlf b/src-ui/messages.xlf index 17f1bedf5..376594cb7 100644 --- a/src-ui/messages.xlf +++ b/src-ui/messages.xlf @@ -324,7 +324,7 @@ src/app/components/document-list/document-list.component.ts - 190 + 192 src/app/components/manage/custom-fields/custom-fields.component.html @@ -743,7 +743,7 @@ src/app/components/document-list/document-list.component.html - 114 + 134 src/app/components/manage/custom-fields/custom-fields.component.html @@ -1167,7 +1167,7 @@ src/app/components/document-list/document-list.component.html - 217 + 242 src/app/data/document.ts @@ -1209,7 +1209,7 @@ src/app/components/document-list/bulk-editor/bulk-editor.component.html - 97 + 78 src/app/components/document-list/filter-editor/filter-editor.component.html @@ -1494,10 +1494,6 @@ src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.html 182 - - src/app/components/document-list/bulk-editor/bulk-editor.component.html - 4 - src/app/components/document-list/bulk-editor/custom-fields-bulk-edit-dialog/custom-fields-bulk-edit-dialog.component.html 81 @@ -1604,6 +1600,10 @@ src/app/components/admin/trash/trash.component.html 8 + + src/app/components/document-list/document-list.component.html + 153 + src/app/components/manage/management-list/management-list.component.html 4 @@ -1755,7 +1755,7 @@ src/app/components/document-list/document-list.component.html - 244 + 269 src/app/data/document.ts @@ -1808,7 +1808,7 @@ src/app/components/document-list/bulk-editor/bulk-editor.component.html - 103 + 87 src/app/components/manage/custom-fields/custom-fields.component.html @@ -2109,7 +2109,7 @@ src/app/components/document-list/bulk-editor/bulk-editor.component.html - 157 + 140 src/app/components/manage/custom-fields/custom-fields.component.html @@ -2769,11 +2769,11 @@ src/app/components/document-list/bulk-editor/bulk-editor.component.html - 21 + 5 src/app/components/document-list/document-list.component.html - 199 + 224 src/app/components/document-list/filter-editor/filter-editor.component.html @@ -3001,7 +3001,7 @@ src/app/components/document-list/bulk-editor/bulk-editor.component.html - 129 + 112 src/app/components/document-list/document-card-large/document-card-large.component.html @@ -3448,8 +3448,8 @@ 27 - src/app/components/document-list/bulk-editor/bulk-editor.component.html - 14 + src/app/components/document-list/document-list.component.html + 30 @@ -3529,7 +3529,7 @@ src/app/components/document-list/document-list.component.html - 253 + 278 src/app/data/document.ts @@ -6356,7 +6356,7 @@ src/app/components/document-list/document-list.component.html - 298 + 323 @@ -6371,7 +6371,7 @@ src/app/components/document-list/document-list.component.html - 338 + 363 @@ -6386,7 +6386,7 @@ src/app/components/document-list/document-list.component.html - 345 + 370 @@ -6404,7 +6404,7 @@ src/app/components/document-list/document-list.component.html - 366 + 391 @@ -6415,7 +6415,7 @@ src/app/components/document-list/document-list.component.html - 366 + 391 @@ -6585,8 +6585,8 @@ 5 - src/app/components/document-list/bulk-editor/bulk-editor.component.html - 11 + src/app/components/document-list/document-list.component.html + 27 @@ -6625,7 +6625,7 @@ src/app/components/document-list/bulk-editor/bulk-editor.component.html - 107 + 91 @@ -6686,7 +6686,7 @@ src/app/components/document-list/document-list.component.html - 196 + 221 src/app/components/document-list/filter-editor/filter-editor.component.ts @@ -6723,11 +6723,11 @@ src/app/components/document-list/bulk-editor/bulk-editor.component.html - 35 + 19 src/app/components/document-list/document-list.component.html - 186 + 211 src/app/components/document-list/filter-editor/filter-editor.component.html @@ -6750,11 +6750,11 @@ src/app/components/document-list/bulk-editor/bulk-editor.component.html - 49 + 33 src/app/components/document-list/document-list.component.html - 226 + 251 src/app/components/document-list/filter-editor/filter-editor.component.html @@ -6777,11 +6777,11 @@ src/app/components/document-list/bulk-editor/bulk-editor.component.html - 63 + 47 src/app/components/document-list/document-list.component.html - 235 + 260 src/app/components/document-list/filter-editor/filter-editor.component.html @@ -7188,25 +7188,18 @@ 10 - - Select: - - src/app/components/document-list/bulk-editor/bulk-editor.component.html - 8 - - Edit: src/app/components/document-list/bulk-editor/bulk-editor.component.html - 19 + 3 Filter tags src/app/components/document-list/bulk-editor/bulk-editor.component.html - 22 + 6 src/app/components/document-list/filter-editor/filter-editor.component.html @@ -7217,7 +7210,7 @@ Filter correspondents src/app/components/document-list/bulk-editor/bulk-editor.component.html - 36 + 20 src/app/components/document-list/filter-editor/filter-editor.component.html @@ -7228,7 +7221,7 @@ Filter document types src/app/components/document-list/bulk-editor/bulk-editor.component.html - 50 + 34 src/app/components/document-list/filter-editor/filter-editor.component.html @@ -7239,7 +7232,7 @@ Filter storage paths src/app/components/document-list/bulk-editor/bulk-editor.component.html - 64 + 48 src/app/components/document-list/filter-editor/filter-editor.component.html @@ -7250,7 +7243,7 @@ Custom fields src/app/components/document-list/bulk-editor/bulk-editor.component.html - 77 + 61 src/app/components/document-list/filter-editor/filter-editor.component.html @@ -7265,56 +7258,56 @@ Filter custom fields src/app/components/document-list/bulk-editor/bulk-editor.component.html - 78 + 62 Set values src/app/components/document-list/bulk-editor/bulk-editor.component.html - 86 + 70 Rotate src/app/components/document-list/bulk-editor/bulk-editor.component.html - 110 + 94 Merge src/app/components/document-list/bulk-editor/bulk-editor.component.html - 113 + 97 Include: src/app/components/document-list/bulk-editor/bulk-editor.component.html - 135 + 118 Archived files src/app/components/document-list/bulk-editor/bulk-editor.component.html - 139 + 122 Original files src/app/components/document-list/bulk-editor/bulk-editor.component.html - 143 + 126 Use formatted filename src/app/components/document-list/bulk-editor/bulk-editor.component.html - 148 + 131 @@ -7614,7 +7607,7 @@ src/app/components/document-list/document-list.component.html - 314 + 339 @@ -7738,7 +7731,7 @@ Select src/app/components/document-list/document-list.component.html - 6 + 5 src/app/data/custom-field.ts @@ -7749,36 +7742,51 @@ Select none src/app/components/document-list/document-list.component.html - 9 + 11 Select page src/app/components/document-list/document-list.component.html - 10 + 12 src/app/components/document-list/document-list.component.ts - 313 + 315 Select all src/app/components/document-list/document-list.component.html - 11 + 13 src/app/components/document-list/document-list.component.ts - 306 + 308 + + + + None + + src/app/components/document-list/document-list.component.html + 23 + + + src/app/components/manage/management-list/management-list.component.ts + 120 + + + src/app/data/matching-model.ts + 45 Show src/app/components/document-list/document-list.component.html - 17 + 37 src/app/components/manage/saved-views/saved-views.component.html @@ -7789,63 +7797,63 @@ Sort src/app/components/document-list/document-list.component.html - 48 + 68 Views src/app/components/document-list/document-list.component.html - 74 + 94 Save "" src/app/components/document-list/document-list.component.html - 93 + 113 Save as... src/app/components/document-list/document-list.component.html - 96 + 116 All saved views src/app/components/document-list/document-list.component.html - 97 + 117 {VAR_PLURAL, plural, =1 {Selected of one document} other {Selected of documents}} src/app/components/document-list/document-list.component.html - 117 + 137 {VAR_PLURAL, plural, =1 {One document} other { documents}} src/app/components/document-list/document-list.component.html - 121 + 141 (filtered) src/app/components/document-list/document-list.component.html - 123 + 143 Reset filters src/app/components/document-list/document-list.component.html - 128 + 148 src/app/components/document-list/filter-editor/filter-editor.component.html @@ -7856,21 +7864,21 @@ Error while loading documents src/app/components/document-list/document-list.component.html - 144 + 169 Sort by ASN src/app/components/document-list/document-list.component.html - 173 + 198 ASN src/app/components/document-list/document-list.component.html - 177 + 202 src/app/components/document-list/filter-editor/filter-editor.component.ts @@ -7889,28 +7897,28 @@ Sort by correspondent src/app/components/document-list/document-list.component.html - 182 + 207 Sort by title src/app/components/document-list/document-list.component.html - 191 + 216 Sort by owner src/app/components/document-list/document-list.component.html - 204 + 229 Owner src/app/components/document-list/document-list.component.html - 208 + 233 src/app/data/document.ts @@ -7925,49 +7933,49 @@ Sort by notes src/app/components/document-list/document-list.component.html - 213 + 238 Sort by document type src/app/components/document-list/document-list.component.html - 222 + 247 Sort by storage path src/app/components/document-list/document-list.component.html - 231 + 256 Sort by created date src/app/components/document-list/document-list.component.html - 240 + 265 Sort by added date src/app/components/document-list/document-list.component.html - 249 + 274 Sort by number of pages src/app/components/document-list/document-list.component.html - 258 + 283 Pages src/app/components/document-list/document-list.component.html - 262 + 287 src/app/data/document.ts @@ -7986,77 +7994,77 @@ Shared src/app/components/document-list/document-list.component.html - 265,267 + 290,292 Sort by src/app/components/document-list/document-list.component.html - 272,273 + 297,298 Edit document src/app/components/document-list/document-list.component.html - 306 + 331 Preview document src/app/components/document-list/document-list.component.html - 307 + 332 Reset filters / selection src/app/components/document-list/document-list.component.ts - 294 + 296 Open first [selected] document src/app/components/document-list/document-list.component.ts - 322 + 324 Previous page src/app/components/document-list/document-list.component.ts - 338 + 340 Next page src/app/components/document-list/document-list.component.ts - 350 + 352 View "" saved successfully. src/app/components/document-list/document-list.component.ts - 383 + 385 Failed to save view "". src/app/components/document-list/document-list.component.ts - 389 + 391 View "" created successfully. src/app/components/document-list/document-list.component.ts - 435 + 437 @@ -8861,17 +8869,6 @@ 15 - - None - - src/app/components/manage/management-list/management-list.component.ts - 120 - - - src/app/data/matching-model.ts - 45 - - Successfully created . diff --git a/src-ui/src/app/components/common/edit-dialog/custom-field-edit-dialog/custom-field-edit-dialog.component.ts b/src-ui/src/app/components/common/edit-dialog/custom-field-edit-dialog/custom-field-edit-dialog.component.ts index 617d825b2..8e8bddfab 100644 --- a/src-ui/src/app/components/common/edit-dialog/custom-field-edit-dialog/custom-field-edit-dialog.component.ts +++ b/src-ui/src/app/components/common/edit-dialog/custom-field-edit-dialog/custom-field-edit-dialog.component.ts @@ -177,10 +177,16 @@ export class CustomFieldEditDialogComponent } public removeSelectOption(index: number) { - this.selectOptions.removeAt(index) - this._allSelectOptions.splice( - index + (this.selectOptionsPage - 1) * SELECT_OPTION_PAGE_SIZE, - 1 + const globalIndex = + index + (this.selectOptionsPage - 1) * SELECT_OPTION_PAGE_SIZE + this._allSelectOptions.splice(globalIndex, 1) + + const totalPages = Math.max( + 1, + Math.ceil(this._allSelectOptions.length / SELECT_OPTION_PAGE_SIZE) ) + const targetPage = Math.min(this.selectOptionsPage, totalPages) + + this.selectOptionsPage = targetPage } } diff --git a/src-ui/src/app/components/document-list/bulk-editor/bulk-editor.component.html b/src-ui/src/app/components/document-list/bulk-editor/bulk-editor.component.html index 0eb655a21..7e499dfd0 100644 --- a/src-ui/src/app/components/document-list/bulk-editor/bulk-editor.component.html +++ b/src-ui/src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1,161 +1,144 @@
-
-
-
- -
-
+
+
+
+ +
+ + + - -
-
- - @if (permissionService.currentUserCan(PermissionAction.View, PermissionType.Tag)) { - - - } - @if (permissionService.currentUserCan(PermissionAction.View, PermissionType.Correspondent)) { - - - } - @if (permissionService.currentUserCan(PermissionAction.View, PermissionType.DocumentType)) { - - - } - @if (permissionService.currentUserCan(PermissionAction.View, PermissionType.StoragePath)) { - - - } - @if (permissionService.currentUserCan(PermissionAction.View, PermissionType.CustomField)) { - - - } +
+
+
+ +
+ +
+
+

Include:

+
+
+ + +
+
+ + +
+
+
+ + +
+
-
-
+
+
- - -
- -
- - - -
-
-
- -
- -
- -
-
-

Include:

-
-
- - -
-
- - -
-
-
- - -
-
-
-
-
- -
- -
-
-
+
+ +
+
+
diff --git a/src-ui/src/app/components/document-list/bulk-editor/bulk-editor.component.scss b/src-ui/src/app/components/document-list/bulk-editor/bulk-editor.component.scss index 939f2c790..a5ea35ce4 100644 --- a/src-ui/src/app/components/document-list/bulk-editor/bulk-editor.component.scss +++ b/src-ui/src/app/components/document-list/bulk-editor/bulk-editor.component.scss @@ -5,3 +5,7 @@ .dropdown-menu{ --bs-dropdown-min-width: 12rem; } + +.btn-group .btn { + white-space: nowrap; +} diff --git a/src-ui/src/app/components/document-list/document-list.component.html b/src-ui/src/app/components/document-list/document-list.component.html index c58d1ede1..a6d23f2a5 100644 --- a/src-ui/src/app/components/document-list/document-list.component.html +++ b/src-ui/src/app/components/document-list/document-list.component.html @@ -1,16 +1,36 @@ - -
- -
+
+
+
+ Select: +
+
+ @if (list.selected.size > 0) { + + } + + +
+
- } + + } + @if (!list.isReloading && list.selected.size > 0) { + + }
@if (list.collectionSize) { 0 and not fnmatch( - document.original_file, + match_against, trigger.filter_path, ) ): diff --git a/src/documents/tests/test_barcodes.py b/src/documents/tests/test_barcodes.py index b2c28a82b..0ad98344d 100644 --- a/src/documents/tests/test_barcodes.py +++ b/src/documents/tests/test_barcodes.py @@ -614,14 +614,16 @@ class TestBarcodeNewConsume( self.assertIsNotFile(temp_copy) # Check the split files exist + # Check the original_path is set # Check the source is unchanged # Check the overrides are unchanged for ( new_input_doc, new_doc_overrides, ) in self.get_all_consume_delay_call_args(): - self.assertEqual(new_input_doc.source, DocumentSource.ConsumeFolder) self.assertIsFile(new_input_doc.original_file) + self.assertEqual(new_input_doc.original_path, temp_copy) + self.assertEqual(new_input_doc.source, DocumentSource.ConsumeFolder) self.assertEqual(overrides, new_doc_overrides) diff --git a/uv.lock b/uv.lock index cbe75715d..69e1a5cea 100644 --- a/uv.lock +++ b/uv.lock @@ -758,15 +758,15 @@ wheels = [ [[package]] name = "django-cors-headers" -version = "4.8.0" +version = "4.9.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "asgiref", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, { name = "django", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/89/8e/6225441edcfe179bf4861e9e67489e33375e0b66316c8d7b9edaae863d37/django_cors_headers-4.8.0.tar.gz", hash = "sha256:0a12a2efcd59a3cea741e44db8ab589e929949de5bc4cdf35a29c6ae77297686", size = 21425, upload-time = "2025-09-08T15:58:05.34Z" } +sdist = { url = "https://files.pythonhosted.org/packages/21/39/55822b15b7ec87410f34cd16ce04065ff390e50f9e29f31d6d116fc80456/django_cors_headers-4.9.0.tar.gz", hash = "sha256:fe5d7cb59fdc2c8c646ce84b727ac2bca8912a247e6e68e1fb507372178e59e8", size = 21458, upload-time = "2025-09-18T10:40:52.326Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ac/b3/29ef49d6ff7800f323f3d98cde7777b3cfdda133de8feea84cffafea4578/django_cors_headers-4.8.0-py3-none-any.whl", hash = "sha256:3b883f4c6d07848673218456a5e070d8ab51f97341c1f27d0242ca167e7272ab", size = 12804, upload-time = "2025-09-08T15:58:03.882Z" }, + { url = "https://files.pythonhosted.org/packages/30/d8/19ed1e47badf477d17fb177c1c19b5a21da0fd2d9f093f23be3fb86c5fab/django_cors_headers-4.9.0-py3-none-any.whl", hash = "sha256:15c7f20727f90044dcee2216a9fd7303741a864865f0c3657e28b7056f61b449", size = 12809, upload-time = "2025-09-18T10:40:50.843Z" }, ] [[package]] @@ -2221,7 +2221,7 @@ requires-dist = [ { name = "django-cachalot", specifier = "~=2.8.0" }, { name = "django-celery-results", specifier = "~=2.6.0" }, { name = "django-compression-middleware", specifier = "~=0.5.0" }, - { name = "django-cors-headers", specifier = "~=4.8.0" }, + { name = "django-cors-headers", specifier = "~=4.9.0" }, { name = "django-extensions", specifier = "~=4.1" }, { name = "django-filter", specifier = "~=25.1" }, { name = "django-guardian", specifier = "~=3.1.2" },