diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 000000000..ed42bd707 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,68 @@ +/.git +!/.git/config + +# Unneeded application files +/.docker +/.github +/docs +/fixtures +/public/build +/public/fixtures +/public/media/* +!public/media/thumbnail_other.png +!public/media/thumbnail_video.png +/scripts +/tests + +###> symfony/framework-bundle ### +/.env.local +/.env.local.php +/.env.*.local +/config/secrets/prod/prod.decrypt.private.php +/var/ +/vendor/ +###< symfony/framework-bundle ### + +###> friendsofphp/php-cs-fixer ### +/.php-cs-fixer.php +/.php-cs-fixer.cache +###< friendsofphp/php-cs-fixer ### + +###> phpunit/phpunit ### +/phpunit.xml +.phpunit.result.cache +###< phpunit/phpunit ### + +###> lexik/jwt-authentication-bundle ### +/config/jwt/*.pem +###< lexik/jwt-authentication-bundle ### + +xdebug.ini +launch.json + +###> pentatrion/vite-bundle ### +/node_modules/ +###< pentatrion/vite-bundle ### + +#> Playwright +/test-results/ +/playwright-report/ +/blob-report/ +/playwright/.cache/ +#< Playwright + +###> vincentlanglet/twig-cs-fixer ### +/.twig-cs-fixer.cache +###< vincentlanglet/twig-cs-fixer ### + +docker-compose.* +phpstan.dist.neon +psalm* +playwright.* +phpunit.* +rector.php +Taskfile.yml +.markdown* +.php-cs-fixer.dist.php +.twig-cs-fixer.dist.php +.prettier diff --git a/.env b/.env index 414a776c5..f92d23d68 100644 --- a/.env +++ b/.env @@ -19,7 +19,7 @@ ITKDEV_TEMPLATE=symfony-6 ###> symfony/framework-bundle ### APP_ENV=dev -APP_SECRET=22d8a60c047b96413b3337e3ddae3da9 +APP_SECRET=CHANGE_ME TRUSTED_PROXIES=127.0.0.1,REMOTE_ADDR ###< symfony/framework-bundle ### @@ -42,7 +42,7 @@ CORS_ALLOW_ORIGIN='^https?://(localhost|127\.0\.0\.1)(:[0-9]+)?$' ###> lexik/jwt-authentication-bundle ### JWT_SECRET_KEY=%kernel.project_dir%/config/jwt/private.pem JWT_PUBLIC_KEY=%kernel.project_dir%/config/jwt/public.pem -JWT_PASSPHRASE=APP_JWT_PASSPHRASE +JWT_PASSPHRASE=CHANGE_ME # Default: 1 hour JWT_TOKEN_TTL=3600 # Default: 15 days diff --git a/.github/workflows/apispec.yaml b/.github/workflows/apispec.yaml index 81de9fed9..962ae966f 100644 --- a/.github/workflows/apispec.yaml +++ b/.github/workflows/apispec.yaml @@ -1,6 +1,7 @@ on: pull_request name: Api Spec +run-name: "Api Spec - ${{ github.head_ref || github.ref_name }}" jobs: apispec: @@ -9,7 +10,7 @@ jobs: strategy: fail-fast: false matrix: - php: ["8.3"] + php: ["8.4"] steps: - name: Checkout uses: actions/checkout@v4 diff --git a/.github/workflows/changelog.yaml b/.github/workflows/changelog.yaml index 483da6e95..563581199 100644 --- a/.github/workflows/changelog.yaml +++ b/.github/workflows/changelog.yaml @@ -7,6 +7,7 @@ ### Checks that changelog has been updated name: Changelog +run-name: "Changelog - ${{ github.head_ref || github.ref_name }}" on: pull_request: diff --git a/.github/workflows/composer.yaml b/.github/workflows/composer.yaml index b068c235a..6a4d41b6a 100644 --- a/.github/workflows/composer.yaml +++ b/.github/workflows/composer.yaml @@ -24,6 +24,7 @@ ### ``` name: Composer +run-name: "Composer - ${{ github.head_ref || github.ref_name }}" env: COMPOSE_USER: runner diff --git a/.github/workflows/composer_install.yaml b/.github/workflows/composer_install.yaml index 569a71b32..0c7c56f51 100644 --- a/.github/workflows/composer_install.yaml +++ b/.github/workflows/composer_install.yaml @@ -1,6 +1,7 @@ on: pull_request name: Composer install +run-name: "Composer install - ${{ github.head_ref || github.ref_name }}" jobs: test-composer-install: @@ -10,7 +11,7 @@ jobs: strategy: fail-fast: false matrix: - php: ["8.3"] + php: ["8.4"] name: Composer install in prod mode (PHP ${{ matrix.php}}) steps: - name: Checkout diff --git a/.github/workflows/os2display_docker_build_develop.yml b/.github/workflows/docker_build_stg_images.yml similarity index 59% rename from .github/workflows/os2display_docker_build_develop.yml rename to .github/workflows/docker_build_stg_images.yml index bcdf09a6c..781b76f6d 100644 --- a/.github/workflows/os2display_docker_build_develop.yml +++ b/.github/workflows/docker_build_stg_images.yml @@ -2,10 +2,11 @@ on: push: branches: - - "develop" + - "release/*" -# This Action builds to os2display/* using ./infrastructure/os2display/* -name: OS2display - Build docker image (develop) +# This Action builds to os2display/* using ./infrastructure/* +name: Build docker image (develop) +run-name: "Build docker image (staging) - ${{ github.head_ref || github.ref_name }}" jobs: docker: @@ -14,15 +15,18 @@ jobs: APP_VERSION: develop COMPOSER_ALLOW_SUPERUSER: 1 steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Login to DockerHub uses: docker/login-action@v3 with: username: ${{ secrets.DOCKERHUB_USER }} password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + # Build api - name: Docker meta (API) id: meta-api @@ -31,15 +35,18 @@ jobs: images: os2display/display-api-service - name: Build and push (API) - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6 with: - context: ./infrastructure/os2display/display-api-service/ - file: ./infrastructure/os2display/display-api-service/Dockerfile + context: ./infrastructure/display-api-service/ + file: ./infrastructure/display-api-service/Dockerfile build-args: | VERSION=${{ env.APP_VERSION }} push: true tags: ${{ steps.meta-api.outputs.tags }} labels: ${{ steps.meta-api.outputs.labels }} + provenance: mode=max + sbom: true + platforms: linux/amd64,linux/arm64 # Build nginx (depends on api build) - name: Docker meta (Nginx) @@ -49,12 +56,15 @@ jobs: images: os2display/display-api-service-nginx - name: Build and push (Nginx) - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6 with: - context: ./infrastructure/os2display/nginx/ - file: ./infrastructure/os2display/nginx/Dockerfile + context: ./infrastructure/nginx/ + file: ./infrastructure/nginx/Dockerfile build-args: | APP_VERSION=${{ env.APP_VERSION }} push: true tags: ${{ steps.meta-nginx.outputs.tags }} labels: ${{ steps.meta-nginx.outputs.labels }} + provenance: mode=max + sbom: true + platforms: linux/amd64,linux/arm64 diff --git a/.github/workflows/doctrine.yaml b/.github/workflows/doctrine.yaml index 411acc50f..940ff0227 100644 --- a/.github/workflows/doctrine.yaml +++ b/.github/workflows/doctrine.yaml @@ -1,6 +1,7 @@ on: pull_request name: Doctrine +run-name: "Doctrine - ${{ github.head_ref || github.ref_name }}" jobs: validate-doctrine-shema: @@ -10,7 +11,7 @@ jobs: strategy: fail-fast: false matrix: - php: ["8.3"] + php: ["8.4"] name: Validate Schema (PHP ${{ matrix.php}}) services: mariadb: diff --git a/.github/workflows/github_build_release.yml b/.github/workflows/github_build_release.yml index 2ca6b44d7..ea6bbe7c5 100644 --- a/.github/workflows/github_build_release.yml +++ b/.github/workflows/github_build_release.yml @@ -1,29 +1,48 @@ +# This workflow builds a GitHub release on tag creation and then builds and +# pushes Docker images to GitHub Container Registry. + on: push: tags: - - "*.*.*" + - "*" name: Create Github Release +run-name: "Create Github Release - ${{ github.head_ref || github.ref_name }}" -permissions: - contents: write +env: + COMPOSE_USER: runner jobs: create-release: runs-on: ubuntu-latest - env: - COMPOSER_ALLOW_SUPERUSER: 1 - APP_ENV: prod + permissions: + contents: write steps: - name: Checkout uses: actions/checkout@v4 - - name: Composer install + - name: Setup docker network run: | docker network create frontend - docker compose run --rm --user=root --env APP_ENV=prod phpfpm composer install --no-dev -o --classmap-authoritative - docker compose run --rm --user=root --env APP_ENV=prod phpfpm composer clear-cache + + - name: Install dependencies with composer + run: | + docker compose run --rm --env APP_ENV=prod phpfpm composer install --no-dev -o --classmap-authoritative + docker compose run --rm --env APP_ENV=prod phpfpm composer clear-cache + + - name: Installs node dependencies with npm + run: | + docker compose run --rm node npm install + docker compose run --rm node npm run build + + - name: Cleanup after install + run: | + sudo chown -R runner:runner . + rm -rf docs rm -rf infrastructure + rm -rf fixtures + rm -rf tests + rm -rf node_modules - name: Make assets dir run: | @@ -31,15 +50,91 @@ jobs: - name: Create archive run: | - tar \ - -zcf ../assets/${{ github.event.repository.name }}-${{ github.ref_name }}.tar.gz ./* + tar -zcf ../assets/${{ github.event.repository.name }}-${{ github.ref_name }}.tar.gz ./* - name: Create checksum run: sha256sum ../assets/${{ github.event.repository.name }}-${{ github.ref_name }}.tar.gz > ../assets/checksum.txt - name: Create a release in GitHub and uploads assets run: | - gh release create ${{ github.ref_name }} --verify-tag --generate-notes ../assets/*.* + gh release create ${{ github.ref_name }} --verify-tag --generate-notes ${{ steps.prerelease.outputs.flag }} ../assets/*.* env: GITHUB_TOKEN: ${{ github.TOKEN }} shell: bash + + images: + needs: create-release + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + attestations: write + id-token: write + env: + REGISTRY: ghcr.io + IMAGE_NAME_MAIN: ${{ github.repository }} + IMAGE_NAME_NGINX: ${{ github.repository }}-nginx + steps: + - name: Checkout repository + uses: actions/checkout@v5 + with: + ref: ${{ github.ref_name }} + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to the Container registry + uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + # Build main + - name: Docker meta (main) + id: meta-main + uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME_MAIN }} + tags: | + type=raw,value=${{ github.ref_name }} + + - name: Build and push Docker image (main) + id: push-main + uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4 + with: + context: . + file: ./infrastructure/display-api-service/Dockerfile + build-args: | + APP_VERSION=${{ github.ref_name }} + push: true + tags: ${{ steps.meta-main.outputs.tags }} + labels: ${{ steps.meta-main.outputs.labels }} + sbom: true + + # Build Nginx (depends on main) + - name: Docker meta (nginx) + id: meta-nginx + uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME_NGINX }} + tags: | + type=raw,value=${{ github.ref_name }} + + - name: Build and push Docker image (nginx) + id: push-nginx + uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4 + with: + context: ./infrastructure/nginx/ + file: ./infrastructure/nginx/Dockerfile + build-args: | + APP_VERSION=${{ github.ref_name }} + APP_IMAGE=${{ env.IMAGE_NAME_MAIN }} + push: true + pull: true + tags: ${{ steps.meta-nginx.outputs.tags }} + labels: ${{ steps.meta-nginx.outputs.labels }} + sbom: true diff --git a/.github/workflows/itkdev_docker_build_develop.yml b/.github/workflows/itkdev_docker_build_develop.yml deleted file mode 100644 index aaef33621..000000000 --- a/.github/workflows/itkdev_docker_build_develop.yml +++ /dev/null @@ -1,60 +0,0 @@ ---- -on: - push: - branches: - - "develop" - -# This Action builds to itkdev/* using ./infrastructure/itkdev/* -name: ITK Dev - Build docker image (develop) - -jobs: - docker: - runs-on: ubuntu-latest - env: - APP_VERSION: develop - COMPOSER_ALLOW_SUPERUSER: 1 - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Login to DockerHub - uses: docker/login-action@v3 - with: - username: ${{ secrets.DOCKERHUB_USER }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - # Build api - - name: Docker meta (API) - id: meta-api - uses: docker/metadata-action@v5 - with: - images: itkdev/os2display-api-service - - - name: Build and push (API) - uses: docker/build-push-action@v5 - with: - context: ./infrastructure/itkdev/display-api-service/ - file: ./infrastructure/itkdev/display-api-service/Dockerfile - build-args: | - VERSION=${{ env.APP_VERSION }} - push: true - tags: ${{ steps.meta-api.outputs.tags }} - labels: ${{ steps.meta-api.outputs.labels }} - - # Build nginx (depends on api build) - - name: Docker meta (Nginx) - id: meta-nginx - uses: docker/metadata-action@v5 - with: - images: itkdev/os2display-api-service-nginx - - - name: Build and push (Nginx) - uses: docker/build-push-action@v5 - with: - context: ./infrastructure/itkdev/nginx/ - file: ./infrastructure/itkdev/nginx/Dockerfile - build-args: | - APP_VERSION=${{ env.APP_VERSION }} - push: true - tags: ${{ steps.meta-nginx.outputs.tags }} - labels: ${{ steps.meta-nginx.outputs.labels }} diff --git a/.github/workflows/itkdev_docker_build_tag.yml b/.github/workflows/itkdev_docker_build_tag.yml deleted file mode 100644 index f64644a28..000000000 --- a/.github/workflows/itkdev_docker_build_tag.yml +++ /dev/null @@ -1,63 +0,0 @@ ---- -on: - push: - tags: - - "*" - -# This Action builds to itkdev/* using ./infrastructure/itkdev/* -name: ITK Dev - Build docker image (tag) - -jobs: - docker: - runs-on: ubuntu-latest - env: - COMPOSER_ALLOW_SUPERUSER: 1 - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Login to DockerHub - uses: docker/login-action@v3 - with: - username: ${{ secrets.DOCKERHUB_USER }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - # Build api - - name: Docker meta (API) - id: meta-api - uses: docker/metadata-action@v5 - with: - images: itkdev/os2display-api-service - - - name: Build and push (API) - uses: docker/build-push-action@v5 - with: - context: ./infrastructure/itkdev/display-api-service/ - file: ./infrastructure/itkdev/display-api-service/Dockerfile - build-args: | - APP_VERSION=${{ github.ref }} - push: true - tags: ${{ steps.meta-api.outputs.tags }} - labels: ${{ steps.meta-api.outputs.labels }} - - # Build nginx (depends on api build) - - name: Docker meta (Nginx) - id: meta-nginx - uses: docker/metadata-action@v5 - with: - images: itkdev/os2display-api-service-nginx - - - name: Get the tag - id: get_tag - run: echo ::set-output name=git_tag::$(echo $GITHUB_REF_NAME) - - - name: Build and push (Nginx) - uses: docker/build-push-action@v5 - with: - context: ./infrastructure/itkdev/nginx/ - file: ./infrastructure/itkdev/nginx/Dockerfile - build-args: | - APP_VERSION=${{ steps.get_tag.outputs.git_tag }} - push: true - tags: ${{ steps.meta-nginx.outputs.tags }} - labels: ${{ steps.meta-nginx.outputs.labels }} diff --git a/.github/workflows/javascript.yaml b/.github/workflows/javascript.yaml index 801ddbe93..2c0317ce1 100644 --- a/.github/workflows/javascript.yaml +++ b/.github/workflows/javascript.yaml @@ -12,6 +12,7 @@ ### [Prettier](https://prettier.io/) exists. name: JavaScript +run-name: "JavaScript - ${{ github.head_ref || github.ref_name }}" on: pull_request: diff --git a/.github/workflows/markdown.yaml b/.github/workflows/markdown.yaml index 60fc0ee5c..a4b365d61 100644 --- a/.github/workflows/markdown.yaml +++ b/.github/workflows/markdown.yaml @@ -19,6 +19,7 @@ ### exists. name: Markdown +run-name: "Markdown - ${{ github.head_ref || github.ref_name }}" on: pull_request: diff --git a/.github/workflows/os2display_docker_build_tag.yml b/.github/workflows/os2display_docker_build_tag.yml deleted file mode 100644 index 8bd2b12aa..000000000 --- a/.github/workflows/os2display_docker_build_tag.yml +++ /dev/null @@ -1,63 +0,0 @@ ---- -on: - push: - tags: - - "*" - -# This Action builds to os2display/* using ./infrastructure/os2display/* -name: OS2display - Build docker image (tag) - -jobs: - docker: - runs-on: ubuntu-latest - env: - COMPOSER_ALLOW_SUPERUSER: 1 - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Login to DockerHub - uses: docker/login-action@v3 - with: - username: ${{ secrets.DOCKERHUB_USER }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - # Build api - - name: Docker meta (API) - id: meta-api - uses: docker/metadata-action@v5 - with: - images: os2display/display-api-service - - - name: Build and push (API) - uses: docker/build-push-action@v5 - with: - context: ./infrastructure/os2display/display-api-service/ - file: ./infrastructure/os2display/display-api-service/Dockerfile - build-args: | - APP_VERSION=${{ github.ref }} - push: true - tags: ${{ steps.meta-api.outputs.tags }} - labels: ${{ steps.meta-api.outputs.labels }} - - # Build nginx (depends on api build) - - name: Docker meta (Nginx) - id: meta-nginx - uses: docker/metadata-action@v5 - with: - images: os2display/display-api-service-nginx - - - name: Get the tag - id: get_tag - run: echo ::set-output name=git_tag::$(echo $GITHUB_REF_NAME) - - - name: Build and push (Nginx) - uses: docker/build-push-action@v5 - with: - context: ./infrastructure/os2display/nginx/ - file: ./infrastructure/os2display/nginx/Dockerfile - build-args: | - APP_VERSION=${{ steps.get_tag.outputs.git_tag }} - push: true - tags: ${{ steps.meta-nginx.outputs.tags }} - labels: ${{ steps.meta-nginx.outputs.labels }} diff --git a/.github/workflows/php.yaml b/.github/workflows/php.yaml index ee9679776..f62f7bd93 100644 --- a/.github/workflows/php.yaml +++ b/.github/workflows/php.yaml @@ -32,6 +32,7 @@ ### > project by adding a more important configuration file, `.php-cs-fixer.php`. name: Symfony PHP +run-name: "Symfony PHP - ${{ github.head_ref || github.ref_name }}" env: COMPOSE_USER: runner diff --git a/.github/workflows/phpunit.yaml b/.github/workflows/phpunit.yaml index 2a2e54889..d3f8334b1 100644 --- a/.github/workflows/phpunit.yaml +++ b/.github/workflows/phpunit.yaml @@ -1,6 +1,7 @@ on: pull_request name: Test +run-name: "PHPUnit - ${{ github.head_ref || github.ref_name }}" jobs: phpunit: @@ -24,7 +25,7 @@ jobs: strategy: fail-fast: false matrix: - php: ["8.3"] + php: ["8.4"] name: PHP Unit tests (PHP ${{ matrix.php }}) steps: - name: Checkout diff --git a/.github/workflows/playwright.yaml b/.github/workflows/playwright.yaml index 5b78012d6..63f7ccdeb 100644 --- a/.github/workflows/playwright.yaml +++ b/.github/workflows/playwright.yaml @@ -1,6 +1,7 @@ on: pull_request name: Test +run-name: "Playwright - ${{ github.head_ref || github.ref_name }}" env: COMPOSE_USER: runner diff --git a/.github/workflows/psalm.yaml b/.github/workflows/psalm.yaml index 6cbb222c9..ffbd118bc 100644 --- a/.github/workflows/psalm.yaml +++ b/.github/workflows/psalm.yaml @@ -1,6 +1,7 @@ on: pull_request name: Psalm +run-name: "Psalm - ${{ github.head_ref || github.ref_name }}" jobs: psalm: @@ -8,7 +9,7 @@ jobs: strategy: fail-fast: false matrix: - php: ["8.3"] + php: ["8.4"] name: Psalm (PHP ${{ matrix.php }}) steps: - name: Checkout diff --git a/.github/workflows/rector.yaml b/.github/workflows/rector.yaml index aa482e70b..9baf3a5a0 100644 --- a/.github/workflows/rector.yaml +++ b/.github/workflows/rector.yaml @@ -1,6 +1,7 @@ on: pull_request name: Rector +run-name: "Rector - ${{ github.head_ref || github.ref_name }}" jobs: rector: @@ -8,7 +9,7 @@ jobs: strategy: fail-fast: false matrix: - php: ["8.3"] + php: ["8.4"] name: Rector (PHP ${{ matrix.php }}) steps: - name: Checkout diff --git a/.github/workflows/styles.yaml b/.github/workflows/styles.yaml index edc796020..b95ddb08b 100644 --- a/.github/workflows/styles.yaml +++ b/.github/workflows/styles.yaml @@ -12,6 +12,7 @@ ### [Prettier](https://prettier.io/) exists. name: Styles +run-name: "Styles - ${{ github.head_ref || github.ref_name }}" on: pull_request: diff --git a/.github/workflows/twig.yaml b/.github/workflows/twig.yaml index 9dc424b45..62d9df81d 100644 --- a/.github/workflows/twig.yaml +++ b/.github/workflows/twig.yaml @@ -22,6 +22,7 @@ ### in the root of the project defines which files to check and rules to use. name: Twig +run-name: "Twig - ${{ github.head_ref || github.ref_name }}" env: COMPOSE_USER: runner diff --git a/.github/workflows/yaml.yaml b/.github/workflows/yaml.yaml index 1c0ada3f7..3776a90c0 100644 --- a/.github/workflows/yaml.yaml +++ b/.github/workflows/yaml.yaml @@ -19,6 +19,7 @@ ### Prettier format YAML files in the `config/` folder like Symfony expects. name: YAML +run-name: "YAML - ${{ github.head_ref || github.ref_name }}" on: pull_request: diff --git a/.gitignore b/.gitignore index 6a75d6466..521b8cb58 100644 --- a/.gitignore +++ b/.gitignore @@ -25,8 +25,6 @@ /.php-cs-fixer.cache ###< friendsofphp/php-cs-fixer ### -node_modules - public/media/* !public/media/thumbnail_video.png !public/media/thumbnail_other.png diff --git a/CHANGELOG.md b/CHANGELOG.md index 561ad259e..44f5ee5e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ All notable changes to this project will be documented in this file. - Added command to migrate config.json files. - Fix data fetching bug and tests - Refactored screen layout commands. +- Updated infrastructure and image build for mono-repo - Moved list components (search and checkboxes) around. - Aligned environment variable names. - Aligned with v. 2.6.0. diff --git a/README.md b/README.md index 379c63fab..7f5c8da73 100644 --- a/README.md +++ b/README.md @@ -9,23 +9,24 @@ 5. [Taskfile](#taskfile) 6. [Development setup](#development-setup) 7. [Production setup](#production-setup) -8. [Coding standards](#coding-standards) -9. [Stateless](#stateless) -10. [OIDC providers](#oidc-providers) -11. [JWT Auth](#jwt-auth) -12. [Test](#test) -13. [API specification and generated code](#api-specification-and-generated-code) -14. [Configuration](#configuration) -15. [Rest API & Relationships](#rest-api--relationships) -16. [Error codes in the Client](#error-codes-in-the-client) -17. [Preview mode in the Client](#preview-mode-in-the-client) -18. [Feeds](#feeds) -19. [Custom Templates](#custom-templates) -20. [Static Analysis](#static-analysis) -21. [Upgrade Guide](#upgrade-guide) -22. [Tenants](#tenants) -23. [Screen layouts](#screen-layouts) -24. [Templates](#templates) +8. [Infrastructure](#infrastructure) +9. [Coding standards](#coding-standards) +10. [Stateless](#stateless) +11. [OIDC providers](#oidc-providers) +12. [JWT Auth](#jwt-auth) +13. [Test](#test) +14. [API specification and generated code](#api-specification-and-generated-code) +15. [Configuration](#configuration) +16. [Rest API & Relationships](#rest-api--relationships) +17. [Error codes in the Client](#error-codes-in-the-client) +18. [Preview mode in the Client](#preview-mode-in-the-client) +19. [Feeds](#feeds) +20. [Custom Templates](#custom-templates) +21. [Static Analysis](#static-analysis) +22. [Upgrade Guide](#upgrade-guide) +23. [Tenants](#tenants) +24. [Screen layouts](#screen-layouts) +25. [Templates](#templates) ## Description @@ -126,10 +127,10 @@ docker compose exec phpfpm bin/console lexik:jwt:generate-keypair To get started with the development setup, run the following task command: ```shell -task site-install +task install:site # or if you want to load fixtures as well -task site-install-with-fixtures +task install:site-with-fixtures ``` If you want to load fixtures manually, use the command (`--yes` for auto-confirming): @@ -163,6 +164,19 @@ Use the `app:update` command to migrate and update templates to latest version: docker compose exec phpfpm bin/console app:update --no-interaction ``` +## Infrastructure + +When a new tag is created a GitHub release is created with built assets. + +After this, docker images are built and published in GitHub packages: + + +See for a docker based server setup, that uses these packages. + +TODO: Fix links after repository moves and renames. + +![Infrastructure overview](docs/infrastructure.png) + ## Coding standards Before a PR can be merged it has to pass the GitHub Actions checks. See `.github/workflows` for workflows that should diff --git a/Taskfile.yml b/Taskfile.yml index d0bd361af..088ee25f8 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -20,65 +20,65 @@ tasks: cmds: - "{{ .DOCKER_COMPOSE }} {{ .CLI_ARGS }}" - site-install: + install:site: prompt: "This will reset your setup. Continue?" desc: "Install new OS2Display." cmds: - task compose -- down - task compose -- pull - - task npm-install - - task compose-up - - task composer-install + - task install:npm + - task compose:up + - task install:composer - task db:migrate --yes - task fixtures:copy-assets - - task site-open + - task open silent: true - site-install-with-fixtures: + install:site-with-fixtures: prompt: "This will reset your setup. Continue?" desc: "Install new OS2Display with fixtures installed." cmds: - task compose -- down - task compose -- pull - - task npm-install - - task compose-up - - task composer-install + - task install:npm + - task compose:up + - task install:composer - task db:migrate --yes - task fixtures:load --yes - task fixtures:copy-assets - - task site-open + - task open silent: true - site-open: + open: desc: "Opens admin, docs and client." cmds: - - task site-open:admin - - task site-open:client - - task site-open:docs - - task site-open:templates + - task open:admin + - task open:client + - task open:docs + - task open:templates silent: true - site-open:admin: + open:admin: desc: "Opens admin site." cmds: - open http://{{ .BASE_URL }} - site-open:client: + open:client: desc: "Opens client site." cmds: - open http://{{ .BASE_URL }}/client - site-open:docs: + open:docs: desc: "Opens API docs page" cmds: - open http://{{ .BASE_URL }}/docs - site-open:templates: + open:templates: desc: "Opens templates site." cmds: - open http://{{ .BASE_URL }}/template - npm-install: + install:npm: desc: "Installs node dependencies with npm." cmds: - docker compose run --rm --volume "$PWD:/md" node npm install @@ -89,13 +89,13 @@ tasks: - task compose -- exec phpfpm composer {{.CLI_ARGS}} silent: true - compose-up: + compose:up: desc: "Runs docker compose up." cmds: - task compose -- up --detach --remove-orphans silent: true - composer-install: + install:composer: desc: "Installs dependencies with composer." cmds: - task composer -- install {{.COMPOSER_INSTALL_ARGUMENTS}} {{.CLI_ARGS}} @@ -177,7 +177,7 @@ tasks: desc: Apply fixtures cmds: - task compose -- exec phpfpm bin/console hautelook:fixtures:load --no-interaction - - task compose-up + - task compose:up silent: true db:migrate: @@ -185,7 +185,7 @@ tasks: desc: Run database migrations cmds: - task compose -- exec phpfpm bin/console doctrine:migrations:migrate --no-interaction - - task compose-up + - task compose:up silent: true test:api: diff --git a/composer.json b/composer.json index 3108dd75c..0cdba3b81 100644 --- a/composer.json +++ b/composer.json @@ -4,7 +4,7 @@ "license": "proprietary", "type": "project", "require": { - "php": ">=8.3", + "php": ">=8.4", "ext-ctype": "*", "ext-fileinfo": "*", "ext-gd": "*", @@ -16,7 +16,7 @@ "doctrine/doctrine-migrations-bundle": "^3.1", "doctrine/orm": "^2.9", "gesdinet/jwt-refresh-token-bundle": "^1.0", - "itk-dev/openid-connect-bundle": "^3.1", + "itk-dev/openid-connect-bundle": "^4.1", "justinrainbow/json-schema": "^5.2", "kubawerlos/php-cs-fixer-custom-fixers": "^3.11", "lexik/jwt-authentication-bundle": "^2.14", @@ -63,7 +63,7 @@ "symfony/stopwatch": "~6.4.0", "symfony/var-dumper": "~6.4.0", "symfony/web-profiler-bundle": "~6.4.0", - "vimeo/psalm": "^5.12.0", + "vimeo/psalm": "^6.13.0", "vincentlanglet/twig-cs-fixer": "^3.8", "weirdan/doctrine-psalm-plugin": "^2.0" }, diff --git a/composer.lock b/composer.lock index 846da321c..8000f6cda 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "1bd6fd456477d1e03a03bb4359ad3e77", + "content-hash": "576ea5d4c8981e57c636bbae1b3113f0", "packages": [ { "name": "api-platform/core", @@ -1481,30 +1481,29 @@ }, { "name": "doctrine/instantiator", - "version": "2.0.0", + "version": "2.1.0", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", - "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0" + "reference": "23da848e1a2308728fe5fdddabf4be17ff9720c7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/c6222283fa3f4ac679f8b9ced9a4e23f163e80d0", - "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/23da848e1a2308728fe5fdddabf4be17ff9720c7", + "reference": "23da848e1a2308728fe5fdddabf4be17ff9720c7", "shasum": "" }, "require": { - "php": "^8.1" + "php": "^8.4" }, "require-dev": { - "doctrine/coding-standard": "^11", + "doctrine/coding-standard": "^14", "ext-pdo": "*", "ext-phar": "*", "phpbench/phpbench": "^1.2", - "phpstan/phpstan": "^1.9.4", - "phpstan/phpstan-phpunit": "^1.3", - "phpunit/phpunit": "^9.5.27", - "vimeo/psalm": "^5.4" + "phpstan/phpstan": "^2.1", + "phpstan/phpstan-phpunit": "^2.0", + "phpunit/phpunit": "^10.5.58" }, "type": "library", "autoload": { @@ -1531,7 +1530,7 @@ ], "support": { "issues": "https://github.com/doctrine/instantiator/issues", - "source": "https://github.com/doctrine/instantiator/tree/2.0.0" + "source": "https://github.com/doctrine/instantiator/tree/2.1.0" }, "funding": [ { @@ -1547,7 +1546,7 @@ "type": "tidelift" } ], - "time": "2022-12-30T00:23:10+00:00" + "time": "2026-01-05T06:47:08+00:00" }, { "name": "doctrine/lexer", @@ -2091,16 +2090,16 @@ }, { "name": "firebase/php-jwt", - "version": "v6.11.1", + "version": "v7.0.4", "source": { "type": "git", "url": "https://github.com/firebase/php-jwt.git", - "reference": "d1e91ecf8c598d073d0995afa8cd5c75c6e19e66" + "reference": "e41f1bd7dbe3c5455c3f72d4338cfeb083b71931" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/firebase/php-jwt/zipball/d1e91ecf8c598d073d0995afa8cd5c75c6e19e66", - "reference": "d1e91ecf8c598d073d0995afa8cd5c75c6e19e66", + "url": "https://api.github.com/repos/firebase/php-jwt/zipball/e41f1bd7dbe3c5455c3f72d4338cfeb083b71931", + "reference": "e41f1bd7dbe3c5455c3f72d4338cfeb083b71931", "shasum": "" }, "require": { @@ -2108,6 +2107,7 @@ }, "require-dev": { "guzzlehttp/guzzle": "^7.4", + "phpfastcache/phpfastcache": "^9.2", "phpspec/prophecy-phpunit": "^2.0", "phpunit/phpunit": "^9.5", "psr/cache": "^2.0||^3.0", @@ -2148,9 +2148,9 @@ ], "support": { "issues": "https://github.com/firebase/php-jwt/issues", - "source": "https://github.com/firebase/php-jwt/tree/v6.11.1" + "source": "https://github.com/firebase/php-jwt/tree/v7.0.4" }, - "time": "2025-04-09T20:32:01+00:00" + "time": "2026-03-27T21:17:19+00:00" }, { "name": "friendsofphp/php-cs-fixer", @@ -2629,16 +2629,16 @@ }, { "name": "guzzlehttp/psr7", - "version": "2.8.0", + "version": "2.9.0", "source": { "type": "git", "url": "https://github.com/guzzle/psr7.git", - "reference": "21dc724a0583619cd1652f673303492272778051" + "reference": "7d0ed42f28e42d61352a7a79de682e5e67fec884" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/21dc724a0583619cd1652f673303492272778051", - "reference": "21dc724a0583619cd1652f673303492272778051", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/7d0ed42f28e42d61352a7a79de682e5e67fec884", + "reference": "7d0ed42f28e42d61352a7a79de682e5e67fec884", "shasum": "" }, "require": { @@ -2654,6 +2654,7 @@ "require-dev": { "bamarni/composer-bin-plugin": "^1.8.2", "http-interop/http-factory-tests": "0.9.0", + "jshttp/mime-db": "1.54.0.1", "phpunit/phpunit": "^8.5.44 || ^9.6.25" }, "suggest": { @@ -2725,7 +2726,7 @@ ], "support": { "issues": "https://github.com/guzzle/psr7/issues", - "source": "https://github.com/guzzle/psr7/tree/2.8.0" + "source": "https://github.com/guzzle/psr7/tree/2.9.0" }, "funding": [ { @@ -2741,7 +2742,7 @@ "type": "tidelift" } ], - "time": "2025-08-23T21:21:41+00:00" + "time": "2026-03-10T16:41:02+00:00" }, { "name": "imagine/imagine", @@ -2807,35 +2808,35 @@ }, { "name": "itk-dev/openid-connect", - "version": "3.2.1", + "version": "4.1.0", "source": { "type": "git", "url": "https://github.com/itk-dev/openid-connect.git", - "reference": "7bea58e5d8b338a1e0d260653ccf3f72fc2a4c2d" + "reference": "9e069c13a3b09105d67b3e364ae296dea2bbcbae" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/itk-dev/openid-connect/zipball/7bea58e5d8b338a1e0d260653ccf3f72fc2a4c2d", - "reference": "7bea58e5d8b338a1e0d260653ccf3f72fc2a4c2d", + "url": "https://api.github.com/repos/itk-dev/openid-connect/zipball/9e069c13a3b09105d67b3e364ae296dea2bbcbae", + "reference": "9e069c13a3b09105d67b3e364ae296dea2bbcbae", "shasum": "" }, "require": { "ext-json": "*", "ext-openssl": "*", - "firebase/php-jwt": "^6.8", + "firebase/php-jwt": "^7.0", "league/oauth2-client": "^2.6", - "php": "^8.1", + "php": "^8.3", "psr/cache": "^2.0 || ^3.0", "psr/http-client": "^1.0", "robrichards/xmlseclibs": "^3.1" }, "require-dev": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.7.1", - "escapestudios/symfony2-coding-standard": "^3.12", - "mockery/mockery": "^1.4", - "phpunit/php-code-coverage": "^9.2", - "phpunit/phpunit": "^9.5", - "vimeo/psalm": "^5.0" + "ergebnis/composer-normalize": "^2.50", + "friendsofphp/php-cs-fixer": "^3.75", + "mockery/mockery": "^1.6.12", + "phpstan/phpstan": "^2.1.40", + "phpunit/php-code-coverage": "^12", + "phpunit/phpunit": "^12" }, "type": "library", "autoload": { @@ -2864,45 +2865,43 @@ "description": "OpenID connect configuration package", "support": { "issues": "https://github.com/itk-dev/openid-connect/issues", - "source": "https://github.com/itk-dev/openid-connect/tree/3.2.1" + "source": "https://github.com/itk-dev/openid-connect/tree/4.1.0" }, - "time": "2023-09-18T10:24:50+00:00" + "time": "2026-03-20T10:53:12+00:00" }, { "name": "itk-dev/openid-connect-bundle", - "version": "3.1.0", + "version": "4.1.0", "source": { "type": "git", "url": "https://github.com/itk-dev/openid-connect-bundle.git", - "reference": "8ab0b9ccbe900571f0dd1c9854cd462c991b31e3" + "reference": "9e605801b027f98817aa10fbe5f33cbaa47a8fd7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/itk-dev/openid-connect-bundle/zipball/8ab0b9ccbe900571f0dd1c9854cd462c991b31e3", - "reference": "8ab0b9ccbe900571f0dd1c9854cd462c991b31e3", + "url": "https://api.github.com/repos/itk-dev/openid-connect-bundle/zipball/9e605801b027f98817aa10fbe5f33cbaa47a8fd7", + "reference": "9e605801b027f98817aa10fbe5f33cbaa47a8fd7", "shasum": "" }, "require": { - "doctrine/orm": "^2.8", + "doctrine/orm": "^2.8 || ^3.0", "ext-json": "*", "ext-openssl": "*", - "itk-dev/openid-connect": "^3.1", - "php": "^8.1", - "symfony/cache": "^5.4|^6.0", - "symfony/framework-bundle": "^5.4|^6.0", - "symfony/security-bundle": "^5.4|^6.0", - "symfony/uid": "^5.4|^6.0", - "symfony/yaml": "^5.4|^6.0" + "itk-dev/openid-connect": "^4.0", + "php": "^8.3", + "symfony/cache": "^6.4 || ^7.0 || ^8.0", + "symfony/framework-bundle": "^6.4.13 || ^7.0 || ^8.0", + "symfony/security-bundle": "^6.4.13 || ^7.0 || ^8.0", + "symfony/uid": "^6.4 || ^7.0 || ^8.0", + "symfony/yaml": "^6.4 || ^7.0 || ^8.0" }, "require-dev": { "ergebnis/composer-normalize": "^2.28", - "escapestudios/symfony2-coding-standard": "^3.12", "friendsofphp/php-cs-fixer": "^3.11", - "kubawerlos/php-cs-fixer-custom-fixers": "^3.11", - "phpunit/phpunit": "^9.5", - "psalm/plugin-symfony": "^5.0", - "rector/rector": "^0.14.2", - "vimeo/psalm": "^5.0" + "phpstan/phpstan": "^2.1", + "phpunit/phpunit": "^12.0", + "rector/rector": "^2.0", + "symfony/runtime": "^6.4.13 || ^7.0 || ^8.0" }, "type": "symfony-bundle", "autoload": { @@ -2927,9 +2926,9 @@ "description": "Symfony bundle for openid-connect", "support": { "issues": "https://github.com/itk-dev/openid-connect-bundle/issues", - "source": "https://github.com/itk-dev/openid-connect-bundle/tree/3.1.0" + "source": "https://github.com/itk-dev/openid-connect-bundle/tree/4.1.0" }, - "time": "2023-08-03T12:08:33+00:00" + "time": "2026-03-20T10:52:03+00:00" }, { "name": "jms/metadata", @@ -2997,16 +2996,16 @@ }, { "name": "justinrainbow/json-schema", - "version": "5.3.2", + "version": "5.3.3", "source": { "type": "git", "url": "https://github.com/jsonrainbow/json-schema.git", - "reference": "2f7abf648939847a789c55c206d4cb9dd0d53e2c" + "reference": "a0b7c13588b102d7d6536823e96d1c88d3dba85e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/jsonrainbow/json-schema/zipball/2f7abf648939847a789c55c206d4cb9dd0d53e2c", - "reference": "2f7abf648939847a789c55c206d4cb9dd0d53e2c", + "url": "https://api.github.com/repos/jsonrainbow/json-schema/zipball/a0b7c13588b102d7d6536823e96d1c88d3dba85e", + "reference": "a0b7c13588b102d7d6536823e96d1c88d3dba85e", "shasum": "" }, "require": { @@ -3056,22 +3055,22 @@ ], "support": { "issues": "https://github.com/jsonrainbow/json-schema/issues", - "source": "https://github.com/jsonrainbow/json-schema/tree/5.3.2" + "source": "https://github.com/jsonrainbow/json-schema/tree/5.3.3" }, - "time": "2026-02-27T12:33:19+00:00" + "time": "2026-03-24T18:47:53+00:00" }, { "name": "kubawerlos/php-cs-fixer-custom-fixers", - "version": "v3.36.0", + "version": "v3.36.1", "source": { "type": "git", "url": "https://github.com/kubawerlos/php-cs-fixer-custom-fixers.git", - "reference": "e1f97f6463f0b2a22e0dd320948a04132ff9c501" + "reference": "ec9776e80f5ea9bf0d8ec16d662e431bfab19a24" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/kubawerlos/php-cs-fixer-custom-fixers/zipball/e1f97f6463f0b2a22e0dd320948a04132ff9c501", - "reference": "e1f97f6463f0b2a22e0dd320948a04132ff9c501", + "url": "https://api.github.com/repos/kubawerlos/php-cs-fixer-custom-fixers/zipball/ec9776e80f5ea9bf0d8ec16d662e431bfab19a24", + "reference": "ec9776e80f5ea9bf0d8ec16d662e431bfab19a24", "shasum": "" }, "require": { @@ -3102,7 +3101,7 @@ "description": "A set of custom fixers for PHP CS Fixer", "support": { "issues": "https://github.com/kubawerlos/php-cs-fixer-custom-fixers/issues", - "source": "https://github.com/kubawerlos/php-cs-fixer-custom-fixers/tree/v3.36.0" + "source": "https://github.com/kubawerlos/php-cs-fixer-custom-fixers/tree/v3.36.1" }, "funding": [ { @@ -3110,7 +3109,7 @@ "type": "github" } ], - "time": "2026-01-31T07:02:11+00:00" + "time": "2026-03-07T11:35:13+00:00" }, { "name": "laminas/laminas-code", @@ -3986,16 +3985,16 @@ }, { "name": "pentatrion/vite-bundle", - "version": "v8.2.3", + "version": "v8.2.4", "source": { "type": "git", "url": "https://github.com/lhapaipai/vite-bundle.git", - "reference": "354d90eebc702950daba6adcd2b93930de61812c" + "reference": "80a5391af3a924597d65e7c81a4b28d212fea5fe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/lhapaipai/vite-bundle/zipball/354d90eebc702950daba6adcd2b93930de61812c", - "reference": "354d90eebc702950daba6adcd2b93930de61812c", + "url": "https://api.github.com/repos/lhapaipai/vite-bundle/zipball/80a5391af3a924597d65e7c81a4b28d212fea5fe", + "reference": "80a5391af3a924597d65e7c81a4b28d212fea5fe", "shasum": "" }, "require": { @@ -4041,9 +4040,9 @@ ], "support": { "issues": "https://github.com/lhapaipai/vite-bundle/issues", - "source": "https://github.com/lhapaipai/vite-bundle/tree/v8.2.3" + "source": "https://github.com/lhapaipai/vite-bundle/tree/v8.2.4" }, - "time": "2025-11-16T22:02:23+00:00" + "time": "2026-03-22T11:41:50+00:00" }, { "name": "php-http/discovery", @@ -4288,16 +4287,16 @@ }, { "name": "phpdocumentor/reflection-docblock", - "version": "5.6.6", + "version": "5.6.7", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "5cee1d3dfc2d2aa6599834520911d246f656bcb8" + "reference": "31a105931bc8ffa3a123383829772e832fd8d903" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/5cee1d3dfc2d2aa6599834520911d246f656bcb8", - "reference": "5cee1d3dfc2d2aa6599834520911d246f656bcb8", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/31a105931bc8ffa3a123383829772e832fd8d903", + "reference": "31a105931bc8ffa3a123383829772e832fd8d903", "shasum": "" }, "require": { @@ -4346,9 +4345,9 @@ "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", "support": { "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", - "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.6.6" + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.6.7" }, - "time": "2025-12-22T21:13:58+00:00" + "time": "2026-03-18T20:47:46+00:00" }, { "name": "phpdocumentor/type-resolver", @@ -5542,16 +5541,16 @@ }, { "name": "robrichards/xmlseclibs", - "version": "3.1.4", + "version": "3.1.5", "source": { "type": "git", "url": "https://github.com/robrichards/xmlseclibs.git", - "reference": "bc87389224c6de95802b505e5265b0ec2c5bcdbd" + "reference": "03062be78178cbb5e8f605cd255dc32a14981f92" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/robrichards/xmlseclibs/zipball/bc87389224c6de95802b505e5265b0ec2c5bcdbd", - "reference": "bc87389224c6de95802b505e5265b0ec2c5bcdbd", + "url": "https://api.github.com/repos/robrichards/xmlseclibs/zipball/03062be78178cbb5e8f605cd255dc32a14981f92", + "reference": "03062be78178cbb5e8f605cd255dc32a14981f92", "shasum": "" }, "require": { @@ -5578,9 +5577,9 @@ ], "support": { "issues": "https://github.com/robrichards/xmlseclibs/issues", - "source": "https://github.com/robrichards/xmlseclibs/tree/3.1.4" + "source": "https://github.com/robrichards/xmlseclibs/tree/3.1.5" }, - "time": "2025-12-08T11:57:53+00:00" + "time": "2026-03-13T10:31:56+00:00" }, { "name": "sebastian/diff", @@ -5723,16 +5722,16 @@ }, { "name": "symfony/cache", - "version": "v6.4.34", + "version": "v6.4.35", "source": { "type": "git", "url": "https://github.com/symfony/cache.git", - "reference": "a0a1690543329685c044362c873b78c6de9d4faa" + "reference": "77f5eca135d1b5471de4301b99496649e4f62878" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/cache/zipball/a0a1690543329685c044362c873b78c6de9d4faa", - "reference": "a0a1690543329685c044362c873b78c6de9d4faa", + "url": "https://api.github.com/repos/symfony/cache/zipball/77f5eca135d1b5471de4301b99496649e4f62878", + "reference": "77f5eca135d1b5471de4301b99496649e4f62878", "shasum": "" }, "require": { @@ -5799,7 +5798,7 @@ "psr6" ], "support": { - "source": "https://github.com/symfony/cache/tree/v6.4.34" + "source": "https://github.com/symfony/cache/tree/v6.4.35" }, "funding": [ { @@ -5819,7 +5818,7 @@ "type": "tidelift" } ], - "time": "2026-02-20T15:06:30+00:00" + "time": "2026-03-05T20:47:12+00:00" }, { "name": "symfony/cache-contracts", @@ -6056,16 +6055,16 @@ }, { "name": "symfony/console", - "version": "v6.4.34", + "version": "v6.4.35", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "7b1f1c37eff5910ddda2831345467e593a5120ad" + "reference": "49257c96304c508223815ee965c251e7c79e614e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/7b1f1c37eff5910ddda2831345467e593a5120ad", - "reference": "7b1f1c37eff5910ddda2831345467e593a5120ad", + "url": "https://api.github.com/repos/symfony/console/zipball/49257c96304c508223815ee965c251e7c79e614e", + "reference": "49257c96304c508223815ee965c251e7c79e614e", "shasum": "" }, "require": { @@ -6130,7 +6129,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v6.4.34" + "source": "https://github.com/symfony/console/tree/v6.4.35" }, "funding": [ { @@ -6150,20 +6149,20 @@ "type": "tidelift" } ], - "time": "2026-02-23T15:42:15+00:00" + "time": "2026-03-06T13:31:08+00:00" }, { "name": "symfony/dependency-injection", - "version": "v6.4.34", + "version": "v6.4.35", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "91e49958b8a6092e48e4711894a1aeb1b151c62a" + "reference": "d95712d0e9446b9f244b64811ffb6af7b7434213" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/91e49958b8a6092e48e4711894a1aeb1b151c62a", - "reference": "91e49958b8a6092e48e4711894a1aeb1b151c62a", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/d95712d0e9446b9f244b64811ffb6af7b7434213", + "reference": "d95712d0e9446b9f244b64811ffb6af7b7434213", "shasum": "" }, "require": { @@ -6215,7 +6214,7 @@ "description": "Allows you to standardize and centralize the way objects are constructed in your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dependency-injection/tree/v6.4.34" + "source": "https://github.com/symfony/dependency-injection/tree/v6.4.35" }, "funding": [ { @@ -6235,7 +6234,7 @@ "type": "tidelift" } ], - "time": "2026-02-24T15:33:38+00:00" + "time": "2026-02-26T12:16:01+00:00" }, { "name": "symfony/deprecation-contracts", @@ -6489,16 +6488,16 @@ }, { "name": "symfony/dotenv", - "version": "v6.4.30", + "version": "v6.4.35", "source": { "type": "git", "url": "https://github.com/symfony/dotenv.git", - "reference": "924edbc9631b75302def0258ed1697948b17baf6" + "reference": "148138ead5d7bb582e93a9cc19b134b42a370365" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dotenv/zipball/924edbc9631b75302def0258ed1697948b17baf6", - "reference": "924edbc9631b75302def0258ed1697948b17baf6", + "url": "https://api.github.com/repos/symfony/dotenv/zipball/148138ead5d7bb582e93a9cc19b134b42a370365", + "reference": "148138ead5d7bb582e93a9cc19b134b42a370365", "shasum": "" }, "require": { @@ -6543,7 +6542,7 @@ "environment" ], "support": { - "source": "https://github.com/symfony/dotenv/tree/v6.4.30" + "source": "https://github.com/symfony/dotenv/tree/v6.4.35" }, "funding": [ { @@ -6563,7 +6562,7 @@ "type": "tidelift" } ], - "time": "2025-11-14T17:33:48+00:00" + "time": "2026-02-26T10:15:49+00:00" }, { "name": "symfony/error-handler", @@ -7085,16 +7084,16 @@ }, { "name": "symfony/framework-bundle", - "version": "v6.4.34", + "version": "v6.4.35", "source": { "type": "git", "url": "https://github.com/symfony/framework-bundle.git", - "reference": "5b5d19473f22d699811a41b01cef2462bc42b238" + "reference": "2e065db347ef1c2d1d4b916c860f9782c9060221" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/5b5d19473f22d699811a41b01cef2462bc42b238", - "reference": "5b5d19473f22d699811a41b01cef2462bc42b238", + "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/2e065db347ef1c2d1d4b916c860f9782c9060221", + "reference": "2e065db347ef1c2d1d4b916c860f9782c9060221", "shasum": "" }, "require": { @@ -7214,7 +7213,7 @@ "description": "Provides a tight integration between Symfony components and the Symfony full-stack framework", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/framework-bundle/tree/v6.4.34" + "source": "https://github.com/symfony/framework-bundle/tree/v6.4.35" }, "funding": [ { @@ -7234,7 +7233,7 @@ "type": "tidelift" } ], - "time": "2026-02-24T16:00:52+00:00" + "time": "2026-03-06T11:15:58+00:00" }, { "name": "symfony/http-client", @@ -7414,16 +7413,16 @@ }, { "name": "symfony/http-foundation", - "version": "v6.4.34", + "version": "v6.4.35", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "5bb346d1b4b2a616e5c3d99b3ee4d5810735c535" + "reference": "cffffd0a2c037117b742b4f8b379a22a2a33f6d2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/5bb346d1b4b2a616e5c3d99b3ee4d5810735c535", - "reference": "5bb346d1b4b2a616e5c3d99b3ee4d5810735c535", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/cffffd0a2c037117b742b4f8b379a22a2a33f6d2", + "reference": "cffffd0a2c037117b742b4f8b379a22a2a33f6d2", "shasum": "" }, "require": { @@ -7471,7 +7470,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v6.4.34" + "source": "https://github.com/symfony/http-foundation/tree/v6.4.35" }, "funding": [ { @@ -7491,20 +7490,20 @@ "type": "tidelift" } ], - "time": "2026-02-21T15:48:41+00:00" + "time": "2026-03-06T11:15:58+00:00" }, { "name": "symfony/http-kernel", - "version": "v6.4.34", + "version": "v6.4.35", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "006a49fc4f41ee21a6ca61e69caed1c30b29f07c" + "reference": "ece1a0da7745a5243683f178155c0412c92691eb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/006a49fc4f41ee21a6ca61e69caed1c30b29f07c", - "reference": "006a49fc4f41ee21a6ca61e69caed1c30b29f07c", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/ece1a0da7745a5243683f178155c0412c92691eb", + "reference": "ece1a0da7745a5243683f178155c0412c92691eb", "shasum": "" }, "require": { @@ -7589,7 +7588,7 @@ "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v6.4.34" + "source": "https://github.com/symfony/http-kernel/tree/v6.4.35" }, "funding": [ { @@ -7609,20 +7608,20 @@ "type": "tidelift" } ], - "time": "2026-02-26T08:27:11+00:00" + "time": "2026-03-06T16:28:07+00:00" }, { "name": "symfony/mime", - "version": "v6.4.34", + "version": "v6.4.35", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "2b32fbbe10b36a8379efab6e702ad8b917151839" + "reference": "b5cce719de25bebd6345c7709774f9ac63ff5cdf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/2b32fbbe10b36a8379efab6e702ad8b917151839", - "reference": "2b32fbbe10b36a8379efab6e702ad8b917151839", + "url": "https://api.github.com/repos/symfony/mime/zipball/b5cce719de25bebd6345c7709774f9ac63ff5cdf", + "reference": "b5cce719de25bebd6345c7709774f9ac63ff5cdf", "shasum": "" }, "require": { @@ -7678,7 +7677,7 @@ "mime-type" ], "support": { - "source": "https://github.com/symfony/mime/tree/v6.4.34" + "source": "https://github.com/symfony/mime/tree/v6.4.35" }, "funding": [ { @@ -7698,7 +7697,7 @@ "type": "tidelift" } ], - "time": "2026-02-02T17:01:23+00:00" + "time": "2026-03-05T11:25:28+00:00" }, { "name": "symfony/monolog-bridge", @@ -9673,16 +9672,16 @@ }, { "name": "symfony/serializer", - "version": "v6.4.34", + "version": "v6.4.35", "source": { "type": "git", "url": "https://github.com/symfony/serializer.git", - "reference": "26446be5ec3d84c2aa16a08e195c783e3d4c2af7" + "reference": "fc13cffae86138d3624eff9013724ea1d3e796b4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/serializer/zipball/26446be5ec3d84c2aa16a08e195c783e3d4c2af7", - "reference": "26446be5ec3d84c2aa16a08e195c783e3d4c2af7", + "url": "https://api.github.com/repos/symfony/serializer/zipball/fc13cffae86138d3624eff9013724ea1d3e796b4", + "reference": "fc13cffae86138d3624eff9013724ea1d3e796b4", "shasum": "" }, "require": { @@ -9751,7 +9750,7 @@ "description": "Handles serializing and deserializing data structures, including object graphs, into array structures or other formats like XML and JSON.", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/serializer/tree/v6.4.34" + "source": "https://github.com/symfony/serializer/tree/v6.4.35" }, "funding": [ { @@ -9771,7 +9770,7 @@ "type": "tidelift" } ], - "time": "2026-02-24T16:55:33+00:00" + "time": "2026-03-06T11:03:24+00:00" }, { "name": "symfony/service-contracts", @@ -10099,16 +10098,16 @@ }, { "name": "symfony/twig-bridge", - "version": "v6.4.34", + "version": "v6.4.35", "source": { "type": "git", "url": "https://github.com/symfony/twig-bridge.git", - "reference": "5169074f4a88dfb02eeccddaba78edfdf212a9b2" + "reference": "352acf608d1c9c00692fc3bba9f445176c14ce0f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/5169074f4a88dfb02eeccddaba78edfdf212a9b2", - "reference": "5169074f4a88dfb02eeccddaba78edfdf212a9b2", + "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/352acf608d1c9c00692fc3bba9f445176c14ce0f", + "reference": "352acf608d1c9c00692fc3bba9f445176c14ce0f", "shasum": "" }, "require": { @@ -10188,7 +10187,7 @@ "description": "Provides integration for Twig with various Symfony components", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/twig-bridge/tree/v6.4.34" + "source": "https://github.com/symfony/twig-bridge/tree/v6.4.35" }, "funding": [ { @@ -10208,7 +10207,7 @@ "type": "tidelift" } ], - "time": "2026-02-23T18:17:33+00:00" + "time": "2026-03-04T15:30:31+00:00" }, { "name": "symfony/twig-bundle", @@ -10378,16 +10377,16 @@ }, { "name": "symfony/validator", - "version": "v6.4.34", + "version": "v6.4.35", "source": { "type": "git", "url": "https://github.com/symfony/validator.git", - "reference": "7c3897b7f739d4ab913481e680405ca82d08084d" + "reference": "9dc02b6c7502f7c4b68a741d2826bbec061c5953" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/validator/zipball/7c3897b7f739d4ab913481e680405ca82d08084d", - "reference": "7c3897b7f739d4ab913481e680405ca82d08084d", + "url": "https://api.github.com/repos/symfony/validator/zipball/9dc02b6c7502f7c4b68a741d2826bbec061c5953", + "reference": "9dc02b6c7502f7c4b68a741d2826bbec061c5953", "shasum": "" }, "require": { @@ -10455,7 +10454,7 @@ "description": "Provides tools to validate values", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/validator/tree/v6.4.34" + "source": "https://github.com/symfony/validator/tree/v6.4.35" }, "funding": [ { @@ -10475,7 +10474,7 @@ "type": "tidelift" } ], - "time": "2026-02-23T17:49:24+00:00" + "time": "2026-03-02T17:53:19+00:00" }, { "name": "symfony/var-dumper", @@ -10811,16 +10810,16 @@ }, { "name": "twig/twig", - "version": "v3.23.0", + "version": "v3.24.0", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "a64dc5d2cc7d6cafb9347f6cd802d0d06d0351c9" + "reference": "a6769aefb305efef849dc25c9fd1653358c148f0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/a64dc5d2cc7d6cafb9347f6cd802d0d06d0351c9", - "reference": "a64dc5d2cc7d6cafb9347f6cd802d0d06d0351c9", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/a6769aefb305efef849dc25c9fd1653358c148f0", + "reference": "a6769aefb305efef849dc25c9fd1653358c148f0", "shasum": "" }, "require": { @@ -10830,7 +10829,8 @@ "symfony/polyfill-mbstring": "^1.3" }, "require-dev": { - "phpstan/phpstan": "^2.0", + "php-cs-fixer/shim": "^3.0@stable", + "phpstan/phpstan": "^2.0@stable", "psr/container": "^1.0|^2.0", "symfony/phpunit-bridge": "^5.4.9|^6.4|^7.0" }, @@ -10874,7 +10874,7 @@ ], "support": { "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/v3.23.0" + "source": "https://github.com/twigphp/Twig/tree/v3.24.0" }, "funding": [ { @@ -10886,20 +10886,20 @@ "type": "tidelift" } ], - "time": "2026-01-23T21:00:41+00:00" + "time": "2026-03-17T21:31:11+00:00" }, { "name": "vich/uploader-bundle", - "version": "v2.9.1", + "version": "v2.9.2", "source": { "type": "git", "url": "https://github.com/dustin10/VichUploaderBundle.git", - "reference": "945939a04a33c0b78c5fbb7ead31533d85112df5" + "reference": "4b88b23cb859a121413df4a831d960a46d6fe27f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/dustin10/VichUploaderBundle/zipball/945939a04a33c0b78c5fbb7ead31533d85112df5", - "reference": "945939a04a33c0b78c5fbb7ead31533d85112df5", + "url": "https://api.github.com/repos/dustin10/VichUploaderBundle/zipball/4b88b23cb859a121413df4a831d960a46d6fe27f", + "reference": "4b88b23cb859a121413df4a831d960a46d6fe27f", "shasum": "" }, "require": { @@ -10992,9 +10992,9 @@ ], "support": { "issues": "https://github.com/dustin10/VichUploaderBundle/issues", - "source": "https://github.com/dustin10/VichUploaderBundle/tree/v2.9.1" + "source": "https://github.com/dustin10/VichUploaderBundle/tree/v2.9.2" }, - "time": "2025-12-10T08:23:38+00:00" + "time": "2026-03-12T08:18:50+00:00" }, { "name": "webmozart/assert", @@ -11114,38 +11114,36 @@ "packages-dev": [ { "name": "amphp/amp", - "version": "v2.6.5", + "version": "v3.1.1", "source": { "type": "git", "url": "https://github.com/amphp/amp.git", - "reference": "d7dda98dae26e56f3f6fcfbf1c1f819c9a993207" + "reference": "fa0ab33a6f47a82929c38d03ca47ebb71086a93f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/amphp/amp/zipball/d7dda98dae26e56f3f6fcfbf1c1f819c9a993207", - "reference": "d7dda98dae26e56f3f6fcfbf1c1f819c9a993207", + "url": "https://api.github.com/repos/amphp/amp/zipball/fa0ab33a6f47a82929c38d03ca47ebb71086a93f", + "reference": "fa0ab33a6f47a82929c38d03ca47ebb71086a93f", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=8.1", + "revolt/event-loop": "^1 || ^0.2" }, "require-dev": { - "amphp/php-cs-fixer-config": "dev-master", - "amphp/phpunit-util": "^1", - "ext-json": "*", - "jetbrains/phpstorm-stubs": "^2019.3", - "phpunit/phpunit": "^7 | ^8 | ^9", - "react/promise": "^2", - "vimeo/psalm": "^3.12" + "amphp/php-cs-fixer-config": "^2", + "phpunit/phpunit": "^9", + "psalm/phar": "5.23.1" }, "type": "library", "autoload": { "files": [ - "lib/functions.php", - "lib/Internal/functions.php" + "src/functions.php", + "src/Future/functions.php", + "src/Internal/functions.php" ], "psr-4": { - "Amp\\": "lib" + "Amp\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -11153,10 +11151,6 @@ "MIT" ], "authors": [ - { - "name": "Daniel Lowrey", - "email": "rdlowrey@php.net" - }, { "name": "Aaron Piotrowski", "email": "aaron@trowski.com" @@ -11168,6 +11162,10 @@ { "name": "Niklas Keller", "email": "me@kelunik.com" + }, + { + "name": "Daniel Lowrey", + "email": "rdlowrey@php.net" } ], "description": "A non-blocking concurrency framework for PHP applications.", @@ -11184,9 +11182,8 @@ "promise" ], "support": { - "irc": "irc://irc.freenode.org/amphp", "issues": "https://github.com/amphp/amp/issues", - "source": "https://github.com/amphp/amp/tree/v2.6.5" + "source": "https://github.com/amphp/amp/tree/v3.1.1" }, "funding": [ { @@ -11194,41 +11191,45 @@ "type": "github" } ], - "time": "2025-09-03T19:41:28+00:00" + "time": "2025-08-27T21:42:00+00:00" }, { "name": "amphp/byte-stream", - "version": "v1.8.2", + "version": "v2.1.2", "source": { "type": "git", "url": "https://github.com/amphp/byte-stream.git", - "reference": "4f0e968ba3798a423730f567b1b50d3441c16ddc" + "reference": "55a6bd071aec26fa2a3e002618c20c35e3df1b46" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/amphp/byte-stream/zipball/4f0e968ba3798a423730f567b1b50d3441c16ddc", - "reference": "4f0e968ba3798a423730f567b1b50d3441c16ddc", + "url": "https://api.github.com/repos/amphp/byte-stream/zipball/55a6bd071aec26fa2a3e002618c20c35e3df1b46", + "reference": "55a6bd071aec26fa2a3e002618c20c35e3df1b46", "shasum": "" }, "require": { - "amphp/amp": "^2", - "php": ">=7.1" + "amphp/amp": "^3", + "amphp/parser": "^1.1", + "amphp/pipeline": "^1", + "amphp/serialization": "^1", + "amphp/sync": "^2", + "php": ">=8.1", + "revolt/event-loop": "^1 || ^0.2.3" }, "require-dev": { - "amphp/php-cs-fixer-config": "dev-master", - "amphp/phpunit-util": "^1.4", - "friendsofphp/php-cs-fixer": "^2.3", - "jetbrains/phpstorm-stubs": "^2019.3", - "phpunit/phpunit": "^6 || ^7 || ^8", - "psalm/phar": "^3.11.4" + "amphp/php-cs-fixer-config": "^2", + "amphp/phpunit-util": "^3", + "phpunit/phpunit": "^9", + "psalm/phar": "5.22.1" }, "type": "library", "autoload": { "files": [ - "lib/functions.php" + "src/functions.php", + "src/Internal/functions.php" ], "psr-4": { - "Amp\\ByteStream\\": "lib" + "Amp\\ByteStream\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -11257,7 +11258,7 @@ ], "support": { "issues": "https://github.com/amphp/byte-stream/issues", - "source": "https://github.com/amphp/byte-stream/tree/v1.8.2" + "source": "https://github.com/amphp/byte-stream/tree/v2.1.2" }, "funding": [ { @@ -11265,94 +11266,112 @@ "type": "github" } ], - "time": "2024-04-13T18:00:56+00:00" + "time": "2025-03-16T17:10:27+00:00" }, { - "name": "dnoegel/php-xdg-base-dir", - "version": "v0.1.1", + "name": "amphp/cache", + "version": "v2.0.1", "source": { "type": "git", - "url": "https://github.com/dnoegel/php-xdg-base-dir.git", - "reference": "8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd" + "url": "https://github.com/amphp/cache.git", + "reference": "46912e387e6aa94933b61ea1ead9cf7540b7797c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/dnoegel/php-xdg-base-dir/zipball/8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd", - "reference": "8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd", + "url": "https://api.github.com/repos/amphp/cache/zipball/46912e387e6aa94933b61ea1ead9cf7540b7797c", + "reference": "46912e387e6aa94933b61ea1ead9cf7540b7797c", "shasum": "" }, "require": { - "php": ">=5.3.2" + "amphp/amp": "^3", + "amphp/serialization": "^1", + "amphp/sync": "^2", + "php": ">=8.1", + "revolt/event-loop": "^1 || ^0.2" }, "require-dev": { - "phpunit/phpunit": "~7.0|~6.0|~5.0|~4.8.35" + "amphp/php-cs-fixer-config": "^2", + "amphp/phpunit-util": "^3", + "phpunit/phpunit": "^9", + "psalm/phar": "^5.4" }, "type": "library", "autoload": { "psr-4": { - "XdgBaseDir\\": "src/" + "Amp\\Cache\\": "src" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "description": "implementation of xdg base directory specification for php", + "authors": [ + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + }, + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + }, + { + "name": "Daniel Lowrey", + "email": "rdlowrey@php.net" + } + ], + "description": "A fiber-aware cache API based on Amp and Revolt.", + "homepage": "https://amphp.org/cache", "support": { - "issues": "https://github.com/dnoegel/php-xdg-base-dir/issues", - "source": "https://github.com/dnoegel/php-xdg-base-dir/tree/v0.1.1" + "issues": "https://github.com/amphp/cache/issues", + "source": "https://github.com/amphp/cache/tree/v2.0.1" }, - "time": "2019-12-04T15:06:13+00:00" + "funding": [ + { + "url": "https://github.com/amphp", + "type": "github" + } + ], + "time": "2024-04-19T03:38:06+00:00" }, { - "name": "doctrine/data-fixtures", - "version": "1.8.2", + "name": "amphp/dns", + "version": "v2.4.0", "source": { "type": "git", - "url": "https://github.com/doctrine/data-fixtures.git", - "reference": "6fb221da56dae2011b33d47508e3b8aeb1d91db5" + "url": "https://github.com/amphp/dns.git", + "reference": "78eb3db5fc69bf2fc0cb503c4fcba667bc223c71" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/data-fixtures/zipball/6fb221da56dae2011b33d47508e3b8aeb1d91db5", - "reference": "6fb221da56dae2011b33d47508e3b8aeb1d91db5", + "url": "https://api.github.com/repos/amphp/dns/zipball/78eb3db5fc69bf2fc0cb503c4fcba667bc223c71", + "reference": "78eb3db5fc69bf2fc0cb503c4fcba667bc223c71", "shasum": "" }, "require": { - "doctrine/deprecations": "^0.5.3 || ^1.0", - "doctrine/persistence": "^2.0 || ^3.0", - "php": "^7.4 || ^8.0", - "symfony/polyfill-php80": "^1" - }, - "conflict": { - "doctrine/dbal": "<3.5 || >=5", - "doctrine/orm": "<2.14 || >=4", - "doctrine/phpcr-odm": "<1.3.0" + "amphp/amp": "^3", + "amphp/byte-stream": "^2", + "amphp/cache": "^2", + "amphp/parser": "^1", + "amphp/process": "^2", + "daverandom/libdns": "^2.0.2", + "ext-filter": "*", + "ext-json": "*", + "php": ">=8.1", + "revolt/event-loop": "^1 || ^0.2" }, "require-dev": { - "doctrine/annotations": "^1.12 || ^2", - "doctrine/coding-standard": "^13", - "doctrine/dbal": "^3.5 || ^4", - "doctrine/mongodb-odm": "^1.3.0 || ^2.0.0", - "doctrine/orm": "^2.14 || ^3", - "ext-sqlite3": "*", - "fig/log-test": "^1", - "phpstan/phpstan": "2.1.17", - "phpunit/phpunit": "^9.6.13 || 10.5.45", - "psr/log": "^1.1 || ^2 || ^3", - "symfony/cache": "^5.4 || ^6.3 || ^7", - "symfony/var-exporter": "^5.4 || ^6.3 || ^7" - }, - "suggest": { - "alcaeus/mongo-php-adapter": "For using MongoDB ODM 1.3 with PHP 7 (deprecated)", - "doctrine/mongodb-odm": "For loading MongoDB ODM fixtures", - "doctrine/orm": "For loading ORM fixtures", - "doctrine/phpcr-odm": "For loading PHPCR ODM fixtures" + "amphp/php-cs-fixer-config": "^2", + "amphp/phpunit-util": "^3", + "phpunit/phpunit": "^9", + "psalm/phar": "5.20" }, "type": "library", "autoload": { + "files": [ + "src/functions.php" + ], "psr-4": { - "Doctrine\\Common\\DataFixtures\\": "src" + "Amp\\Dns\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -11361,91 +11380,91 @@ ], "authors": [ { - "name": "Jonathan Wage", - "email": "jonwage@gmail.com" + "name": "Chris Wright", + "email": "addr@daverandom.com" + }, + { + "name": "Daniel Lowrey", + "email": "rdlowrey@php.net" + }, + { + "name": "Bob Weinand", + "email": "bobwei9@hotmail.com" + }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + }, + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" } ], - "description": "Data Fixtures for all Doctrine Object Managers", - "homepage": "https://www.doctrine-project.org", + "description": "Async DNS resolution for Amp.", + "homepage": "https://github.com/amphp/dns", "keywords": [ - "database" + "amp", + "amphp", + "async", + "client", + "dns", + "resolve" ], "support": { - "issues": "https://github.com/doctrine/data-fixtures/issues", - "source": "https://github.com/doctrine/data-fixtures/tree/1.8.2" + "issues": "https://github.com/amphp/dns/issues", + "source": "https://github.com/amphp/dns/tree/v2.4.0" }, "funding": [ { - "url": "https://www.doctrine-project.org/sponsorship.html", - "type": "custom" - }, - { - "url": "https://www.patreon.com/phpdoctrine", - "type": "patreon" - }, - { - "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fdata-fixtures", - "type": "tidelift" + "url": "https://github.com/amphp", + "type": "github" } ], - "time": "2025-06-10T07:00:05+00:00" + "time": "2025-01-19T15:43:40+00:00" }, { - "name": "ergebnis/composer-normalize", - "version": "2.50.0", + "name": "amphp/parallel", + "version": "v2.3.3", "source": { "type": "git", - "url": "https://github.com/ergebnis/composer-normalize.git", - "reference": "80971fe24ff10709789942bcbe9368b2c704097c" + "url": "https://github.com/amphp/parallel.git", + "reference": "296b521137a54d3a02425b464e5aee4c93db2c60" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ergebnis/composer-normalize/zipball/80971fe24ff10709789942bcbe9368b2c704097c", - "reference": "80971fe24ff10709789942bcbe9368b2c704097c", + "url": "https://api.github.com/repos/amphp/parallel/zipball/296b521137a54d3a02425b464e5aee4c93db2c60", + "reference": "296b521137a54d3a02425b464e5aee4c93db2c60", "shasum": "" }, "require": { - "composer-plugin-api": "^2.0.0", - "ergebnis/json": "^1.4.0", - "ergebnis/json-normalizer": "^4.9.0", - "ergebnis/json-printer": "^3.7.0", - "ext-json": "*", - "justinrainbow/json-schema": "^5.2.12 || ^6.0.0", - "localheinz/diff": "^1.3.0", - "php": "~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0" + "amphp/amp": "^3", + "amphp/byte-stream": "^2", + "amphp/cache": "^2", + "amphp/parser": "^1", + "amphp/pipeline": "^1", + "amphp/process": "^2", + "amphp/serialization": "^1", + "amphp/socket": "^2", + "amphp/sync": "^2", + "php": ">=8.1", + "revolt/event-loop": "^1" }, "require-dev": { - "composer/composer": "^2.9.4", - "ergebnis/license": "^2.7.0", - "ergebnis/php-cs-fixer-config": "^6.59.0", - "ergebnis/phpstan-rules": "^2.13.1", - "ergebnis/phpunit-slow-test-detector": "^2.20.0", - "ergebnis/rector-rules": "^1.9.0", - "fakerphp/faker": "^1.24.1", - "phpstan/extension-installer": "^1.4.3", - "phpstan/phpstan": "^2.1.38", - "phpstan/phpstan-deprecation-rules": "^2.0.3", - "phpstan/phpstan-phpunit": "^2.0.12", - "phpstan/phpstan-strict-rules": "^2.0.8", - "phpunit/phpunit": "^9.6.33", - "rector/rector": "^2.3.5", - "symfony/filesystem": "^5.4.41" - }, - "type": "composer-plugin", - "extra": { - "class": "Ergebnis\\Composer\\Normalize\\NormalizePlugin", - "branch-alias": { - "dev-main": "2.49-dev" - }, - "plugin-optional": true, - "composer-normalize": { - "indent-size": 2, - "indent-style": "space" - } + "amphp/php-cs-fixer-config": "^2", + "amphp/phpunit-util": "^3", + "phpunit/phpunit": "^9", + "psalm/phar": "^5.18" }, + "type": "library", "autoload": { + "files": [ + "src/Context/functions.php", + "src/Context/Internal/functions.php", + "src/Ipc/functions.php", + "src/Worker/functions.php" + ], "psr-4": { - "Ergebnis\\Composer\\Normalize\\": "src/" + "Amp\\Parallel\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -11454,63 +11473,793 @@ ], "authors": [ { - "name": "Andreas Möller", - "email": "am@localheinz.com", - "homepage": "https://localheinz.com" + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + }, + { + "name": "Stephen Coakley", + "email": "me@stephencoakley.com" } ], - "description": "Provides a composer plugin for normalizing composer.json.", - "homepage": "https://github.com/ergebnis/composer-normalize", + "description": "Parallel processing component for Amp.", + "homepage": "https://github.com/amphp/parallel", "keywords": [ - "composer", - "normalize", - "normalizer", - "plugin" + "async", + "asynchronous", + "concurrent", + "multi-processing", + "multi-threading" ], "support": { - "issues": "https://github.com/ergebnis/composer-normalize/issues", - "security": "https://github.com/ergebnis/composer-normalize/blob/main/.github/SECURITY.md", - "source": "https://github.com/ergebnis/composer-normalize" + "issues": "https://github.com/amphp/parallel/issues", + "source": "https://github.com/amphp/parallel/tree/v2.3.3" }, - "time": "2026-02-09T20:57:47+00:00" + "funding": [ + { + "url": "https://github.com/amphp", + "type": "github" + } + ], + "time": "2025-11-15T06:23:42+00:00" }, { - "name": "ergebnis/json", - "version": "1.6.0", + "name": "amphp/parser", + "version": "v1.1.1", "source": { "type": "git", - "url": "https://github.com/ergebnis/json.git", - "reference": "7b56d2b5d9e897e75b43e2e753075a0904c921b1" + "url": "https://github.com/amphp/parser.git", + "reference": "3cf1f8b32a0171d4b1bed93d25617637a77cded7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ergebnis/json/zipball/7b56d2b5d9e897e75b43e2e753075a0904c921b1", - "reference": "7b56d2b5d9e897e75b43e2e753075a0904c921b1", + "url": "https://api.github.com/repos/amphp/parser/zipball/3cf1f8b32a0171d4b1bed93d25617637a77cded7", + "reference": "3cf1f8b32a0171d4b1bed93d25617637a77cded7", "shasum": "" }, "require": { - "ext-json": "*", - "php": "~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0" + "php": ">=7.4" }, "require-dev": { - "ergebnis/composer-normalize": "^2.44.0", - "ergebnis/data-provider": "^3.3.0", - "ergebnis/license": "^2.5.0", - "ergebnis/php-cs-fixer-config": "^6.37.0", - "ergebnis/phpstan-rules": "^2.11.0", - "ergebnis/phpunit-slow-test-detector": "^2.16.1", - "fakerphp/faker": "^1.24.0", - "infection/infection": "~0.26.6", - "phpstan/extension-installer": "^1.4.3", - "phpstan/phpstan": "^2.1.22", - "phpstan/phpstan-deprecation-rules": "^2.0.3", - "phpstan/phpstan-phpunit": "^2.0.7", - "phpstan/phpstan-strict-rules": "^2.0.6", - "phpunit/phpunit": "^9.6.24", - "rector/rector": "^2.1.4" + "amphp/php-cs-fixer-config": "^2", + "phpunit/phpunit": "^9", + "psalm/phar": "^5.4" }, "type": "library", - "extra": { + "autoload": { + "psr-4": { + "Amp\\Parser\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + } + ], + "description": "A generator parser to make streaming parsers simple.", + "homepage": "https://github.com/amphp/parser", + "keywords": [ + "async", + "non-blocking", + "parser", + "stream" + ], + "support": { + "issues": "https://github.com/amphp/parser/issues", + "source": "https://github.com/amphp/parser/tree/v1.1.1" + }, + "funding": [ + { + "url": "https://github.com/amphp", + "type": "github" + } + ], + "time": "2024-03-21T19:16:53+00:00" + }, + { + "name": "amphp/pipeline", + "version": "v1.2.3", + "source": { + "type": "git", + "url": "https://github.com/amphp/pipeline.git", + "reference": "7b52598c2e9105ebcddf247fc523161581930367" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/pipeline/zipball/7b52598c2e9105ebcddf247fc523161581930367", + "reference": "7b52598c2e9105ebcddf247fc523161581930367", + "shasum": "" + }, + "require": { + "amphp/amp": "^3", + "php": ">=8.1", + "revolt/event-loop": "^1" + }, + "require-dev": { + "amphp/php-cs-fixer-config": "^2", + "amphp/phpunit-util": "^3", + "phpunit/phpunit": "^9", + "psalm/phar": "^5.18" + }, + "type": "library", + "autoload": { + "psr-4": { + "Amp\\Pipeline\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + } + ], + "description": "Asynchronous iterators and operators.", + "homepage": "https://amphp.org/pipeline", + "keywords": [ + "amp", + "amphp", + "async", + "io", + "iterator", + "non-blocking" + ], + "support": { + "issues": "https://github.com/amphp/pipeline/issues", + "source": "https://github.com/amphp/pipeline/tree/v1.2.3" + }, + "funding": [ + { + "url": "https://github.com/amphp", + "type": "github" + } + ], + "time": "2025-03-16T16:33:53+00:00" + }, + { + "name": "amphp/process", + "version": "v2.0.3", + "source": { + "type": "git", + "url": "https://github.com/amphp/process.git", + "reference": "52e08c09dec7511d5fbc1fb00d3e4e79fc77d58d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/process/zipball/52e08c09dec7511d5fbc1fb00d3e4e79fc77d58d", + "reference": "52e08c09dec7511d5fbc1fb00d3e4e79fc77d58d", + "shasum": "" + }, + "require": { + "amphp/amp": "^3", + "amphp/byte-stream": "^2", + "amphp/sync": "^2", + "php": ">=8.1", + "revolt/event-loop": "^1 || ^0.2" + }, + "require-dev": { + "amphp/php-cs-fixer-config": "^2", + "amphp/phpunit-util": "^3", + "phpunit/phpunit": "^9", + "psalm/phar": "^5.4" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Amp\\Process\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bob Weinand", + "email": "bobwei9@hotmail.com" + }, + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + } + ], + "description": "A fiber-aware process manager based on Amp and Revolt.", + "homepage": "https://amphp.org/process", + "support": { + "issues": "https://github.com/amphp/process/issues", + "source": "https://github.com/amphp/process/tree/v2.0.3" + }, + "funding": [ + { + "url": "https://github.com/amphp", + "type": "github" + } + ], + "time": "2024-04-19T03:13:44+00:00" + }, + { + "name": "amphp/serialization", + "version": "v1.0.0", + "source": { + "type": "git", + "url": "https://github.com/amphp/serialization.git", + "reference": "693e77b2fb0b266c3c7d622317f881de44ae94a1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/serialization/zipball/693e77b2fb0b266c3c7d622317f881de44ae94a1", + "reference": "693e77b2fb0b266c3c7d622317f881de44ae94a1", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "require-dev": { + "amphp/php-cs-fixer-config": "dev-master", + "phpunit/phpunit": "^9 || ^8 || ^7" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Amp\\Serialization\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + } + ], + "description": "Serialization tools for IPC and data storage in PHP.", + "homepage": "https://github.com/amphp/serialization", + "keywords": [ + "async", + "asynchronous", + "serialization", + "serialize" + ], + "support": { + "issues": "https://github.com/amphp/serialization/issues", + "source": "https://github.com/amphp/serialization/tree/master" + }, + "time": "2020-03-25T21:39:07+00:00" + }, + { + "name": "amphp/socket", + "version": "v2.3.1", + "source": { + "type": "git", + "url": "https://github.com/amphp/socket.git", + "reference": "58e0422221825b79681b72c50c47a930be7bf1e1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/socket/zipball/58e0422221825b79681b72c50c47a930be7bf1e1", + "reference": "58e0422221825b79681b72c50c47a930be7bf1e1", + "shasum": "" + }, + "require": { + "amphp/amp": "^3", + "amphp/byte-stream": "^2", + "amphp/dns": "^2", + "ext-openssl": "*", + "kelunik/certificate": "^1.1", + "league/uri": "^6.5 | ^7", + "league/uri-interfaces": "^2.3 | ^7", + "php": ">=8.1", + "revolt/event-loop": "^1 || ^0.2" + }, + "require-dev": { + "amphp/php-cs-fixer-config": "^2", + "amphp/phpunit-util": "^3", + "amphp/process": "^2", + "phpunit/phpunit": "^9", + "psalm/phar": "5.20" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions.php", + "src/Internal/functions.php", + "src/SocketAddress/functions.php" + ], + "psr-4": { + "Amp\\Socket\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Daniel Lowrey", + "email": "rdlowrey@gmail.com" + }, + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + } + ], + "description": "Non-blocking socket connection / server implementations based on Amp and Revolt.", + "homepage": "https://github.com/amphp/socket", + "keywords": [ + "amp", + "async", + "encryption", + "non-blocking", + "sockets", + "tcp", + "tls" + ], + "support": { + "issues": "https://github.com/amphp/socket/issues", + "source": "https://github.com/amphp/socket/tree/v2.3.1" + }, + "funding": [ + { + "url": "https://github.com/amphp", + "type": "github" + } + ], + "time": "2024-04-21T14:33:03+00:00" + }, + { + "name": "amphp/sync", + "version": "v2.3.0", + "source": { + "type": "git", + "url": "https://github.com/amphp/sync.git", + "reference": "217097b785130d77cfcc58ff583cf26cd1770bf1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/sync/zipball/217097b785130d77cfcc58ff583cf26cd1770bf1", + "reference": "217097b785130d77cfcc58ff583cf26cd1770bf1", + "shasum": "" + }, + "require": { + "amphp/amp": "^3", + "amphp/pipeline": "^1", + "amphp/serialization": "^1", + "php": ">=8.1", + "revolt/event-loop": "^1 || ^0.2" + }, + "require-dev": { + "amphp/php-cs-fixer-config": "^2", + "amphp/phpunit-util": "^3", + "phpunit/phpunit": "^9", + "psalm/phar": "5.23" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Amp\\Sync\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + }, + { + "name": "Stephen Coakley", + "email": "me@stephencoakley.com" + } + ], + "description": "Non-blocking synchronization primitives for PHP based on Amp and Revolt.", + "homepage": "https://github.com/amphp/sync", + "keywords": [ + "async", + "asynchronous", + "mutex", + "semaphore", + "synchronization" + ], + "support": { + "issues": "https://github.com/amphp/sync/issues", + "source": "https://github.com/amphp/sync/tree/v2.3.0" + }, + "funding": [ + { + "url": "https://github.com/amphp", + "type": "github" + } + ], + "time": "2024-08-03T19:31:26+00:00" + }, + { + "name": "danog/advanced-json-rpc", + "version": "v3.2.3", + "source": { + "type": "git", + "url": "https://github.com/danog/php-advanced-json-rpc.git", + "reference": "ae703ea7b4811797a10590b6078de05b3b33dd91" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/danog/php-advanced-json-rpc/zipball/ae703ea7b4811797a10590b6078de05b3b33dd91", + "reference": "ae703ea7b4811797a10590b6078de05b3b33dd91", + "shasum": "" + }, + "require": { + "netresearch/jsonmapper": "^5", + "php": ">=8.1", + "phpdocumentor/reflection-docblock": "^4.3.4 || ^5.0.0 || ^6" + }, + "replace": { + "felixfbecker/php-advanced-json-rpc": "^3" + }, + "require-dev": { + "phpunit/phpunit": "^9" + }, + "type": "library", + "autoload": { + "psr-4": { + "AdvancedJsonRpc\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "ISC" + ], + "authors": [ + { + "name": "Felix Becker", + "email": "felix.b@outlook.com" + }, + { + "name": "Daniil Gentili", + "email": "daniil@daniil.it" + } + ], + "description": "A more advanced JSONRPC implementation", + "support": { + "issues": "https://github.com/danog/php-advanced-json-rpc/issues", + "source": "https://github.com/danog/php-advanced-json-rpc/tree/v3.2.3" + }, + "time": "2026-01-12T21:07:10+00:00" + }, + { + "name": "daverandom/libdns", + "version": "v2.1.0", + "source": { + "type": "git", + "url": "https://github.com/DaveRandom/LibDNS.git", + "reference": "b84c94e8fe6b7ee4aecfe121bfe3b6177d303c8a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/DaveRandom/LibDNS/zipball/b84c94e8fe6b7ee4aecfe121bfe3b6177d303c8a", + "reference": "b84c94e8fe6b7ee4aecfe121bfe3b6177d303c8a", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "php": ">=7.1" + }, + "suggest": { + "ext-intl": "Required for IDN support" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "LibDNS\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "DNS protocol implementation written in pure PHP", + "keywords": [ + "dns" + ], + "support": { + "issues": "https://github.com/DaveRandom/LibDNS/issues", + "source": "https://github.com/DaveRandom/LibDNS/tree/v2.1.0" + }, + "time": "2024-04-12T12:12:48+00:00" + }, + { + "name": "dnoegel/php-xdg-base-dir", + "version": "v0.1.1", + "source": { + "type": "git", + "url": "https://github.com/dnoegel/php-xdg-base-dir.git", + "reference": "8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dnoegel/php-xdg-base-dir/zipball/8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd", + "reference": "8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "require-dev": { + "phpunit/phpunit": "~7.0|~6.0|~5.0|~4.8.35" + }, + "type": "library", + "autoload": { + "psr-4": { + "XdgBaseDir\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "implementation of xdg base directory specification for php", + "support": { + "issues": "https://github.com/dnoegel/php-xdg-base-dir/issues", + "source": "https://github.com/dnoegel/php-xdg-base-dir/tree/v0.1.1" + }, + "time": "2019-12-04T15:06:13+00:00" + }, + { + "name": "doctrine/data-fixtures", + "version": "1.8.2", + "source": { + "type": "git", + "url": "https://github.com/doctrine/data-fixtures.git", + "reference": "6fb221da56dae2011b33d47508e3b8aeb1d91db5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/data-fixtures/zipball/6fb221da56dae2011b33d47508e3b8aeb1d91db5", + "reference": "6fb221da56dae2011b33d47508e3b8aeb1d91db5", + "shasum": "" + }, + "require": { + "doctrine/deprecations": "^0.5.3 || ^1.0", + "doctrine/persistence": "^2.0 || ^3.0", + "php": "^7.4 || ^8.0", + "symfony/polyfill-php80": "^1" + }, + "conflict": { + "doctrine/dbal": "<3.5 || >=5", + "doctrine/orm": "<2.14 || >=4", + "doctrine/phpcr-odm": "<1.3.0" + }, + "require-dev": { + "doctrine/annotations": "^1.12 || ^2", + "doctrine/coding-standard": "^13", + "doctrine/dbal": "^3.5 || ^4", + "doctrine/mongodb-odm": "^1.3.0 || ^2.0.0", + "doctrine/orm": "^2.14 || ^3", + "ext-sqlite3": "*", + "fig/log-test": "^1", + "phpstan/phpstan": "2.1.17", + "phpunit/phpunit": "^9.6.13 || 10.5.45", + "psr/log": "^1.1 || ^2 || ^3", + "symfony/cache": "^5.4 || ^6.3 || ^7", + "symfony/var-exporter": "^5.4 || ^6.3 || ^7" + }, + "suggest": { + "alcaeus/mongo-php-adapter": "For using MongoDB ODM 1.3 with PHP 7 (deprecated)", + "doctrine/mongodb-odm": "For loading MongoDB ODM fixtures", + "doctrine/orm": "For loading ORM fixtures", + "doctrine/phpcr-odm": "For loading PHPCR ODM fixtures" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Common\\DataFixtures\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + } + ], + "description": "Data Fixtures for all Doctrine Object Managers", + "homepage": "https://www.doctrine-project.org", + "keywords": [ + "database" + ], + "support": { + "issues": "https://github.com/doctrine/data-fixtures/issues", + "source": "https://github.com/doctrine/data-fixtures/tree/1.8.2" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fdata-fixtures", + "type": "tidelift" + } + ], + "time": "2025-06-10T07:00:05+00:00" + }, + { + "name": "ergebnis/composer-normalize", + "version": "2.50.0", + "source": { + "type": "git", + "url": "https://github.com/ergebnis/composer-normalize.git", + "reference": "80971fe24ff10709789942bcbe9368b2c704097c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ergebnis/composer-normalize/zipball/80971fe24ff10709789942bcbe9368b2c704097c", + "reference": "80971fe24ff10709789942bcbe9368b2c704097c", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^2.0.0", + "ergebnis/json": "^1.4.0", + "ergebnis/json-normalizer": "^4.9.0", + "ergebnis/json-printer": "^3.7.0", + "ext-json": "*", + "justinrainbow/json-schema": "^5.2.12 || ^6.0.0", + "localheinz/diff": "^1.3.0", + "php": "~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0" + }, + "require-dev": { + "composer/composer": "^2.9.4", + "ergebnis/license": "^2.7.0", + "ergebnis/php-cs-fixer-config": "^6.59.0", + "ergebnis/phpstan-rules": "^2.13.1", + "ergebnis/phpunit-slow-test-detector": "^2.20.0", + "ergebnis/rector-rules": "^1.9.0", + "fakerphp/faker": "^1.24.1", + "phpstan/extension-installer": "^1.4.3", + "phpstan/phpstan": "^2.1.38", + "phpstan/phpstan-deprecation-rules": "^2.0.3", + "phpstan/phpstan-phpunit": "^2.0.12", + "phpstan/phpstan-strict-rules": "^2.0.8", + "phpunit/phpunit": "^9.6.33", + "rector/rector": "^2.3.5", + "symfony/filesystem": "^5.4.41" + }, + "type": "composer-plugin", + "extra": { + "class": "Ergebnis\\Composer\\Normalize\\NormalizePlugin", + "branch-alias": { + "dev-main": "2.49-dev" + }, + "plugin-optional": true, + "composer-normalize": { + "indent-size": 2, + "indent-style": "space" + } + }, + "autoload": { + "psr-4": { + "Ergebnis\\Composer\\Normalize\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Andreas Möller", + "email": "am@localheinz.com", + "homepage": "https://localheinz.com" + } + ], + "description": "Provides a composer plugin for normalizing composer.json.", + "homepage": "https://github.com/ergebnis/composer-normalize", + "keywords": [ + "composer", + "normalize", + "normalizer", + "plugin" + ], + "support": { + "issues": "https://github.com/ergebnis/composer-normalize/issues", + "security": "https://github.com/ergebnis/composer-normalize/blob/main/.github/SECURITY.md", + "source": "https://github.com/ergebnis/composer-normalize" + }, + "time": "2026-02-09T20:57:47+00:00" + }, + { + "name": "ergebnis/json", + "version": "1.6.0", + "source": { + "type": "git", + "url": "https://github.com/ergebnis/json.git", + "reference": "7b56d2b5d9e897e75b43e2e753075a0904c921b1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ergebnis/json/zipball/7b56d2b5d9e897e75b43e2e753075a0904c921b1", + "reference": "7b56d2b5d9e897e75b43e2e753075a0904c921b1", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": "~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0" + }, + "require-dev": { + "ergebnis/composer-normalize": "^2.44.0", + "ergebnis/data-provider": "^3.3.0", + "ergebnis/license": "^2.5.0", + "ergebnis/php-cs-fixer-config": "^6.37.0", + "ergebnis/phpstan-rules": "^2.11.0", + "ergebnis/phpunit-slow-test-detector": "^2.16.1", + "fakerphp/faker": "^1.24.0", + "infection/infection": "~0.26.6", + "phpstan/extension-installer": "^1.4.3", + "phpstan/phpstan": "^2.1.22", + "phpstan/phpstan-deprecation-rules": "^2.0.3", + "phpstan/phpstan-phpunit": "^2.0.7", + "phpstan/phpstan-strict-rules": "^2.0.6", + "phpunit/phpunit": "^9.6.24", + "rector/rector": "^2.1.4" + }, + "type": "library", + "extra": { "branch-alias": { "dev-main": "1.7-dev" }, @@ -11917,51 +12666,6 @@ }, "time": "2024-11-21T13:46:39+00:00" }, - { - "name": "felixfbecker/advanced-json-rpc", - "version": "v3.2.1", - "source": { - "type": "git", - "url": "https://github.com/felixfbecker/php-advanced-json-rpc.git", - "reference": "b5f37dbff9a8ad360ca341f3240dc1c168b45447" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/felixfbecker/php-advanced-json-rpc/zipball/b5f37dbff9a8ad360ca341f3240dc1c168b45447", - "reference": "b5f37dbff9a8ad360ca341f3240dc1c168b45447", - "shasum": "" - }, - "require": { - "netresearch/jsonmapper": "^1.0 || ^2.0 || ^3.0 || ^4.0", - "php": "^7.1 || ^8.0", - "phpdocumentor/reflection-docblock": "^4.3.4 || ^5.0.0" - }, - "require-dev": { - "phpunit/phpunit": "^7.0 || ^8.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "AdvancedJsonRpc\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "ISC" - ], - "authors": [ - { - "name": "Felix Becker", - "email": "felix.b@outlook.com" - } - ], - "description": "A more advanced JSONRPC implementation", - "support": { - "issues": "https://github.com/felixfbecker/php-advanced-json-rpc/issues", - "source": "https://github.com/felixfbecker/php-advanced-json-rpc/tree/v3.2.1" - }, - "time": "2021-06-11T22:34:44+00:00" - }, { "name": "felixfbecker/language-server-protocol", "version": "v1.5.3", @@ -12092,6 +12796,246 @@ }, "time": "2023-12-03T23:53:29+00:00" }, + { + "name": "kelunik/certificate", + "version": "v1.1.3", + "source": { + "type": "git", + "url": "https://github.com/kelunik/certificate.git", + "reference": "7e00d498c264d5eb4f78c69f41c8bd6719c0199e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/kelunik/certificate/zipball/7e00d498c264d5eb4f78c69f41c8bd6719c0199e", + "reference": "7e00d498c264d5eb4f78c69f41c8bd6719c0199e", + "shasum": "" + }, + "require": { + "ext-openssl": "*", + "php": ">=7.0" + }, + "require-dev": { + "amphp/php-cs-fixer-config": "^2", + "phpunit/phpunit": "^6 | 7 | ^8 | ^9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Kelunik\\Certificate\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + } + ], + "description": "Access certificate details and transform between different formats.", + "keywords": [ + "DER", + "certificate", + "certificates", + "openssl", + "pem", + "x509" + ], + "support": { + "issues": "https://github.com/kelunik/certificate/issues", + "source": "https://github.com/kelunik/certificate/tree/v1.1.3" + }, + "time": "2023-02-03T21:26:53+00:00" + }, + { + "name": "league/uri", + "version": "7.8.1", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/uri.git", + "reference": "08cf38e3924d4f56238125547b5720496fac8fd4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/uri/zipball/08cf38e3924d4f56238125547b5720496fac8fd4", + "reference": "08cf38e3924d4f56238125547b5720496fac8fd4", + "shasum": "" + }, + "require": { + "league/uri-interfaces": "^7.8.1", + "php": "^8.1", + "psr/http-factory": "^1" + }, + "conflict": { + "league/uri-schemes": "^1.0" + }, + "suggest": { + "ext-bcmath": "to improve IPV4 host parsing", + "ext-dom": "to convert the URI into an HTML anchor tag", + "ext-fileinfo": "to create Data URI from file contennts", + "ext-gmp": "to improve IPV4 host parsing", + "ext-intl": "to handle IDN host with the best performance", + "ext-uri": "to use the PHP native URI class", + "jeremykendall/php-domain-parser": "to further parse the URI host and resolve its Public Suffix and Top Level Domain", + "league/uri-components": "to provide additional tools to manipulate URI objects components", + "league/uri-polyfill": "to backport the PHP URI extension for older versions of PHP", + "php-64bit": "to improve IPV4 host parsing", + "rowbot/url": "to handle URLs using the WHATWG URL Living Standard specification", + "symfony/polyfill-intl-idn": "to handle IDN host via the Symfony polyfill if ext-intl is not present" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "7.x-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Uri\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ignace Nyamagana Butera", + "email": "nyamsprod@gmail.com", + "homepage": "https://nyamsprod.com" + } + ], + "description": "URI manipulation library", + "homepage": "https://uri.thephpleague.com", + "keywords": [ + "URN", + "data-uri", + "file-uri", + "ftp", + "hostname", + "http", + "https", + "middleware", + "parse_str", + "parse_url", + "psr-7", + "query-string", + "querystring", + "rfc2141", + "rfc3986", + "rfc3987", + "rfc6570", + "rfc8141", + "uri", + "uri-template", + "url", + "ws" + ], + "support": { + "docs": "https://uri.thephpleague.com", + "forum": "https://thephpleague.slack.com", + "issues": "https://github.com/thephpleague/uri-src/issues", + "source": "https://github.com/thephpleague/uri/tree/7.8.1" + }, + "funding": [ + { + "url": "https://github.com/sponsors/nyamsprod", + "type": "github" + } + ], + "time": "2026-03-15T20:22:25+00:00" + }, + { + "name": "league/uri-interfaces", + "version": "7.8.1", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/uri-interfaces.git", + "reference": "85d5c77c5d6d3af6c54db4a78246364908f3c928" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/uri-interfaces/zipball/85d5c77c5d6d3af6c54db4a78246364908f3c928", + "reference": "85d5c77c5d6d3af6c54db4a78246364908f3c928", + "shasum": "" + }, + "require": { + "ext-filter": "*", + "php": "^8.1", + "psr/http-message": "^1.1 || ^2.0" + }, + "suggest": { + "ext-bcmath": "to improve IPV4 host parsing", + "ext-gmp": "to improve IPV4 host parsing", + "ext-intl": "to handle IDN host with the best performance", + "php-64bit": "to improve IPV4 host parsing", + "rowbot/url": "to handle URLs using the WHATWG URL Living Standard specification", + "symfony/polyfill-intl-idn": "to handle IDN host via the Symfony polyfill if ext-intl is not present" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "7.x-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Uri\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ignace Nyamagana Butera", + "email": "nyamsprod@gmail.com", + "homepage": "https://nyamsprod.com" + } + ], + "description": "Common tools for parsing and resolving RFC3987/RFC3986 URI", + "homepage": "https://uri.thephpleague.com", + "keywords": [ + "data-uri", + "file-uri", + "ftp", + "hostname", + "http", + "https", + "parse_str", + "parse_url", + "psr-7", + "query-string", + "querystring", + "rfc3986", + "rfc3987", + "rfc6570", + "uri", + "url", + "ws" + ], + "support": { + "docs": "https://uri.thephpleague.com", + "forum": "https://thephpleague.slack.com", + "issues": "https://github.com/thephpleague/uri-src/issues", + "source": "https://github.com/thephpleague/uri-interfaces/tree/7.8.1" + }, + "funding": [ + { + "url": "https://github.com/sponsors/nyamsprod", + "type": "github" + } + ], + "time": "2026-03-08T20:05:35+00:00" + }, { "name": "localheinz/diff", "version": "1.3.0", @@ -12304,16 +13248,16 @@ }, { "name": "netresearch/jsonmapper", - "version": "v4.5.0", + "version": "v5.0.1", "source": { "type": "git", "url": "https://github.com/cweiske/jsonmapper.git", - "reference": "8e76efb98ee8b6afc54687045e1b8dba55ac76e5" + "reference": "980674efdda65913492d29a8fd51c82270dd37bb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/cweiske/jsonmapper/zipball/8e76efb98ee8b6afc54687045e1b8dba55ac76e5", - "reference": "8e76efb98ee8b6afc54687045e1b8dba55ac76e5", + "url": "https://api.github.com/repos/cweiske/jsonmapper/zipball/980674efdda65913492d29a8fd51c82270dd37bb", + "reference": "980674efdda65913492d29a8fd51c82270dd37bb", "shasum": "" }, "require": { @@ -12349,36 +13293,43 @@ "support": { "email": "cweiske@cweiske.de", "issues": "https://github.com/cweiske/jsonmapper/issues", - "source": "https://github.com/cweiske/jsonmapper/tree/v4.5.0" + "source": "https://github.com/cweiske/jsonmapper/tree/v5.0.1" }, - "time": "2024-09-08T10:13:13+00:00" + "time": "2026-02-22T16:28:03+00:00" }, { "name": "nikic/php-parser", - "version": "v4.19.5", + "version": "v5.7.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "51bd93cc741b7fc3d63d20b6bdcd99fdaa359837" + "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/51bd93cc741b7fc3d63d20b6bdcd99fdaa359837", - "reference": "51bd93cc741b7fc3d63d20b6bdcd99fdaa359837", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/dca41cd15c2ac9d055ad70dbfd011130757d1f82", + "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82", "shasum": "" }, "require": { + "ext-ctype": "*", + "ext-json": "*", "ext-tokenizer": "*", - "php": ">=7.1" + "php": ">=7.4" }, "require-dev": { "ircmaxell/php-yacc": "^0.0.7", - "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" + "phpunit/phpunit": "^9.0" }, "bin": [ "bin/php-parse" ], "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.x-dev" + } + }, "autoload": { "psr-4": { "PhpParser\\": "lib/PhpParser" @@ -12400,9 +13351,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.19.5" + "source": "https://github.com/nikic/PHP-Parser/tree/v5.7.0" }, - "time": "2025-12-06T11:45:25+00:00" + "time": "2025-12-06T11:56:16+00:00" }, { "name": "phar-io/manifest", @@ -13007,34 +13958,35 @@ }, { "name": "psalm/plugin-symfony", - "version": "v5.2.6", + "version": "v5.3.0", "source": { "type": "git", "url": "https://github.com/psalm/psalm-plugin-symfony.git", - "reference": "1638f172b4ae5f283ee6b1b58fff3e44aa628742" + "reference": "df874ff48ae3b1833ea17fba7c21b31a4d682614" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/psalm/psalm-plugin-symfony/zipball/1638f172b4ae5f283ee6b1b58fff3e44aa628742", - "reference": "1638f172b4ae5f283ee6b1b58fff3e44aa628742", + "url": "https://api.github.com/repos/psalm/psalm-plugin-symfony/zipball/df874ff48ae3b1833ea17fba7c21b31a4d682614", + "reference": "df874ff48ae3b1833ea17fba7c21b31a4d682614", "shasum": "" }, "require": { "ext-simplexml": "*", - "php": "^8.1", - "symfony/framework-bundle": "^5.0 || ^6.0 || ^7.0", - "vimeo/psalm": "^5.16 || dev-master" + "php": ">=8.1", + "symfony/expression-language": "^5.0 || ^6.0 || ^7.0 || ^8.0", + "symfony/framework-bundle": "^5.0 || ^6.0 || ^7.0 || ^8.0", + "vimeo/psalm": "^6 || dev-master" }, "require-dev": { "doctrine/annotations": "^1.8|^2", - "doctrine/orm": "^2.9", + "doctrine/orm": "^2.9 || ^3.6", "phpunit/phpunit": "~7.5 || ~9.5", - "symfony/cache-contracts": "^1.0 || ^2.0", + "symfony/cache-contracts": "^1.0 || ^2.0 || ^3.0", "symfony/console": "*", - "symfony/form": "^5.0 || ^6.0 || ^7.0", - "symfony/messenger": "^5.0 || ^6.0 || ^7.0", + "symfony/form": "^5.0 || ^6.0 || ^7.0 || ^8.0", + "symfony/messenger": "^5.0 || ^6.0 || ^7.0 || ^8.0", "symfony/security-core": "*", - "symfony/serializer": "^5.0 || ^6.0 || ^7.0", + "symfony/serializer": "^5.0 || ^6.0 || ^7.0 || ^8.0", "symfony/validator": "*", "twig/twig": "^2.10 || ^3.0", "weirdan/codeception-psalm-module": "dev-master" @@ -13066,9 +14018,9 @@ "description": "Psalm Plugin for Symfony", "support": { "issues": "https://github.com/psalm/psalm-plugin-symfony/issues", - "source": "https://github.com/psalm/psalm-plugin-symfony/tree/v5.2.6" + "source": "https://github.com/psalm/psalm-plugin-symfony/tree/v5.3.0" }, - "time": "2024-12-21T08:46:26+00:00" + "time": "2026-02-12T11:24:16+00:00" }, { "name": "rector/rector", @@ -13129,6 +14081,78 @@ ], "time": "2024-11-08T13:59:10+00:00" }, + { + "name": "revolt/event-loop", + "version": "v1.0.8", + "source": { + "type": "git", + "url": "https://github.com/revoltphp/event-loop.git", + "reference": "b6fc06dce8e9b523c9946138fa5e62181934f91c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/revoltphp/event-loop/zipball/b6fc06dce8e9b523c9946138fa5e62181934f91c", + "reference": "b6fc06dce8e9b523c9946138fa5e62181934f91c", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "ext-json": "*", + "jetbrains/phpstorm-stubs": "^2019.3", + "phpunit/phpunit": "^9", + "psalm/phar": "^5.15" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Revolt\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "ceesjank@gmail.com" + }, + { + "name": "Christian Lück", + "email": "christian@clue.engineering" + }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + } + ], + "description": "Rock-solid event loop for concurrent PHP applications.", + "keywords": [ + "async", + "asynchronous", + "concurrency", + "event", + "event-loop", + "non-blocking", + "scheduler" + ], + "support": { + "issues": "https://github.com/revoltphp/event-loop/issues", + "source": "https://github.com/revoltphp/event-loop/tree/v1.0.8" + }, + "time": "2025-08-27T21:33:23+00:00" + }, { "name": "sebastian/cli-parser", "version": "1.0.2", @@ -14285,16 +15309,16 @@ }, { "name": "symfony/debug-bundle", - "version": "v6.4.27", + "version": "v6.4.35", "source": { "type": "git", "url": "https://github.com/symfony/debug-bundle.git", - "reference": "21a61c55192d558a6b81cdb12e8c010fc9474fe0" + "reference": "eb79084c2c9778559b21f61cb1507cbd580cc6e1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/debug-bundle/zipball/21a61c55192d558a6b81cdb12e8c010fc9474fe0", - "reference": "21a61c55192d558a6b81cdb12e8c010fc9474fe0", + "url": "https://api.github.com/repos/symfony/debug-bundle/zipball/eb79084c2c9778559b21f61cb1507cbd580cc6e1", + "reference": "eb79084c2c9778559b21f61cb1507cbd580cc6e1", "shasum": "" }, "require": { @@ -14339,7 +15363,7 @@ "description": "Provides a tight integration of the Symfony VarDumper component and the ServerLogCommand from MonologBridge into the Symfony full-stack framework", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/debug-bundle/tree/v6.4.27" + "source": "https://github.com/symfony/debug-bundle/tree/v6.4.35" }, "funding": [ { @@ -14359,35 +15383,36 @@ "type": "tidelift" } ], - "time": "2025-10-11T17:35:31+00:00" + "time": "2026-03-02T09:25:10+00:00" }, { "name": "symfony/maker-bundle", - "version": "v1.62.1", + "version": "v1.67.0", "source": { "type": "git", "url": "https://github.com/symfony/maker-bundle.git", - "reference": "468ff2708200c95ebc0d85d3174b6c6711b8a590" + "reference": "6ce8b313845f16bcf385ee3cb31d8b24e30d5516" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/maker-bundle/zipball/468ff2708200c95ebc0d85d3174b6c6711b8a590", - "reference": "468ff2708200c95ebc0d85d3174b6c6711b8a590", + "url": "https://api.github.com/repos/symfony/maker-bundle/zipball/6ce8b313845f16bcf385ee3cb31d8b24e30d5516", + "reference": "6ce8b313845f16bcf385ee3cb31d8b24e30d5516", "shasum": "" }, "require": { + "composer-runtime-api": "^2.1", "doctrine/inflector": "^2.0", - "nikic/php-parser": "^4.18|^5.0", + "nikic/php-parser": "^5.0", "php": ">=8.1", - "symfony/config": "^6.4|^7.0", - "symfony/console": "^6.4|^7.0", - "symfony/dependency-injection": "^6.4|^7.0", + "symfony/config": "^6.4|^7.0|^8.0", + "symfony/console": "^6.4|^7.0|^8.0", + "symfony/dependency-injection": "^6.4|^7.0|^8.0", "symfony/deprecation-contracts": "^2.2|^3", - "symfony/filesystem": "^6.4|^7.0", - "symfony/finder": "^6.4|^7.0", - "symfony/framework-bundle": "^6.4|^7.0", - "symfony/http-kernel": "^6.4|^7.0", - "symfony/process": "^6.4|^7.0" + "symfony/filesystem": "^6.4|^7.0|^8.0", + "symfony/finder": "^6.4|^7.0|^8.0", + "symfony/framework-bundle": "^6.4|^7.0|^8.0", + "symfony/http-kernel": "^6.4|^7.0|^8.0", + "symfony/process": "^6.4|^7.0|^8.0" }, "conflict": { "doctrine/doctrine-bundle": "<2.10", @@ -14395,12 +15420,14 @@ }, "require-dev": { "composer/semver": "^3.0", - "doctrine/doctrine-bundle": "^2.5.0", + "doctrine/doctrine-bundle": "^2.10|^3.0", "doctrine/orm": "^2.15|^3", - "symfony/http-client": "^6.4|^7.0", - "symfony/phpunit-bridge": "^6.4.1|^7.0", - "symfony/security-core": "^6.4|^7.0", - "symfony/yaml": "^6.4|^7.0", + "doctrine/persistence": "^3.1|^4.0", + "symfony/http-client": "^6.4|^7.0|^8.0", + "symfony/phpunit-bridge": "^6.4.1|^7.0|^8.0", + "symfony/security-core": "^6.4|^7.0|^8.0", + "symfony/security-http": "^6.4|^7.0|^8.0", + "symfony/yaml": "^6.4|^7.0|^8.0", "twig/twig": "^3.0|^4.x-dev" }, "type": "symfony-bundle", @@ -14435,7 +15462,7 @@ ], "support": { "issues": "https://github.com/symfony/maker-bundle/issues", - "source": "https://github.com/symfony/maker-bundle/tree/v1.62.1" + "source": "https://github.com/symfony/maker-bundle/tree/v1.67.0" }, "funding": [ { @@ -14446,25 +15473,29 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2025-01-15T00:21:40+00:00" + "time": "2026-03-18T13:39:06+00:00" }, { "name": "symfony/phpunit-bridge", - "version": "v6.4.26", + "version": "v6.4.35", "source": { "type": "git", "url": "https://github.com/symfony/phpunit-bridge.git", - "reference": "406aa80401bf960e7a173a3ccf268ae82b6bc93f" + "reference": "10b3646a631191501e73e83211fed9b19413e54e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/406aa80401bf960e7a173a3ccf268ae82b6bc93f", - "reference": "406aa80401bf960e7a173a3ccf268ae82b6bc93f", + "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/10b3646a631191501e73e83211fed9b19413e54e", + "reference": "10b3646a631191501e73e83211fed9b19413e54e", "shasum": "" }, "require": { @@ -14520,7 +15551,7 @@ "testing" ], "support": { - "source": "https://github.com/symfony/phpunit-bridge/tree/v6.4.26" + "source": "https://github.com/symfony/phpunit-bridge/tree/v6.4.35" }, "funding": [ { @@ -14540,20 +15571,20 @@ "type": "tidelift" } ], - "time": "2025-09-12T08:37:02+00:00" + "time": "2026-03-04T13:04:47+00:00" }, { "name": "symfony/web-profiler-bundle", - "version": "v6.4.34", + "version": "v6.4.35", "source": { "type": "git", "url": "https://github.com/symfony/web-profiler-bundle.git", - "reference": "848bc5d5745500f855bb201d57ae066fd7e67448" + "reference": "ae7fc9802c6eef1fa5078efad3c72db836ffcb9d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/web-profiler-bundle/zipball/848bc5d5745500f855bb201d57ae066fd7e67448", - "reference": "848bc5d5745500f855bb201d57ae066fd7e67448", + "url": "https://api.github.com/repos/symfony/web-profiler-bundle/zipball/ae7fc9802c6eef1fa5078efad3c72db836ffcb9d", + "reference": "ae7fc9802c6eef1fa5078efad3c72db836ffcb9d", "shasum": "" }, "require": { @@ -14606,7 +15637,7 @@ "dev" ], "support": { - "source": "https://github.com/symfony/web-profiler-bundle/tree/v6.4.34" + "source": "https://github.com/symfony/web-profiler-bundle/tree/v6.4.35" }, "funding": [ { @@ -14626,7 +15657,7 @@ "type": "tidelift" } ], - "time": "2026-02-05T15:19:06+00:00" + "time": "2026-03-03T10:22:09+00:00" }, { "name": "theofidry/alice-data-fixtures", @@ -14781,24 +15812,26 @@ }, { "name": "vimeo/psalm", - "version": "5.26.1", + "version": "6.16.1", "source": { "type": "git", "url": "https://github.com/vimeo/psalm.git", - "reference": "d747f6500b38ac4f7dfc5edbcae6e4b637d7add0" + "reference": "f1f5de594dc76faf8784e02d3dc4716c91c6f6ac" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/vimeo/psalm/zipball/d747f6500b38ac4f7dfc5edbcae6e4b637d7add0", - "reference": "d747f6500b38ac4f7dfc5edbcae6e4b637d7add0", + "url": "https://api.github.com/repos/vimeo/psalm/zipball/f1f5de594dc76faf8784e02d3dc4716c91c6f6ac", + "reference": "f1f5de594dc76faf8784e02d3dc4716c91c6f6ac", "shasum": "" }, "require": { - "amphp/amp": "^2.4.2", - "amphp/byte-stream": "^1.5", + "amphp/amp": "^3", + "amphp/byte-stream": "^2", + "amphp/parallel": "^2.3", "composer-runtime-api": "^2", "composer/semver": "^1.4 || ^2.0 || ^3.0", "composer/xdebug-handler": "^2.0 || ^3.0", + "danog/advanced-json-rpc": "^3.1", "dnoegel/php-xdg-base-dir": "^0.1.1", "ext-ctype": "*", "ext-dom": "*", @@ -14807,27 +15840,26 @@ "ext-mbstring": "*", "ext-simplexml": "*", "ext-tokenizer": "*", - "felixfbecker/advanced-json-rpc": "^3.1", - "felixfbecker/language-server-protocol": "^1.5.2", + "felixfbecker/language-server-protocol": "^1.5.3", "fidry/cpu-core-counter": "^0.4.1 || ^0.5.1 || ^1.0.0", - "netresearch/jsonmapper": "^1.0 || ^2.0 || ^3.0 || ^4.0", - "nikic/php-parser": "^4.17", - "php": "^7.4 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0", - "sebastian/diff": "^4.0 || ^5.0 || ^6.0", + "netresearch/jsonmapper": "^5.0", + "nikic/php-parser": "^5.0.0", + "php": "~8.1.31 || ~8.2.27 || ~8.3.16 || ~8.4.3 || ~8.5.0", + "sebastian/diff": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0", "spatie/array-to-xml": "^2.17.0 || ^3.0", - "symfony/console": "^4.1.6 || ^5.0 || ^6.0 || ^7.0", - "symfony/filesystem": "^5.4 || ^6.0 || ^7.0" - }, - "conflict": { - "nikic/php-parser": "4.17.0" + "symfony/console": "^6.0 || ^7.0 || ^8.0", + "symfony/filesystem": "~6.3.12 || ~6.4.3 || ^7.0.3 || ^8.0", + "symfony/polyfill-php84": "^1.31.0" }, "provide": { "psalm/psalm": "self.version" }, "require-dev": { - "amphp/phpunit-util": "^2.0", + "amphp/phpunit-util": "^3", "bamarni/composer-bin-plugin": "^1.4", "brianium/paratest": "^6.9", + "danog/class-finder": "^0.4.8", + "dg/bypass-finals": "^1.5", "ext-curl": "*", "mockery/mockery": "^1.5", "nunomaduro/mock-final-classes": "^1.1", @@ -14835,10 +15867,10 @@ "phpstan/phpdoc-parser": "^1.6", "phpunit/phpunit": "^9.6", "psalm/plugin-mockery": "^1.1", - "psalm/plugin-phpunit": "^0.18", + "psalm/plugin-phpunit": "^0.19", "slevomat/coding-standard": "^8.4", "squizlabs/php_codesniffer": "^3.6", - "symfony/process": "^4.4 || ^5.0 || ^6.0 || ^7.0" + "symfony/process": "^6.0 || ^7.0 || ^8.0" }, "suggest": { "ext-curl": "In order to send data to shepherd", @@ -14849,6 +15881,7 @@ "psalm-language-server", "psalm-plugin", "psalm-refactor", + "psalm-review", "psalter" ], "type": "project", @@ -14858,7 +15891,9 @@ "dev-2.x": "2.x-dev", "dev-3.x": "3.x-dev", "dev-4.x": "4.x-dev", - "dev-master": "5.x-dev" + "dev-5.x": "5.x-dev", + "dev-6.x": "6.x-dev", + "dev-master": "7.x-dev" } }, "autoload": { @@ -14873,6 +15908,10 @@ "authors": [ { "name": "Matthew Brown" + }, + { + "name": "Daniil Gentili", + "email": "daniil@daniil.it" } ], "description": "A static analysis tool for finding errors in PHP applications", @@ -14887,7 +15926,7 @@ "issues": "https://github.com/vimeo/psalm/issues", "source": "https://github.com/vimeo/psalm" }, - "time": "2024-09-08T18:53:08+00:00" + "time": "2026-03-19T10:56:09+00:00" }, { "name": "vincentlanglet/twig-cs-fixer", @@ -14968,22 +16007,22 @@ }, { "name": "weirdan/doctrine-psalm-plugin", - "version": "v2.9.0", + "version": "v2.10.0", "source": { "type": "git", "url": "https://github.com/psalm/psalm-plugin-doctrine.git", - "reference": "3db8e55b2ea15373338d2a3eab71c5f5a31c8b08" + "reference": "8d604c817976e156cd6f1cfab983eadd35b04a2f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/psalm/psalm-plugin-doctrine/zipball/3db8e55b2ea15373338d2a3eab71c5f5a31c8b08", - "reference": "3db8e55b2ea15373338d2a3eab71c5f5a31c8b08", + "url": "https://api.github.com/repos/psalm/psalm-plugin-doctrine/zipball/8d604c817976e156cd6f1cfab983eadd35b04a2f", + "reference": "8d604c817976e156cd6f1cfab983eadd35b04a2f", "shasum": "" }, "require": { "composer/semver": "^1.4 || ^2.0 || ^3.0", - "php": "^7.2 || ^8", - "vimeo/psalm": "^4.28|^5.0" + "php": "^8", + "vimeo/psalm": "^6" }, "conflict": { "doctrine/collections": "<1.8", @@ -15040,9 +16079,9 @@ ], "support": { "issues": "https://github.com/psalm/psalm-plugin-doctrine/issues", - "source": "https://github.com/psalm/psalm-plugin-doctrine/tree/v2.9.0" + "source": "https://github.com/psalm/psalm-plugin-doctrine/tree/v2.10.0" }, - "time": "2023-07-15T05:44:30+00:00" + "time": "2025-01-26T11:36:27+00:00" } ], "aliases": [], @@ -15051,12 +16090,12 @@ "prefer-stable": true, "prefer-lowest": false, "platform": { - "php": ">=8.3", + "php": ">=8.4", "ext-ctype": "*", "ext-fileinfo": "*", "ext-gd": "*", "ext-iconv": "*" }, "platform-dev": {}, - "plugin-api-version": "2.9.0" + "plugin-api-version": "2.6.0" } diff --git a/config/packages/pentatrion_vite.yaml b/config/packages/pentatrion_vite.yaml new file mode 100644 index 000000000..3b3ecaacf --- /dev/null +++ b/config/packages/pentatrion_vite.yaml @@ -0,0 +1,4 @@ +# @see https://symfony-vite.pentatrion.com/guide/performance.html#caching-configuration-files-%F0%9F%8F%83 +when@prod: + pentatrion_vite: + cache: true diff --git a/docker-compose.server.yml b/docker-compose.server.yml index 614d67b10..bc011cac0 100644 --- a/docker-compose.server.yml +++ b/docker-compose.server.yml @@ -8,7 +8,7 @@ networks: services: phpfpm: - image: itkdev/php8.3-fpm:alpine + image: itkdev/php8.4-fpm:alpine restart: unless-stopped networks: - app diff --git a/docker-compose.yml b/docker-compose.yml index b5c08946d..b18ab3814 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -27,7 +27,7 @@ services: #- ENCRYPT=1 # Uncomment to enable database encryption. phpfpm: - image: itkdev/php8.3-fpm:latest + image: itkdev/php8.4-fpm:latest user: ${COMPOSE_USER:-deploy} networks: - app diff --git a/docs/infrastructure.png b/docs/infrastructure.png new file mode 100644 index 000000000..0cdbb9835 Binary files /dev/null and b/docs/infrastructure.png differ diff --git a/infrastructure/README.md b/infrastructure/README.md new file mode 100644 index 000000000..e311e9f0e --- /dev/null +++ b/infrastructure/README.md @@ -0,0 +1,29 @@ +# OS2display image build + +This folder contains the infrastructure files for building the `os2display/*` images. + +Two images are built: + +- `os2display/display-api-service`: The web (php-fpm) application image +- `os2display/display-api-service-nginx`: The API (nginx) server image + +## GitHub Actions + +Both images are built automatically on push to the `develop` branch, and on tag creation. +They are tagged with the same version as the application. + +## Docker Hub + +Images are published to + +## Building images locally + +A script is provided to build the images locally: `build-n-push.sh` + +## Build process + +Both images use multistage builds, with the first two stages being identical. +And the final stage is optimized for the specific image. + +This is done because both images requires files from both the `npm` and `composer` build stages. And while having a +shared build stage when building locally is possible, it's not feasible when building on Github Actions. diff --git a/infrastructure/build-n-push.sh b/infrastructure/build-n-push.sh new file mode 100755 index 000000000..feae48ab7 --- /dev/null +++ b/infrastructure/build-n-push.sh @@ -0,0 +1,29 @@ +#!/bin/sh + +set -eux + +APP_VERSION=3.0.0-beta1 + +docker pull itkdev/php8.4-fpm:alpine +docker pull nginxinc/nginx-unprivileged:alpine + +docker buildx build \ + --platform linux/amd64,linux/arm64 \ + --no-cache \ + --pull \ + --build-arg APP_VERSION=${APP_VERSION} \ + --tag=ghcr.io/itk-dev/os2display-api-service:${APP_VERSION} \ + --file="display-api-service/Dockerfile" ../ + +docker push ghcr.io/itk-dev/os2display-api-service:${APP_VERSION} + +docker buildx build \ + --platform linux/amd64,linux/arm64 \ + --no-cache \ + --pull \ + --build-arg APP_VERSION=${APP_VERSION} \ + --build-arg APP_IMAGE=os2display-api-service \ + --tag=ghcr.io/itk-dev/os2display-api-service-nginx:${APP_VERSION} \ + --file="nginx/Dockerfile" nginx + +docker push ghcr.io/itk-dev/os2display-api-service-nginx:${APP_VERSION} diff --git a/infrastructure/display-api-service/Dockerfile b/infrastructure/display-api-service/Dockerfile new file mode 100644 index 000000000..1f0d6db63 --- /dev/null +++ b/infrastructure/display-api-service/Dockerfile @@ -0,0 +1,72 @@ +################################ +# Assets build +################################ +FROM --platform=$BUILDPLATFORM node:24-alpine AS assets_builder +LABEL maintainer="ITK Dev " + +ARG APP_VERSION="develop" + +RUN mkdir -p /app +WORKDIR /app + +# Copy only necessary files for npm install +COPY package.json package-lock.json vite.config.js ./ + +# Install dependencies +RUN npm ci --no-audit --no-fund + +# Copy source files needed for build +COPY assets/ ./assets/ + +# Build the application with version info +RUN npm run build + + +################################ +# API backend build +################################ +FROM --platform=$BUILDPLATFORM itkdev/php8.4-fpm:latest AS api_app_builder +LABEL maintainer="ITK Dev " + +ARG APP_VERSION="develop" + +WORKDIR /app + +# Copy only composer files first for better layer caching +COPY --chown=deploy:deploy . ./ + +# Composer packages first +RUN APP_ENV=prod composer install --no-dev --optimize-autoloader --classmap-authoritative + +COPY --chown=deploy:deploy --from=assets_builder /app/public/build /app/public/build + +# Remove files we do not need to the final image +RUN rm -rf package* vite.config.js + + +################################ +# PHP-FPM (API) production image +################################ +FROM --platform=$BUILDPLATFORM itkdev/php8.4-fpm:alpine +LABEL maintainer="ITK Dev " + +ENV APP_ENV=prod \ + COMPOSER_VERSION=2 \ + PHP_OPCACHE_ENABLED=1 \ + PHP_OPCACHE_VALIDATE_TIMESTAMPS=0 \ + PHP_OPCACHE_MAX_ACCELERATED_FILES=20000 \ + PHP_OPCACHE_MEMORY_CONSUMPTION=256 \ + PHP_PM_TYPE="dynamic" \ + PHP_PM_MAX_CHILDREN="24" \ + PHP_PM_MAX_REQUESTS="0" \ + PHP_PM_START_SERVERS="5" \ + PHP_PM_MIN_SPARE_SERVERS="5" \ + PHP_PM_MAX_SPARE_SERVERS="10" + +# Install the api application. +COPY --chown=deploy:deploy --from=api_app_builder /app . + +# Symfony settings (warmup required to make vite assets work corretly) +RUN mkdir -p ./config/secrets + +CMD [ "docker-entrypoint.sh" ] diff --git a/infrastructure/itkdev/Readme.md b/infrastructure/itkdev/Readme.md deleted file mode 100644 index abf2b9d1e..000000000 --- a/infrastructure/itkdev/Readme.md +++ /dev/null @@ -1,3 +0,0 @@ -# ITK-development image build - -This folder contains the infrastructure files for building the `itkdev/*` images diff --git a/infrastructure/itkdev/display-api-service/Dockerfile b/infrastructure/itkdev/display-api-service/Dockerfile deleted file mode 100644 index b30ecff1a..000000000 --- a/infrastructure/itkdev/display-api-service/Dockerfile +++ /dev/null @@ -1,63 +0,0 @@ -FROM itkdev/php8.3-fpm:alpine AS APP_BUILDER -LABEL maintainer="ITK Dev " - -ARG APP_VERSION="develop" -ENV APP_PATH=/var/www/html - -USER root - -# Move site into the container. -ADD https://github.com/os2display/display-api-service/archive/${APP_VERSION}.tar.gz /tmp/app.tar -RUN tar -zxf /tmp/app.tar --strip-components=1 -C ${APP_PATH} \ - && rm /tmp/app.tar - -# Add composer in from the official composer image (also alpine). -COPY --from=composer:2 /usr/bin/composer /usr/local/bin/composer - -WORKDIR ${APP_PATH} - -## Install assets, which requires a HACK as redis is not available (should be removed later on). -RUN COMPOSER_ALLOW_SUPERUSER=1 APP_ENV=prod composer install --no-dev -o --classmap-authoritative - -RUN rm -rf infrastructure - -#### -## Build main application image. -#### -FROM itkdev/php8.3-fpm:alpine -LABEL maintainer="ITK Dev " - -ENV APP_PATH=/var/www/html \ - COMPOSER_VERSION=2 - -USER root - -# Add composer needed to run optimizations after config is loaded. -COPY --from=composer:2 /usr/bin/composer /usr/local/bin/composer - -# Install the application. -COPY --from=APP_BUILDER ${APP_PATH} ${APP_PATH} -RUN mkdir -p ${APP_PATH}/config/secrets \ - && chown -R deploy:deploy ${APP_PATH} - -# Download Prometheus php-fpm export. -COPY --from=hipages/php-fpm_exporter:1.1.1 /php-fpm_exporter /usr/local/bin/php-fpm_exporter - -# Copy configuration. -COPY etc /etc/ - -# Install configuration template handler -ADD https://github.com/kelseyhightower/confd/releases/download/v0.16.0/confd-0.16.0-linux-amd64 /usr/local/bin/confd -RUN chmod +x /usr/local/bin/confd - -# Copy confd onfiguration. -COPY etc /etc/ - -COPY docker-entrypoint.sh /usr/local/bin/ -RUN chmod +x /usr/local/bin/docker-entrypoint.sh - -USER deploy - -WORKDIR ${APP_PATH} - -CMD [ "docker-entrypoint.sh" ] diff --git a/infrastructure/itkdev/display-api-service/docker-entrypoint.sh b/infrastructure/itkdev/display-api-service/docker-entrypoint.sh deleted file mode 100644 index 306e9f13d..000000000 --- a/infrastructure/itkdev/display-api-service/docker-entrypoint.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/sh - -set -eux - -## Run templates with configuration. -/usr/local/bin/confd --onetime --backend env --confdir /etc/confd - -## Bump env.local into PHP for better performance. -composer dump-env prod - -## Warm-up Symfony cache (with the current configuration). -/var/www/html/bin/console --env=prod cache:warmup - -## Set selected composer version. Default version 2. -if [ ! -z "${COMPOSER_VERSION}" ]; then - if [ "${COMPOSER_VERSION}" = "1" ]; then - ln -fs /usr/bin/composer1 /home/deploy/bin/composer - else - ln -fs /usr/bin/composer2 /home/deploy/bin/composer - fi -else - ln -fs /usr/bin/composer2 /home/deploy/bin/composer -fi - -exec php-fpm "$@" diff --git a/infrastructure/itkdev/display-api-service/etc/confd/conf.d/env.local.toml b/infrastructure/itkdev/display-api-service/etc/confd/conf.d/env.local.toml deleted file mode 100644 index d614cc69a..000000000 --- a/infrastructure/itkdev/display-api-service/etc/confd/conf.d/env.local.toml +++ /dev/null @@ -1,8 +0,0 @@ -[template] -src = "env.local.tmpl" -dest = "/var/www/html/.env.local" -owner = "deploy" -mode = "0644" -keys = [ - "/app-config" -] diff --git a/infrastructure/itkdev/display-api-service/etc/confd/templates/env.local.tmpl b/infrastructure/itkdev/display-api-service/etc/confd/templates/env.local.tmpl deleted file mode 100644 index 76e585b97..000000000 --- a/infrastructure/itkdev/display-api-service/etc/confd/templates/env.local.tmpl +++ /dev/null @@ -1,71 +0,0 @@ -###> symfony/framework-bundle ### -APP_ENV={{ getenv "APP_ENV" "prod" }} -APP_SECRET={{ getenv "APP_SECRET" "MySuperSecret" }} -TRUSTED_PROXIES={{ getenv "APP_TRUSTED_PROXIES" "127.0.0.1,REMOTE_ADDR" }} -###< symfony/framework-bundle ### - -###> doctrine/doctrine-bundle ### -DATABASE_URL={{ getenv "APP_DATABASE_URL" "mysql://db:db@mariadb:3306/db?serverVersion=mariadb-10.4.0" }} -###< doctrine/doctrine-bundle ### - -###> nelmio/cors-bundle ### -CORS_ALLOW_ORIGIN={{ getenv "APP_CORS_ALLOW_ORIGIN" "'^https?://localhost(:[0-9]+)?$'" }} -###< nelmio/cors-bundle ### - -###> App ### -APP_DEFAULT_DATE_FORMAT='{{ getenv "APP_DEFAULT_DATE_FORMAT" "Y-m-d\\TH:i:s\\Z" }}' -APP_ACTIVATION_CODE_EXPIRE_INTERVAL='{{ getenv "APP_ACTIVATION_CODE_EXPIRE_INTERVAL" "P2D" }}' -###< App ### - -###> lexik/jwt-authentication-bundle ### -JWT_PASSPHRASE={{ getenv "APP_JWT_PASSPHRASE" }} -JWT_TOKEN_TTL={{ getenv "APP_JWT_TOKEN_TTL" "3600" }} -JWT_SCREEN_TOKEN_TTL={{ getenv "APP_JWT_SCREEN_TOKEN_TTL" "3600" }} -###< lexik/jwt-authentication-bundle ### - -###> gesdinet/jwt-refresh-token-bundle ### -JWT_REFRESH_TOKEN_TTL={{ getenv "APP_JWT_REFRESH_TOKEN_TTL" "2592000" }} -JWT_SCREEN_REFRESH_TOKEN_TTL={{ getenv "APP_JWT_SCREEN_REFRESH_TOKEN_TTL" "2592000" }} -###< gesdinet/jwt-refresh-token-bundle ### - -###> itk-dev/openid-connect-bundle ### -# internal provider -INTERNAL_OIDC_METADATA_URL={{ getenv "APP_INTERNAL_OIDC_METADATA_URL" "" }} -INTERNAL_OIDC_CLIENT_ID={{ getenv "APP_INTERNAL_OIDC_CLIENT_ID" "" }} -INTERNAL_OIDC_CLIENT_SECRET={{ getenv "APP_INTERNAL_OIDC_CLIENT_SECRET" "" }} -INTERNAL_OIDC_REDIRECT_URI={{ getenv "APP_INTERNAL_OIDC_REDIRECT_URI" "" }} -INTERNAL_OIDC_LEEWAY={{ getenv "APP_INTERNAL_OIDC_LEEWAY" "30" }} - -# external provider -EXTERNAL_OIDC_METADATA_URL={{ getenv "APP_EXTERNAL_OIDC_METADATA_URL" "" }} -EXTERNAL_OIDC_CLIENT_ID={{ getenv "APP_EXTERNAL_OIDC_CLIENT_ID" "" }} -EXTERNAL_OIDC_CLIENT_SECRET={{ getenv "APP_EXTERNAL_OIDC_CLIENT_SECRET" "" }} -EXTERNAL_OIDC_REDIRECT_URI={{ getenv "APP_EXTERNAL_OIDC_REDIRECT_URI" "" }} -EXTERNAL_OIDC_LEEWAY={{ getenv "APP_EXTERNAL_OIDC_LEEWAY" "30" }} -EXTERNAL_OIDC_HASH_SALT={{ getenv "APP_EXTERNAL_OIDC_HASH_SALT" "" }} - -CLI_REDIRECT={{ getenv "APP_CLI_REDIRECT" "" }} -###< itk-dev/openid-connect-bundle ### - -###> redis ### -REDIS_CACHE_PREFIX={{ getenv "APP_CLI_REDIRECT" "DisplayApiService" }} -REDIS_CACHE_DSN={{ getenv "APP_CLI_REDIRECT" "redis://redis:6379/0" }} -###< redis ### - -###> Calendar Api Feed Source ### -CALENDAR_API_FEED_SOURCE_LOCATION_ENDPOINT={{ getenv "APP_CALENDAR_API_FEED_SOURCE_LOCATION_ENDPOINT" "" }} -CALENDAR_API_FEED_SOURCE_RESOURCE_ENDPOINT={{ getenv "APP_CALENDAR_API_FEED_SOURCE_RESOURCE_ENDPOINT" "" }} -CALENDAR_API_FEED_SOURCE_EVENT_ENDPOINT={{ getenv "APP_CALENDAR_API_FEED_SOURCE_EVENT_ENDPOINT" "" }} -CALENDAR_API_FEED_SOURCE_CUSTOM_MAPPINGS={{ getenv "APP_CALENDAR_API_FEED_SOURCE_CUSTOM_MAPPINGS" "'{}'" }} -CALENDAR_API_FEED_SOURCE_EVENT_MODIFIERS={{ getenv "APP_CALENDAR_API_FEED_SOURCE_EVENT_MODIFIERS" "'{}'" }} -CALENDAR_API_FEED_SOURCE_DATE_FORMAT={{ getenv "APP_CALENDAR_API_FEED_SOURCE_DATE_FORMAT" "" }} -CALENDAR_API_FEED_SOURCE_DATE_TIMEZONE={{ getenv "APP_CALENDAR_API_FEED_SOURCE_DATE_TIMEZONE" "" }} -CALENDAR_API_FEED_SOURCE_CACHE_EXPIRE_SECONDS={{ getenv "APP_CALENDAR_API_FEED_SOURCE_CACHE_EXPIRE_SECONDS" "300" }} -###< Calendar Api Feed Source ### - -EVENTDATABASE_API_V2_CACHE_EXPIRE_SECONDS={{ getenv "APP_EVENTDATABASE_API_V2_CACHE_EXPIRE_SECONDS" "300" }} - -TRACK_SCREEN_INFO={{ getenv "APP_TRACK_SCREEN_INFO" "false" }} -TRACK_SCREEN_INFO_UPDATE_INTERVAL_SECONDS={{ getenv "APP_TRACK_SCREEN_INFO_UPDATE_INTERVAL_SECONDS" "300" }} - -APP_KEY_VAULT_JSON={{ getenv "APP_KEY_VAULT_JSON" "{}" }} diff --git a/infrastructure/itkdev/nginx/Dockerfile b/infrastructure/itkdev/nginx/Dockerfile deleted file mode 100644 index 7a0334dd9..000000000 --- a/infrastructure/itkdev/nginx/Dockerfile +++ /dev/null @@ -1,37 +0,0 @@ -ARG APP_VERSION="develop" -FROM itkdev/os2display-api-service:${APP_VERSION} as APPLICATION - -FROM nginxinc/nginx-unprivileged:alpine -LABEL maintainer="ITK Dev " -ARG UID=101 -ARG GID=101 - -ENV APP_PATH=/var/www/html - -USER root - -RUN mkdir -p ${APP_PATH}/public - -COPY --from=APPLICATION ${APP_PATH}/public ${APP_PATH}/public - -WORKDIR ${APP_PATH} - -# Copy configuration. -COPY etc/ /etc/ - -# Install configuration template handler -ADD https://github.com/kelseyhightower/confd/releases/download/v0.16.0/confd-0.16.0-linux-amd64 /usr/local/bin/confd -RUN chmod +x /usr/local/bin/confd - -COPY docker-entrypoint.sh / -RUN chmod +x /docker-entrypoint.sh \ - && chown -R $UID:0 ${APP_PATH} \ - && chmod -R g+w ${APP_PATH} - -USER $UID - -EXPOSE 8080 - -ENTRYPOINT [ "/docker-entrypoint.sh" ] - -CMD ["nginx", "-g", "daemon off;"] diff --git a/infrastructure/itkdev/nginx/docker-entrypoint.sh b/infrastructure/itkdev/nginx/docker-entrypoint.sh deleted file mode 100644 index 978fa9f4e..000000000 --- a/infrastructure/itkdev/nginx/docker-entrypoint.sh +++ /dev/null @@ -1,49 +0,0 @@ -#!/bin/sh - -set -eux - -## Run templates with configuration. -/usr/local/bin/confd --onetime --backend env --confdir /etc/confd - -entrypoint_log() { - if [ -z "${NGINX_ENTRYPOINT_QUIET_LOGS:-}" ]; then - echo "$@" - fi -} - -if [ "$1" = "nginx" -o "$1" = "nginx-debug" ]; then - if /usr/bin/find "/docker-entrypoint.d/" -mindepth 1 -maxdepth 1 -type f -print -quit 2>/dev/null | read v; then - entrypoint_log "$0: /docker-entrypoint.d/ is not empty, will attempt to perform configuration" - - entrypoint_log "$0: Looking for shell scripts in /docker-entrypoint.d/" - find "/docker-entrypoint.d/" -follow -type f -print | sort -V | while read -r f; do - case "$f" in - *.envsh) - if [ -x "$f" ]; then - entrypoint_log "$0: Sourcing $f"; - . "$f" - else - # warn on shell scripts without exec bit - entrypoint_log "$0: Ignoring $f, not executable"; - fi - ;; - *.sh) - if [ -x "$f" ]; then - entrypoint_log "$0: Launching $f"; - "$f" - else - # warn on shell scripts without exec bit - entrypoint_log "$0: Ignoring $f, not executable"; - fi - ;; - *) entrypoint_log "$0: Ignoring $f";; - esac - done - - entrypoint_log "$0: Configuration complete; ready for start up" - else - entrypoint_log "$0: No files found in /docker-entrypoint.d/, skipping configuration" - fi -fi - -exec "$@" diff --git a/infrastructure/itkdev/nginx/etc/confd/conf.d/default.conf.toml b/infrastructure/itkdev/nginx/etc/confd/conf.d/default.conf.toml deleted file mode 100644 index 185954f0d..000000000 --- a/infrastructure/itkdev/nginx/etc/confd/conf.d/default.conf.toml +++ /dev/null @@ -1,7 +0,0 @@ -[template] -src = "default.conf.tmpl" -dest = "/etc/nginx/conf.d/default.conf" -mode = "0644" -keys = [ - "/nginx-config" -] diff --git a/infrastructure/itkdev/nginx/etc/confd/conf.d/nginx.conf.toml b/infrastructure/itkdev/nginx/etc/confd/conf.d/nginx.conf.toml deleted file mode 100644 index 7c81a661f..000000000 --- a/infrastructure/itkdev/nginx/etc/confd/conf.d/nginx.conf.toml +++ /dev/null @@ -1,7 +0,0 @@ -[template] -src = "nginx.conf.tmpl" -dest = "/etc/nginx/nginx.conf" -mode = "0644" -keys = [ - "/nginx-config" -] diff --git a/infrastructure/itkdev/nginx/etc/confd/templates/default.conf.tmpl b/infrastructure/itkdev/nginx/etc/confd/templates/default.conf.tmpl deleted file mode 100644 index b6f32099b..000000000 --- a/infrastructure/itkdev/nginx/etc/confd/templates/default.conf.tmpl +++ /dev/null @@ -1,52 +0,0 @@ -# @see https://symfony.com/doc/current/setup/web_server_configuration.html -server { - listen 8080; - server_name localhost; - root /var/www/html/public; - - location / { - add_header X-Robots-Tag "noindex, nofollow, nosnippet, noarchive"; - - # try to serve file directly, fallback to index.php - try_files $uri /index.php$is_args$args; - } - - location = /robots.txt { - add_header Content-Type text/plain; - add_header X-Robots-Tag "noindex, nofollow, nosnippet, noarchive"; - return 200 "User-agent: *\nDisallow: /\n"; - } - - location ~ ^/index\.php(/|$) { - fastcgi_pass {{ getenv "PHP_FPM_SERVER" "phpfpm" }}:{{ getenv "PHP_FPM_SERVER_PORT" "9000" }}; - fastcgi_split_path_info ^(.+\.php)(/.*)$; - include fastcgi_params; - - fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; - fastcgi_param DOCUMENT_ROOT $realpath_root; - - internal; - } - - # return 404 for all other php files not matching the front controller - # this prevents access to other php files you don't want to be accessible. - location ~ \.php$ { - return 404; - } - - error_log /var/log/nginx/error.log; - access_log /var/log/nginx/access.log; -} - -server { - listen 8080; - server_name localhost; - root /var/www/html/public; - - error_log off; - access_log off; - - location /stub_status { - stub_status; - } -} diff --git a/infrastructure/itkdev/nginx/etc/confd/templates/nginx.conf.tmpl b/infrastructure/itkdev/nginx/etc/confd/templates/nginx.conf.tmpl deleted file mode 100644 index 29d5283af..000000000 --- a/infrastructure/itkdev/nginx/etc/confd/templates/nginx.conf.tmpl +++ /dev/null @@ -1,52 +0,0 @@ -worker_processes auto; - -error_log /var/log/nginx/error.log warn; -pid /tmp/nginx.pid; - -events { - worker_connections 2048; - multi_accept on; -} - - -http { - open_file_cache max=10000 inactive=5m; - open_file_cache_valid 5m; - open_file_cache_min_uses 5; - open_file_cache_errors off; - - sendfile on; - tcp_nopush on; - tcp_nodelay on; - keepalive_timeout 15 15; - types_hash_max_size 2048; - - server_tokens off; - - client_max_body_size {{ getenv "NGINX_FPM_UPLOAD_MAX" "8M" }}; - - gzip on; - gzip_disable "msie6"; - gzip_vary on; - gzip_proxied any; - gzip_comp_level 6; - gzip_buffers 16 8k; - gzip_http_version 1.0; - gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript; - - include /etc/nginx/mime.types; - default_type application/octet-stream; - - set_real_ip_from 172.16.0.0/8; - real_ip_recursive on; - real_ip_header X-Forwarded-For; - - log_format main '$http_x_real_ip - $remote_user [$time_local] "$request" ' - '$status $body_bytes_sent "$http_referer" ' - '"$http_user_agent" "$http_x_forwarded_for"'; - - error_log /dev/stderr; - access_log /dev/stdout main; - - include /etc/nginx/conf.d/*.conf; -} diff --git a/infrastructure/itkdev/run.sh b/infrastructure/itkdev/run.sh deleted file mode 100755 index b028f5cdc..000000000 --- a/infrastructure/itkdev/run.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/sh - -set -eux - -APP_VERSION=develop - -docker pull nginxinc/nginx-unprivileged:alpine - -docker build --pull --no-cache --build-arg APP_VERSION=${APP_VERSION} --tag=itkdev/os2display-api-service:${APP_VERSION} --file="display-api-service/Dockerfile" display-api-service -docker build --no-cache --build-arg VERSION=${APP_VERSION} --tag=itkdev/os2display-api-service-nginx:${APP_VERSION} --file="nginx/Dockerfile" nginx - -# docker push itkdev/os2display-api-service:${APP_VERSION} -# docker push itkdev/os2display-api-service-nginx:${APP_VERSION} diff --git a/infrastructure/nginx/Dockerfile b/infrastructure/nginx/Dockerfile new file mode 100644 index 000000000..8d6c7ecab --- /dev/null +++ b/infrastructure/nginx/Dockerfile @@ -0,0 +1,35 @@ +ARG APP_VERSION="develop" +ARG APP_IMAGE="os2display-api-service" + +FROM --platform=$BUILDPLATFORM ghcr.io/${APP_IMAGE}:${APP_VERSION} AS app + +################################ +# Nginx production image +################################ +FROM --platform=$BUILDPLATFORM nginxinc/nginx-unprivileged:alpine +LABEL maintainer="ITK Dev " + +ENV NGINX_PORT=8080 \ + NGINX_SET_REAL_IP_FROM=172.17.0.0/16 \ + NGINX_MAX_BODY_SIZE=10m + +WORKDIR /app + +USER root + +# Create directory and copy built client assets +RUN mkdir -p ./public +COPY --from=app --chown=nginx:nginx /app/public ./public + +# Copy configuration +COPY --chown=nginx:nginx etc /etc/nginx + +# Add health check +HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ + CMD wget --no-verbose --tries=1 --spider http://localhost:${NGINX_PORT}/health || exit 1 + +USER nginx + +EXPOSE ${NGINX_PORT} + +CMD ["nginx", "-g", "daemon off;"] diff --git a/infrastructure/nginx/etc/nginx.conf b/infrastructure/nginx/etc/nginx.conf new file mode 100644 index 000000000..90db47241 --- /dev/null +++ b/infrastructure/nginx/etc/nginx.conf @@ -0,0 +1,77 @@ +# Note: 'user' directive is not needed in nginx-unprivileged image +worker_processes auto; +worker_rlimit_nofile 65535; + +error_log /dev/stderr notice; +pid /tmp/nginx.pid; + +events { + worker_connections 2048; + use epoll; + multi_accept on; +} + +http { + open_file_cache max=10000 inactive=5m; + open_file_cache_valid 5m; + open_file_cache_min_uses 5; + open_file_cache_errors off; + + sendfile on; + tcp_nopush on; + tcp_nodelay on; + keepalive_timeout 15 15; + types_hash_max_size 2048; + + server_tokens off; + + # Compression + gzip on; + gzip_vary on; + gzip_min_length 1024; + gzip_comp_level 6; + gzip_buffers 16 8k; + gzip_http_version 1.1; + gzip_types + text/plain + text/css + text/xml + text/javascript + application/javascript + application/x-javascript + application/json + application/xml + application/xml+rss + application/rss+xml + application/atom+xml + image/svg+xml + font/truetype + font/opentype + application/vnd.ms-fontobject + application/font-woff + application/font-woff2; + gzip_disable "msie6"; + gzip_proxied any; + + # Security headers + add_header X-Frame-Options "SAMEORIGIN" always; + add_header X-Content-Type-Options "nosniff" always; + add_header X-XSS-Protection "1; mode=block" always; + add_header Referrer-Policy "strict-origin-when-cross-origin" always; + add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always; + + # Rate limiting zones + limit_req_zone $binary_remote_addr zone=php_limit:10m rate=10r/s; + + include /etc/nginx/mime.types; + default_type application/octet-stream; + + log_format main '$http_x_real_ip - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + + error_log /dev/stderr; + access_log /dev/stdout main; + + include /etc/nginx/conf.d/*.conf; +} diff --git a/infrastructure/nginx/etc/templates/default.conf.template b/infrastructure/nginx/etc/templates/default.conf.template new file mode 100644 index 000000000..eacfa67e2 --- /dev/null +++ b/infrastructure/nginx/etc/templates/default.conf.template @@ -0,0 +1,138 @@ +server { + listen ${NGINX_PORT}; + listen [::]:${NGINX_PORT}; + server_name localhost; + + root /app/public; + index index.php index.html; + + # Health check endpoint + location /health { + access_log off; + add_header Content-Type text/plain; + return 200 "healthy\n"; + } + + # Upload limits + client_max_body_size ${NGINX_MAX_BODY_SIZE}; + + # Security headers + add_header X-Content-Type-Options "nosniff" always; + add_header X-Frame-Options "DENY" always; + add_header Referrer-Policy "strict-origin-when-cross-origin" always; + + # Real IP from reverse proxy + set_real_ip_from ${NGINX_SET_REAL_IP_FROM}; + real_ip_recursive on; + real_ip_header X-Forwarded-For; + + location / { + # Prevent indexing of API routes + add_header X-Robots-Tag "noindex, nofollow, nosnippet, noarchive"; + + # try to serve file directly, fallback to index.php + try_files $uri /index.php$is_args$args; + } + + # Cache static assets built by Vite under /public/build + location /build/ { + access_log off; + log_not_found off; + + # Serve files directly + try_files $uri =404; + + # Long-term caching for fingerprinted assets + add_header Cache-Control "public, max-age=31536000, immutable" always; + add_header Access-Control-Allow-Origin "*" always; + add_header X-Robots-Tag "noindex, nofollow, nosnippet, noarchive" always; + expires 1y; + } + + # Static files with caching + location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff|woff2|ttf|eot)$ { + expires 1y; + add_header Cache-Control "public, immutable"; + access_log off; + } + + # Screen client online check should just serve static files + location /client/online-check { + index index.html; + } + + location = /robots.txt { + add_header Content-Type text/plain; + add_header X-Robots-Tag "noindex, nofollow, nosnippet, noarchive"; + return 200 "User-agent: *\nDisallow: /\n"; + } + + # Protect sensitive file extensions + location ~* \.(engine|inc|install|make|module|profile|po|sh|sql|tar|gz|bz2|theme|twig|tpl|xtmpl|yml)$ { + deny all; + return 404; + } + + # Protect backup and temporary files + location ~* \.(bak|orig|save|sw[op])$ { + deny all; + return 404; + } + + # Protect dotfiles except .well-known + location ~ /\.(?!well-known) { + deny all; + return 404; + } + + # Protect specific files + location ~ ^/(composer\.(json|lock)|web\.config)$ { + deny all; + return 404; + } + + # PHP-FPM handling + location ~ ^/index\.php(/|$) { + fastcgi_pass ${NGINX_FPM_SERVICE}:${NGINX_FPM_PORT}; + fastcgi_split_path_info ^(.+\.php)(/.*)$; + include fastcgi_params; + + limit_req zone=php_limit burst=20 nodelay; + + # Increase buffer sizes for large responses + fastcgi_buffers 16 32k; + fastcgi_buffer_size 64k; + fastcgi_busy_buffers_size 64k; + + # Timeout settings + fastcgi_connect_timeout 60s; + fastcgi_send_timeout 60s; + fastcgi_read_timeout 60s; + + fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; + fastcgi_param DOCUMENT_ROOT $realpath_root; + + internal; + } + + # return 404 for all other php files not matching the front controller + # this prevents access to other php files you don't want to be accessible. + location ~ \.php$ { + return 404; + } + + sendfile on; + keepalive_timeout 65; + + # Client buffer settings + client_body_buffer_size 128k; + client_header_buffer_size 1k; + large_client_header_buffers 4 16k; + + gzip on; + gzip_vary on; + gzip_proxied any; + gzip_comp_level 6; + gzip_types text/plain text/css text/xml text/javascript application/json application/javascript application/xml+rss application/rss+xml font/truetype font/opentype application/vnd.ms-fontobject image/svg+xml; + gzip_disable "msie6"; +} diff --git a/infrastructure/os2display/Readme.md b/infrastructure/os2display/Readme.md deleted file mode 100644 index def6e8a45..000000000 --- a/infrastructure/os2display/Readme.md +++ /dev/null @@ -1,3 +0,0 @@ -# OS2display image build - -This folder contains the infrastructure files for building the `os2display/*` images diff --git a/infrastructure/os2display/display-api-service/Dockerfile b/infrastructure/os2display/display-api-service/Dockerfile deleted file mode 100644 index 2809349f8..000000000 --- a/infrastructure/os2display/display-api-service/Dockerfile +++ /dev/null @@ -1,155 +0,0 @@ -FROM php:8.3-fpm-alpine -LABEL maintainer="ITK Dev " - -############# SETUP CONTAINER ############# - -USER root - -ARG APP_VERSION="develop" - -ENV APP_PATH=/var/www/html \ - # PHP - TZ="Europe/Copenhagen" \ - PHP_TIMEZONE="Europe/Copenhagen" \ - PHP_MAX_EXECUTION_TIME="30" \ - PHP_MEMORY_LIMIT="128M" \ - PHP_POST_MAX_SIZE="8M" \ - PHP_UPLOAD_MAX_FILESIZE="2M" \ - PHP_USER="www-data" \ - PHP_GROUP="www-data" \ - PHP_SENDMAIL_PATH='/usr/sbin/sendmail -S host.docker.internal -t -i' \ - # OpCache - PHP_OPCACHE_ENABLED="1" \ - PHP_OPCACHE_JIT="off" \ - PHP_OPCACHE_REVALIDATE_FREQ=0 \ - PHP_OPCACHE_VALIDATE_TIMESTAMPS="1" \ - PHP_OPCACHE_MAX_ACCELERATED_FILES="20000" \ - PHP_OPCACHE_MEMORY_CONSUMPTION="64" \ - PHP_OPCACHE_MAX_WASTED_PERCENTAGE="10" \ - # APCU - PHP_APCU_ENABLED=0 \ - PHP_APCU_ENABLED_CLI=0 \ - PHP_APCU_MEMORY_SIZE="16M" \ - PHP_APCU_SEGMENTS=1 \ - PHP_APCU_PRELOAD_PATH='' \ - # FPM pool - PHP_PM_TYPE="static" \ - PHP_PM_MAX_CHILDREN="8" \ - PHP_PM_MAX_REQUESTS="0" \ - PHP_PM_START_SERVERS="5" \ - PHP_PM_MIN_SPARE_SERVERS="5" \ - PHP_PM_MAX_SPARE_SERVERS="8" \ - # Other - PHP_REQUEST_SLOWLOG_TIMEOUT="0" \ - PHP_SLOWLOG="/dev/stderr" \ - COMPOSER_ALLOW_SUPERUSER=1 - -RUN apk upgrade --no-cache --ignore curl -RUN apk --update add --no-cache \ - libxslt-dev \ - libzip-dev \ - libpng-dev \ - gettext-dev \ - git \ - unzip \ - icu-dev \ - icu-data-full \ - openldap-dev \ - libmcrypt-dev \ - mysql-client \ - libmemcached-libs \ - zlib \ - patch \ - tzdata \ - freetype-dev \ - libjpeg-turbo-dev \ - libjpeg-turbo \ - libwebp-dev \ - && docker-php-ext-configure gd --with-freetype --with-webp --with-jpeg \ - && docker-php-ext-install -j$(nproc) \ - bcmath \ - calendar \ - gd \ - gettext \ - intl \ - ldap \ - mysqli \ - opcache \ - pdo_mysql \ - sysvsem \ - soap \ - xsl \ - zip - -# Extension that are not available via ext- -RUN apk --update add --no-cache --virtual .build-deps autoconf g++ make zlib-dev libmemcached-dev cyrus-sasl-dev \ - && pecl channel-update pecl.php.net \ - && pecl install redis memcached apcu \ - && docker-php-ext-enable apcu redis memcached \ - && apk del .build-deps - -# Install AMQP support -RUN apk --update add --no-cache rabbitmq-c -RUN apk --update add --no-cache --virtual .build-deps autoconf g++ make rabbitmq-c-dev \ - && pecl install amqp \ - && docker-php-ext-enable amqp memcached \ - && apk del .build-deps - -# Install composer -COPY --from=composer:2 /usr/bin/composer /usr/local/bin/composer - -# Use default PHP production configuration. -RUN mv ${PHP_INI_DIR}/php.ini-production ${PHP_INI_DIR}/php.ini - -# # Copy custom PHP configuration. -COPY php/opcache.ini ${PHP_INI_DIR}/conf.d/docker-php-ext-opcache.ini -COPY php/php.ini ${PHP_INI_DIR}/conf.d/zz-php.ini -COPY php/apcu.ini ${PHP_INI_DIR}/conf.d/docker-php-ext-apcu.ini - -# Custom FPM configuration. -COPY php/fpm.ini ${PHP_INI_DIR}/../php-fpm.d/zz-fpm-docker.conf - -# Add mhsendmail for mailhog -ADD https://github.com/mailhog/mhsendmail/releases/download/v0.2.0/mhsendmail_linux_amd64 /usr/local/bin/mhsendmail -RUN chmod +x /usr/local/bin/mhsendmail - -# Added FPM health check script (https://github.com/renatomefi/php-fpm-healthcheck) -ADD https://raw.githubusercontent.com/renatomefi/php-fpm-healthcheck/master/php-fpm-healthcheck /usr/local/bin/php-fpm-healthcheck -RUN chmod +x /usr/local/bin/php-fpm-healthcheck - -# Add git global config -COPY gitconfig /root/.gitconfig - -############# SETUP APPLICATION ############# - -# Move site into the container. -ADD https://github.com/os2display/display-api-service/archive/${APP_VERSION}.tar.gz /tmp/app.tar -RUN tar -zxf /tmp/app.tar --strip-components=1 -C ${APP_PATH} \ - && rm /tmp/app.tar - -## Install assets, which requires a HACK as redis is not available (should be removed later on). -RUN APP_ENV=prod composer install --no-dev -o --classmap-authoritative \ - && rm -rf infrastructure \ - && APP_ENV=prod composer clear-cache - -# Install the application. -RUN mkdir -p ${APP_PATH}/config/secrets \ - && chown -R www-data:www-data ${APP_PATH} - -# Copy configuration. -COPY etc /etc/ - -# Install configuration template handler -ADD https://github.com/kelseyhightower/confd/releases/download/v0.16.0/confd-0.16.0-linux-amd64 /usr/local/bin/confd -RUN chmod +x /usr/local/bin/confd - -# Copy confd onfiguration. -COPY etc /etc/ - -COPY docker-entrypoint.sh /usr/local/bin/ -RUN chmod +x /usr/local/bin/docker-entrypoint.sh - -WORKDIR ${APP_PATH} - -CMD ["php-fpm"] -ENTRYPOINT [ "docker-entrypoint.sh" ] diff --git a/infrastructure/os2display/display-api-service/docker-entrypoint.sh b/infrastructure/os2display/display-api-service/docker-entrypoint.sh deleted file mode 100644 index 8ad622b4d..000000000 --- a/infrastructure/os2display/display-api-service/docker-entrypoint.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/sh - -set -eux - -## Run templates with configuration. -/usr/local/bin/confd --onetime --backend env --confdir /etc/confd - -## Bump env.local into PHP for better performance. -composer dump-env prod - -## Warm-up Symfony cache (with the current configuration). -/var/www/html/bin/console --env=prod cache:warmup - -# first arg is `-f` or `--some-option` -if [ "${1#-}" != "$1" ]; then - set -- php-fpm "$@" -fi - -## Start the PHP FPM process. -echo "Starting PHP 8.3 FPM" - -exec "$@" diff --git a/infrastructure/os2display/display-api-service/etc/confd/conf.d/env.local.toml b/infrastructure/os2display/display-api-service/etc/confd/conf.d/env.local.toml deleted file mode 100644 index e7f303a3e..000000000 --- a/infrastructure/os2display/display-api-service/etc/confd/conf.d/env.local.toml +++ /dev/null @@ -1,8 +0,0 @@ -[template] -src = "env.local.tmpl" -dest = "/var/www/html/.env.local" -owner = "www-data" -mode = "0644" -keys = [ - "/app-config" -] diff --git a/infrastructure/os2display/display-api-service/etc/confd/templates/env.local.tmpl b/infrastructure/os2display/display-api-service/etc/confd/templates/env.local.tmpl deleted file mode 100644 index 1fa420ab2..000000000 --- a/infrastructure/os2display/display-api-service/etc/confd/templates/env.local.tmpl +++ /dev/null @@ -1,71 +0,0 @@ -###> symfony/framework-bundle ### -APP_ENV={{ getenv "APP_ENV" "prod" }} -APP_SECRET={{ getenv "APP_SECRET" "MySuperSecret" }} -TRUSTED_PROXIES={{ getenv "APP_TRUSTED_PROXIES" "127.0.0.1,REMOTE_ADDR" }} -###< symfony/framework-bundle ### - -###> doctrine/doctrine-bundle ### -DATABASE_URL={{ getenv "APP_DATABASE_URL" "mysql://db:db@mariadb:3306/db?serverVersion=mariadb-10.4.0" }} -###< doctrine/doctrine-bundle ### - -###> nelmio/cors-bundle ### -CORS_ALLOW_ORIGIN={{ getenv "APP_CORS_ALLOW_ORIGIN" "'^https?://localhost(:[0-9]+)?$'" }} -###< nelmio/cors-bundle ### - -###> App ### -APP_DEFAULT_DATE_FORMAT='{{ getenv "APP_DEFAULT_DATE_FORMAT" "Y-m-d\\TH:i:s\\Z" }}' -APP_ACTIVATION_CODE_EXPIRE_INTERNAL='{{ getenv "APP_ACTIVATION_CODE_EXPIRE_INTERNAL" "P2D" }}' -###< App ### - -###> lexik/jwt-authentication-bundle ### -JWT_PASSPHRASE={{ getenv "APP_JWT_PASSPHRASE" }} -JWT_TOKEN_TTL={{ getenv "APP_JWT_TOKEN_TTL" "3600" }} -JWT_SCREEN_TOKEN_TTL={{ getenv "APP_JWT_SCREEN_TOKEN_TTL" "3600" }} -###< lexik/jwt-authentication-bundle ### - -###> gesdinet/jwt-refresh-token-bundle ### -JWT_REFRESH_TOKEN_TTL={{ getenv "APP_JWT_REFRESH_TOKEN_TTL" "2592000" }} -JWT_SCREEN_REFRESH_TOKEN_TTL={{ getenv "APP_JWT_SCREEN_REFRESH_TOKEN_TTL" "2592000" }} -###< gesdinet/jwt-refresh-token-bundle ### - -###> itk-dev/openid-connect-bundle ### -# internal provider -INTERNAL_OIDC_METADATA_URL={{ getenv "APP_INTERNAL_OIDC_METADATA_URL" "" }} -INTERNAL_OIDC_CLIENT_ID={{ getenv "APP_INTERNAL_OIDC_CLIENT_ID" "" }} -INTERNAL_OIDC_CLIENT_SECRET={{ getenv "APP_INTERNAL_OIDC_CLIENT_SECRET" "" }} -INTERNAL_OIDC_REDIRECT_URI={{ getenv "APP_INTERNAL_OIDC_REDIRECT_URI" "" }} -INTERNAL_OIDC_LEEWAY={{ getenv "APP_INTERNAL_OIDC_LEEWAY" "30" }} - -# external provider -EXTERNAL_OIDC_METADATA_URL={{ getenv "APP_EXTERNAL_OIDC_METADATA_URL" "" }} -EXTERNAL_OIDC_CLIENT_ID={{ getenv "APP_EXTERNAL_OIDC_CLIENT_ID" "" }} -EXTERNAL_OIDC_CLIENT_SECRET={{ getenv "APP_EXTERNAL_OIDC_CLIENT_SECRET" "" }} -EXTERNAL_OIDC_REDIRECT_URI={{ getenv "APP_EXTERNAL_OIDC_REDIRECT_URI" "" }} -EXTERNAL_OIDC_LEEWAY={{ getenv "APP_EXTERNAL_OIDC_LEEWAY" "30" }} -EXTERNAL_OIDC_HASH_SALT={{ getenv "APP_EXTERNAL_OIDC_HASH_SALT" "" }} - -CLI_REDIRECT={{ getenv "APP_CLI_REDIRECT" "" }} -###< itk-dev/openid-connect-bundle ### - -###> redis ### -REDIS_CACHE_PREFIX={{ getenv "APP_CLI_REDIRECT" "DisplayApiService" }} -REDIS_CACHE_DSN={{ getenv "APP_CLI_REDIRECT" "redis://redis:6379/0" }} -###< redis ### - -###> Calendar Api Feed Source ### -CALENDAR_API_FEED_SOURCE_LOCATION_ENDPOINT={{ getenv "APP_CALENDAR_API_FEED_SOURCE_LOCATION_ENDPOINT" "" }} -CALENDAR_API_FEED_SOURCE_RESOURCE_ENDPOINT={{ getenv "APP_CALENDAR_API_FEED_SOURCE_RESOURCE_ENDPOINT" "" }} -CALENDAR_API_FEED_SOURCE_EVENT_ENDPOINT={{ getenv "APP_CALENDAR_API_FEED_SOURCE_EVENT_ENDPOINT" "" }} -CALENDAR_API_FEED_SOURCE_CUSTOM_MAPPINGS={{ getenv "APP_CALENDAR_API_FEED_SOURCE_CUSTOM_MAPPINGS" "'{}'" }} -CALENDAR_API_FEED_SOURCE_EVENT_MODIFIERS={{ getenv "APP_CALENDAR_API_FEED_SOURCE_EVENT_MODIFIERS" "'{}'" }} -CALENDAR_API_FEED_SOURCE_DATE_FORMAT={{ getenv "APP_CALENDAR_API_FEED_SOURCE_DATE_FORMAT" "" }} -CALENDAR_API_FEED_SOURCE_DATE_TIMEZONE={{ getenv "APP_CALENDAR_API_FEED_SOURCE_DATE_TIMEZONE" "" }} -CALENDAR_API_FEED_SOURCE_CACHE_EXPIRE_SECONDS={{ getenv "CALENDAR_API_FEED_SOURCE_CACHE_EXPIRE_SECONDS" "300" }} -###< Calendar Api Feed Source ### - -EVENTDATABASE_API_V2_CACHE_EXPIRE_SECONDS={{ getenv "APP_EVENTDATABASE_API_V2_CACHE_EXPIRE_SECONDS" "300" }} - -TRACK_SCREEN_INFO={{ getenv "APP_TRACK_SCREEN_INFO" "false" }} -TRACK_SCREEN_INFO_UPDATE_INTERVAL_SECONDS={{ getenv "APP_TRACK_SCREEN_INFO_UPDATE_INTERVAL_SECONDS" "300" }} - -APP_KEY_VAULT_JSON={{ getenv "APP_KEY_VAULT_JSON" "{}" }} diff --git a/infrastructure/os2display/display-api-service/gitconfig b/infrastructure/os2display/display-api-service/gitconfig deleted file mode 100644 index 60a3b0202..000000000 --- a/infrastructure/os2display/display-api-service/gitconfig +++ /dev/null @@ -1,9 +0,0 @@ -[color] - ui = true - -[alias] - branch-name = !git for-each-ref --format='%(refname:short)' `git symbolic-ref HEAD` - lg = log --graph --pretty=format:'%Cred%h%Creset %Cgreen(%cr) -%C(yellow)%d%Creset %s %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative - -[safe] - directory = * \ No newline at end of file diff --git a/infrastructure/os2display/display-api-service/php/apcu.ini b/infrastructure/os2display/display-api-service/php/apcu.ini deleted file mode 100644 index 86164be82..000000000 --- a/infrastructure/os2display/display-api-service/php/apcu.ini +++ /dev/null @@ -1,7 +0,0 @@ -extension=apcu -apc.enabled=${PHP_APCU_ENABLED} -apc.shm_segments=${PHP_APCU_SEGMENTS} -apc.shm_size=${PHP_APCU_MEMORY_SIZE} - -apc.enable_cli=${PHP_APCU_ENABLED_CLI} -apc.preload_path=${PHP_APCU_PRELOAD_PATH} \ No newline at end of file diff --git a/infrastructure/os2display/display-api-service/php/fpm.ini b/infrastructure/os2display/display-api-service/php/fpm.ini deleted file mode 100644 index 49e0aeb48..000000000 --- a/infrastructure/os2display/display-api-service/php/fpm.ini +++ /dev/null @@ -1,17 +0,0 @@ -[www] -pm = ${PHP_PM_TYPE} -pm.max_children = ${PHP_PM_MAX_CHILDREN} -pm.start_servers = ${PHP_PM_START_SERVERS} -pm.min_spare_servers = ${PHP_PM_MIN_SPARE_SERVERS} -pm.max_spare_servers = ${PHP_PM_MAX_SPARE_SERVERS} -pm.max_requests = ${PHP_PM_MAX_REQUESTS} - -request_slowlog_timeout = ${PHP_REQUEST_SLOWLOG_TIMEOUT} -slowlog = ${PHP_SLOWLOG} - -; Enable the FPM status page -pm.status_path = /status - -user = ${PHP_USER} -group = ${PHP_GROUP} - diff --git a/infrastructure/os2display/display-api-service/php/opcache.ini b/infrastructure/os2display/display-api-service/php/opcache.ini deleted file mode 100644 index 8ff178634..000000000 --- a/infrastructure/os2display/display-api-service/php/opcache.ini +++ /dev/null @@ -1,15 +0,0 @@ -zend_extension=opcache.so - -[opcache] -opcache.jit=${PHP_OPCACHE_JIT} - -opcache.enable=${PHP_OPCACHE_ENABLED} -opcache.revalidate_freq=${PHP_OPCACHE_REVALIDATE_FREQ} -opcache.validate_timestamps=${PHP_OPCACHE_VALIDATE_TIMESTAMPS} -opcache.max_accelerated_files=${PHP_OPCACHE_MAX_ACCELERATED_FILES} -opcache.memory_consumption=${PHP_OPCACHE_MEMORY_CONSUMPTION} -opcache.max_wasted_percentage=${PHP_OPCACHE_MAX_WASTED_PERCENTAGE} -opcache.interned_strings_buffer=16 -opcache.fast_shutdown=1 - -opcache.optimization_level=0xFFFFFFEF diff --git a/infrastructure/os2display/display-api-service/php/php.ini b/infrastructure/os2display/display-api-service/php/php.ini deleted file mode 100644 index 2bfde2b40..000000000 --- a/infrastructure/os2display/display-api-service/php/php.ini +++ /dev/null @@ -1,13 +0,0 @@ -realpath_cache_size = 4096k -realpath_cache_ttl = 600 - -expose_php = Off -max_execution_time = ${PHP_MAX_EXECUTION_TIME} -memory_limit = ${PHP_MEMORY_LIMIT} - -post_max_size = ${PHP_POST_MAX_SIZE} -upload_max_filesize = ${PHP_UPLOAD_MAX_FILESIZE} - -date.timezone = ${PHP_TIMEZONE} - -sendmail_path = ${PHP_SENDMAIL_PATH} diff --git a/infrastructure/os2display/nginx/Dockerfile b/infrastructure/os2display/nginx/Dockerfile deleted file mode 100644 index bc13dcd12..000000000 --- a/infrastructure/os2display/nginx/Dockerfile +++ /dev/null @@ -1,37 +0,0 @@ -ARG APP_VERSION="develop" -FROM os2display/display-api-service:${APP_VERSION} as APPLICATION - -FROM nginxinc/nginx-unprivileged:alpine -LABEL maintainer="ITK Dev " -ARG UID=101 -ARG GID=101 - -ENV APP_PATH=/var/www/html - -USER root - -RUN mkdir -p ${APP_PATH}/public - -COPY --from=APPLICATION ${APP_PATH}/public ${APP_PATH}/public - -WORKDIR ${APP_PATH} - -# Copy configuration. -COPY etc /etc/ - -# Install configuration template handler -ADD https://github.com/kelseyhightower/confd/releases/download/v0.16.0/confd-0.16.0-linux-amd64 /usr/local/bin/confd -RUN chmod +x /usr/local/bin/confd - -COPY docker-entrypoint.sh / -RUN chmod +x /docker-entrypoint.sh \ - && chown -R $UID:0 ${APP_PATH} \ - && chmod -R g+w ${APP_PATH} - -USER $UID - -EXPOSE 8080 - -ENTRYPOINT [ "/docker-entrypoint.sh" ] - -CMD ["nginx", "-g", "daemon off;"] diff --git a/infrastructure/os2display/nginx/docker-entrypoint.sh b/infrastructure/os2display/nginx/docker-entrypoint.sh deleted file mode 100644 index 978fa9f4e..000000000 --- a/infrastructure/os2display/nginx/docker-entrypoint.sh +++ /dev/null @@ -1,49 +0,0 @@ -#!/bin/sh - -set -eux - -## Run templates with configuration. -/usr/local/bin/confd --onetime --backend env --confdir /etc/confd - -entrypoint_log() { - if [ -z "${NGINX_ENTRYPOINT_QUIET_LOGS:-}" ]; then - echo "$@" - fi -} - -if [ "$1" = "nginx" -o "$1" = "nginx-debug" ]; then - if /usr/bin/find "/docker-entrypoint.d/" -mindepth 1 -maxdepth 1 -type f -print -quit 2>/dev/null | read v; then - entrypoint_log "$0: /docker-entrypoint.d/ is not empty, will attempt to perform configuration" - - entrypoint_log "$0: Looking for shell scripts in /docker-entrypoint.d/" - find "/docker-entrypoint.d/" -follow -type f -print | sort -V | while read -r f; do - case "$f" in - *.envsh) - if [ -x "$f" ]; then - entrypoint_log "$0: Sourcing $f"; - . "$f" - else - # warn on shell scripts without exec bit - entrypoint_log "$0: Ignoring $f, not executable"; - fi - ;; - *.sh) - if [ -x "$f" ]; then - entrypoint_log "$0: Launching $f"; - "$f" - else - # warn on shell scripts without exec bit - entrypoint_log "$0: Ignoring $f, not executable"; - fi - ;; - *) entrypoint_log "$0: Ignoring $f";; - esac - done - - entrypoint_log "$0: Configuration complete; ready for start up" - else - entrypoint_log "$0: No files found in /docker-entrypoint.d/, skipping configuration" - fi -fi - -exec "$@" diff --git a/infrastructure/os2display/nginx/etc/confd/conf.d/default.conf.toml b/infrastructure/os2display/nginx/etc/confd/conf.d/default.conf.toml deleted file mode 100644 index 185954f0d..000000000 --- a/infrastructure/os2display/nginx/etc/confd/conf.d/default.conf.toml +++ /dev/null @@ -1,7 +0,0 @@ -[template] -src = "default.conf.tmpl" -dest = "/etc/nginx/conf.d/default.conf" -mode = "0644" -keys = [ - "/nginx-config" -] diff --git a/infrastructure/os2display/nginx/etc/confd/conf.d/nginx.conf.toml b/infrastructure/os2display/nginx/etc/confd/conf.d/nginx.conf.toml deleted file mode 100644 index 7c81a661f..000000000 --- a/infrastructure/os2display/nginx/etc/confd/conf.d/nginx.conf.toml +++ /dev/null @@ -1,7 +0,0 @@ -[template] -src = "nginx.conf.tmpl" -dest = "/etc/nginx/nginx.conf" -mode = "0644" -keys = [ - "/nginx-config" -] diff --git a/infrastructure/os2display/nginx/etc/confd/templates/default.conf.tmpl b/infrastructure/os2display/nginx/etc/confd/templates/default.conf.tmpl deleted file mode 100644 index b6f32099b..000000000 --- a/infrastructure/os2display/nginx/etc/confd/templates/default.conf.tmpl +++ /dev/null @@ -1,52 +0,0 @@ -# @see https://symfony.com/doc/current/setup/web_server_configuration.html -server { - listen 8080; - server_name localhost; - root /var/www/html/public; - - location / { - add_header X-Robots-Tag "noindex, nofollow, nosnippet, noarchive"; - - # try to serve file directly, fallback to index.php - try_files $uri /index.php$is_args$args; - } - - location = /robots.txt { - add_header Content-Type text/plain; - add_header X-Robots-Tag "noindex, nofollow, nosnippet, noarchive"; - return 200 "User-agent: *\nDisallow: /\n"; - } - - location ~ ^/index\.php(/|$) { - fastcgi_pass {{ getenv "PHP_FPM_SERVER" "phpfpm" }}:{{ getenv "PHP_FPM_SERVER_PORT" "9000" }}; - fastcgi_split_path_info ^(.+\.php)(/.*)$; - include fastcgi_params; - - fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; - fastcgi_param DOCUMENT_ROOT $realpath_root; - - internal; - } - - # return 404 for all other php files not matching the front controller - # this prevents access to other php files you don't want to be accessible. - location ~ \.php$ { - return 404; - } - - error_log /var/log/nginx/error.log; - access_log /var/log/nginx/access.log; -} - -server { - listen 8080; - server_name localhost; - root /var/www/html/public; - - error_log off; - access_log off; - - location /stub_status { - stub_status; - } -} diff --git a/infrastructure/os2display/nginx/etc/confd/templates/nginx.conf.tmpl b/infrastructure/os2display/nginx/etc/confd/templates/nginx.conf.tmpl deleted file mode 100644 index 254adf3ec..000000000 --- a/infrastructure/os2display/nginx/etc/confd/templates/nginx.conf.tmpl +++ /dev/null @@ -1,51 +0,0 @@ -worker_processes auto; - -error_log /var/log/nginx/error.log warn; -pid /tmp/nginx.pid; - -events { - worker_connections 2048; - multi_accept on; -} - - -http { - open_file_cache max=10000 inactive=5m; - open_file_cache_valid 5m; - open_file_cache_min_uses 5; - open_file_cache_errors off; - - sendfile on; - tcp_nopush on; - tcp_nodelay on; - keepalive_timeout 15 15; - types_hash_max_size 2048; - - server_tokens off; - - client_max_body_size {{ getenv "NGINX_FPM_UPLOAD_MAX" "8M" }}; - - gzip on; - gzip_disable "msie6"; - gzip_vary on; - gzip_proxied any; - gzip_comp_level 6; - gzip_buffers 16 8k; - gzip_http_version 1.0; - gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript; - - include /etc/nginx/mime.types; - default_type application/octet-stream; - - set_real_ip_from 172.16.0.0/8; - real_ip_recursive on; - real_ip_header X-Forwarded-For; - - log_format main '$http_x_real_ip - $remote_user [$time_local] "$request" ' - '$status $body_bytes_sent "$http_referer" ' - '"$http_user_agent" "$http_x_forwarded_for"'; - error_log /dev/stderr; - access_log /dev/stdout main; - - include /etc/nginx/conf.d/*.conf; -} diff --git a/infrastructure/os2display/run.sh b/infrastructure/os2display/run.sh deleted file mode 100755 index ae23d67b4..000000000 --- a/infrastructure/os2display/run.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/sh - -set -eux - -APP_VERSION=develop - -docker pull nginxinc/nginx-unprivileged:alpine - -docker build --pull --no-cache --build-arg APP_VERSION=${APP_VERSION} --tag=os2display/display-api-service:${APP_VERSION} --file="display-api-service/Dockerfile" display-api-service -docker build --no-cache --build-arg VERSION=${APP_VERSION} --tag=os2display/display-api-service-nginx:${APP_VERSION} --file="nginx/Dockerfile" nginx - -# docker push os2display/display-api-service:${APP_VERSION} -# docker push os2display/display-api-service-nginx:${APP_VERSION} diff --git a/infrastructure/package-lock.json b/infrastructure/package-lock.json deleted file mode 100644 index 4ca926f5d..000000000 --- a/infrastructure/package-lock.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "app", - "lockfileVersion": 3, - "requires": true, - "packages": {} -} diff --git a/psalm-baseline.xml b/psalm-baseline.xml index 66e0b071e..5304ec920 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -1,16 +1,165 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + repeat(u($title)->length())]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + repeat(u($password)->length())]]> + + + + + + @@ -20,34 +169,284 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + getKernel()->getProjectDir() : getcwd()]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -55,6 +454,9 @@ + + + @@ -64,34 +466,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -99,7 +539,15 @@ + + + + + + + + @@ -108,6 +556,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + @@ -163,34 +636,128 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + modifiedAt]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + playlistSlides]]> @@ -212,18 +779,32 @@ + + + + + + + + + + + + + + @@ -232,18 +813,32 @@ + + + + + + + + + + + + + + @@ -252,13 +847,38 @@ + + + + + + + + + + + + + getTenant()]]> + + + + + + + + + + + + userRoleTenants->first()->getTenant()]]> @@ -276,43 +896,723 @@ getUserType()]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + getId()]]> + getId()]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + getId()]]> + getId()]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -332,6 +1632,9 @@ + + + @@ -346,6 +1649,9 @@ + + + @@ -356,30 +1662,98 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + getId()]]> getModifiedAt()]]> + + + + + + + + + + + + + + + + getId()]]> getModifiedAt()]]> + + + + + + + + + + + + getId()]]> getModifiedAt()]]> + + + + getPlaylist()]]> @@ -388,63 +1762,175 @@ + + + + getId()]]> + + + + getId()]]> getModifiedAt()]]> + + + + + + + getId()]]> + + + + + + + + + + + + getId()]]> getModifiedAt()]]> + + + + + + + + + + + + + + + getId()]]> + + + + + + + + + + + + + + getId()]]> getModifiedAt()]]> iriConverter->getIriFromResource($layout)]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + getId()]]> getModifiedAt()]]> + + + + + + getId()]]> getModifiedAt()]]> + + + + + + + + + + + + getId()]]> getModifiedAt()]]> + + + + + + @@ -453,6 +1939,12 @@ + + + + + + getModifiedAt()]]> @@ -461,9 +1953,17 @@ + + + + + + + + getId()]]> getId()]]> @@ -472,12 +1972,41 @@ getId()]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/psalm.xml b/psalm.xml index 2d36c754f..68f8dc238 100644 --- a/psalm.xml +++ b/psalm.xml @@ -16,18 +16,6 @@ - - - - - - - - - - - - diff --git a/src/Command/Checksum/RecalculateChecksumCommand.php b/src/Command/Checksum/RecalculateChecksumCommand.php index 43d5b53a9..a77d52d5c 100644 --- a/src/Command/Checksum/RecalculateChecksumCommand.php +++ b/src/Command/Checksum/RecalculateChecksumCommand.php @@ -24,7 +24,7 @@ name: 'app:checksum:recalculate', description: 'Recalculate relation checksums for slides and media entities' )] -class RecalculateChecksumCommand extends Command +final class RecalculateChecksumCommand extends Command { private const string OPTION_TENANT = 'tenant'; private const string OPTION_MODIFIED_AFTER = 'modified-after'; diff --git a/src/Security/AzureOidcAuthenticator.php b/src/Security/AzureOidcAuthenticator.php index f93be068a..427e297e7 100644 --- a/src/Security/AzureOidcAuthenticator.php +++ b/src/Security/AzureOidcAuthenticator.php @@ -96,6 +96,7 @@ public function authenticate(Request $request): Passport } // Check if user exists already - if not create a user + /* @var User|null $user */ $user = $this->entityManager->getRepository(User::class)->findOneBy(['providerId' => $providerId]); if (null === $user) { @@ -114,7 +115,7 @@ public function authenticate(Request $request): Passport if (self::OIDC_PROVIDER_INTERNAL === $provider) { // Set tenants from claims. - $oidcGroups = $claims[$this->oidcInternalClaimGroups] ?? []; + $oidcGroups = (array) ($claims[$this->oidcInternalClaimGroups] ?? []); $this->setTenantRoles($user, $oidcGroups); } diff --git a/src/Service/RelationsChecksumCalculator.php b/src/Service/RelationsChecksumCalculator.php index 2e76cf999..187fe4f72 100644 --- a/src/Service/RelationsChecksumCalculator.php +++ b/src/Service/RelationsChecksumCalculator.php @@ -16,7 +16,7 @@ * Extracted from RelationsChecksumListener to allow reuse in console commands * and other contexts outside Doctrine lifecycle events. */ -class RelationsChecksumCalculator +final class RelationsChecksumCalculator { public const array CHECKSUM_TABLES = ['feed_source', 'feed', 'slide', 'media', 'theme', 'template', 'playlist_slide', 'playlist', 'screen_campaign', 'screen', 'screen_group_campaign', 'screen_group', diff --git a/src/Service/ScreenLayoutService.php b/src/Service/ScreenLayoutService.php index 8414f4096..507e0dc5d 100644 --- a/src/Service/ScreenLayoutService.php +++ b/src/Service/ScreenLayoutService.php @@ -72,11 +72,10 @@ public function install(ScreenLayoutData $screenLayoutData, bool $update = false $ulid = Ulid::fromString($screenLayoutData->id); $screenLayout->setId($ulid); + $screenLayout->setTitle($screenLayoutData->title); $this->entityManager->persist($screenLayout); - } - - if ($update) { + } elseif ($update) { $screenLayout->setTitle($screenLayoutData->title); } diff --git a/src/Service/TemplateService.php b/src/Service/TemplateService.php index 123a2b29c..c747a2a69 100644 --- a/src/Service/TemplateService.php +++ b/src/Service/TemplateService.php @@ -69,11 +69,10 @@ public function install(TemplateData $templateData, bool $update = false): void $ulid = Ulid::fromString($templateData->id); $template->setId($ulid); + $template->setTitle($templateData->title); $this->entityManager->persist($template); - } - - if ($update) { + } elseif ($update) { $template->setTitle($templateData->title); }