From ca08f35d0841fa0774dec73c39a310114db0ab43 Mon Sep 17 00:00:00 2001 From: Arnaud J Le Hors Date: Fri, 29 Nov 2024 15:07:21 +0100 Subject: [PATCH 1/3] Add search form to Admin models page Signed-off-by: Arnaud J Le Hors --- web/modules/mof/src/Form/ModelSearchForm.php | 8 ++- web/modules/mof/src/ModelAdminListBuilder.php | 64 ++++++++++++++++++- web/modules/mof/src/ModelListBuilder.php | 2 +- 3 files changed, 68 insertions(+), 6 deletions(-) diff --git a/web/modules/mof/src/Form/ModelSearchForm.php b/web/modules/mof/src/Form/ModelSearchForm.php index d262967..13745ab 100644 --- a/web/modules/mof/src/Form/ModelSearchForm.php +++ b/web/modules/mof/src/Form/ModelSearchForm.php @@ -30,9 +30,11 @@ public function getFormId() { /** * {@inheritdoc} */ - public function buildForm(array $form, FormStateInterface $form_state) { + public function buildForm(array $form, FormStateInterface $form_state, string $collection_name = NULL) { $req = $this->request; + $form['collection'] = $collection_name; + $form['search'] = [ '#type' => 'details', '#title' => $this->t('Search filters'), @@ -93,14 +95,14 @@ public function submitForm(array &$form, FormStateInterface $form_state) { unset($query['org']); } - $form_state->setRedirect('entity.model.collection', $query); + $form_state->setRedirect($form['collection'], $query); } /** * Reset the form. */ public function resetForm(array $form, FormStateInterface $form_state) { - $form_state->setRedirect('entity.model.collection'); + $form_state->setRedirect($form['collection']); } } diff --git a/web/modules/mof/src/ModelAdminListBuilder.php b/web/modules/mof/src/ModelAdminListBuilder.php index d76e9e0..4d20422 100644 --- a/web/modules/mof/src/ModelAdminListBuilder.php +++ b/web/modules/mof/src/ModelAdminListBuilder.php @@ -4,17 +4,55 @@ namespace Drupal\mof; -use Drupal\Core\Entity\EntityListBuilder; +use Drupal\Core\Entity\EntityTypeInterface; +use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Entity\EntityListBuilder; use Drupal\Core\Entity\Query\QueryInterface; +use Drupal\Core\Form\FormBuilderInterface; use Drupal\Core\Url; use Drupal\mof\Entity\Model; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RedirectResponse; class ModelAdminListBuilder extends EntityListBuilder { use PageLimitTrait; + private $formBuilder; + + private $request; + + /** + * {@inheritdoc} + */ + public function __construct( + EntityTypeInterface $entity_type, + EntityStorageInterface $storage, + FormBuilderInterface $form_builder, + Request $request + ) { + parent::__construct($entity_type, $storage); + $this->formBuilder = $form_builder; + $this->request = $request; + } + + /** + * {@inheritdoc} + */ + public static function createInstance( + ContainerInterface $container, + EntityTypeInterface $entity_type + ) { + return new static( + $entity_type, + $container->get('entity_type.manager')->getStorage($entity_type->id()), + $container->get('form_builder'), + $container->get('request_stack')->getCurrentRequest() + ); + } + /** * {@inheritdoc} */ @@ -64,6 +102,16 @@ protected function getEntityListQuery(): QueryInterface { $query = parent::getEntityListQuery(); $query->sort('id', 'DESC'); + if ($label = $this->request->get('label')) { + $label = addcslashes($label, '\\%_'); + $query->condition('label', "%{$label}%", 'LIKE'); + } + + if ($org = $this->request->get('org')) { + $org = addcslashes($org, '\\%_'); + $query->condition('organization', "%{$org}%", 'LIKE'); + } + if ($this->limit) { $query->pager($this->limit); } @@ -99,7 +147,19 @@ public function buildRow(EntityInterface $entity): array { * {@inheritdoc} */ public function render(): array|RedirectResponse { - return ($url = $this->getPageRedirectUrl()) != NULL ? $this->redirectPage($url) : parent::render(); + if (($url = $this->getPageRedirectUrl()) !== NULL) { + return $this->redirectPage($url); + } + + $build = parent::render(); + $build['#attached']['library'][] = 'mof/model-list'; + $build['search'] = $this->formBuilder->getForm('\Drupal\mof\Form\ModelSearchForm', 'entity.model.admin_collection'); + $build['search']['#weight'] = -100; + $build['table']['#attributes']['class'][] = 'tablesaw'; + $build['table']['#attributes']['class'][] = 'tablesaw-stack'; + $build['table']['#attributes']['data-tablesaw-mode'] = 'stack'; + + return $build; } } diff --git a/web/modules/mof/src/ModelListBuilder.php b/web/modules/mof/src/ModelListBuilder.php index 1d3e987..ee854cc 100644 --- a/web/modules/mof/src/ModelListBuilder.php +++ b/web/modules/mof/src/ModelListBuilder.php @@ -71,7 +71,7 @@ public function render(): array|RedirectResponse { $build = parent::render(); $build['#attached']['library'][] = 'mof/model-list'; - $build['search'] = $this->formBuilder->getForm('\Drupal\mof\Form\ModelSearchForm'); + $build['search'] = $this->formBuilder->getForm('\Drupal\mof\Form\ModelSearchForm', 'entity.model.collection'); $build['search']['#weight'] = -100; $build['table']['#attributes']['class'][] = 'tablesaw'; $build['table']['#attributes']['class'][] = 'tablesaw-stack'; From 70c91d326a31ba8e4b18f9663e01182c6d6ebe44 Mon Sep 17 00:00:00 2001 From: Greg Date: Mon, 2 Dec 2024 18:26:58 -0500 Subject: [PATCH 2/3] Merge from main --- .github/workflows/deploy.yml | 5 +- API.md | 89 ++ composer.json | 6 +- composer.lock | 923 +++++++++--------- models/Aquila-VL-2B.yml | 117 +++ models/Jiang-Base.yml | 117 +++ models/Jurassic-1-Jumbo.yml | 116 +++ models/MiniCPM3-4B.yml | 116 +++ models/PanGu-a.yml | 4 +- models/StellarX-4B-V0.yml | 117 +++ .../config/install/rest.resource.model_v1.yml | 17 + web/modules/mof/mof.info.yml | 5 +- web/modules/mof/mof.install | 29 + web/modules/mof/mof.module | 23 +- web/modules/mof/mof.services.yml | 18 + .../mof/src/Controller/ModelController.php | 36 +- .../ApiExceptionSubscriber.php | 47 + web/modules/mof/src/ModelEvaluator.php | 2 +- .../mof/src/ModelEvaluatorInterface.php | 4 +- web/modules/mof/src/ModelSerializer.php | 56 +- .../mof/src/ModelSerializerInterface.php | 41 + .../rest/resource/ModelEntityResourceV1.php | 249 +++++ web/modules/mof/src/RateLimitMiddleware.php | 86 ++ 23 files changed, 1698 insertions(+), 525 deletions(-) create mode 100644 API.md create mode 100644 models/Aquila-VL-2B.yml create mode 100644 models/Jiang-Base.yml create mode 100644 models/Jurassic-1-Jumbo.yml create mode 100644 models/MiniCPM3-4B.yml create mode 100644 models/StellarX-4B-V0.yml create mode 100644 web/modules/mof/config/install/rest.resource.model_v1.yml create mode 100644 web/modules/mof/mof.install create mode 100644 web/modules/mof/src/EventSubscriber/ApiExceptionSubscriber.php create mode 100644 web/modules/mof/src/ModelSerializerInterface.php create mode 100644 web/modules/mof/src/Plugin/rest/resource/ModelEntityResourceV1.php create mode 100644 web/modules/mof/src/RateLimitMiddleware.php diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index bd31f24..f5242cf 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -85,7 +85,7 @@ jobs: --exclude '.github' \ --exclude '.env' \ --exclude 'tests' \ - --exclude 'config' \ + --exclude 'config/sync' \ --exclude 'models/' \ --exclude 'web/sites/*/files' \ --exclude 'web/libraries' \ @@ -97,8 +97,9 @@ jobs: echo "Deploying to $DEPLOY_PATH" cd $DEPLOY_PATH composer install --no-dev --no-progress --optimize-autoloader - ./vendor/bin/drush cr ./vendor/bin/drush updb -y + ./vendor/bin/drush cim --partial --source=modules/mof/config/install -y + ./vendor/bin/drush cr EOF - name: Revoke IP address diff --git a/API.md b/API.md new file mode 100644 index 0000000..e01a7ad --- /dev/null +++ b/API.md @@ -0,0 +1,89 @@ +# API + +## Overview + +This API provides read-only access to a collection of models. It is open to the public and does not require an API key for access. + +### Response Format + +- All responses are in **JSON** format. + +### Rate Limiting + +- **Limit**: 10,000 requests per hour per IP address. +- Exceeding this limit will result in temporary rate-limiting. +- Rate-limited responses include the following structure: +```json +{ + "error": { + "code": 429, + "message": "Rate limit exceeded. Try again later." + } +} +``` + +--- + +## Endpoints + +### **GET /api/v1/models** + +Lists all models with pagination. + +#### Query Parameters: +- `page` (optional): The page number to retrieve (default: `1`). Pages are 1-indexed. +- `limit` (optional): The number of models per page (default: `100`). + +#### Example Request: +```http +GET /api/v1/models?page=2&limit=50 +``` + +#### Example Response: +```json +{ + "pager": { + "total_items": 235, + "total_pages": 5, + "current_page": 2 + }, + "models": [...] +} +``` + +--- + +### **GET /api/v1/model/{model}** + +Retrieves details of a specific model. + +#### Path Parameters: +- `model`: The ID of the model to retrieve. Model IDs can be found using the `/api/v1/models` endpoint. + +#### Example Request: +```http +GET /api/v1/model/1130 +``` + +#### Example Response: +```json +{ + "id": "1130", + "framework": { + "name": "Model Openness Framework", + "version": "1.0", + "date": "2024-12-15" + }, + "release": {...}, + "classification": { + "class": 1, + "label": "Class I - Open Science", + "progress": { + "1": 100, + "2": 100, + "3": 100 + } + } +} +``` + diff --git a/composer.json b/composer.json index e6e409f..4c42cef 100644 --- a/composer.json +++ b/composer.json @@ -19,9 +19,9 @@ "cweagans/composer-patches": "^1.7", "drupal/block_exclude_pages": "^2.1", "drupal/cheeseburger_menu": "^5.0@RC", - "drupal/core-composer-scaffold": "^10.2", - "drupal/core-project-message": "^10.2", - "drupal/core-recommended": "^10.2", + "drupal/core-composer-scaffold": "10.3.10", + "drupal/core-project-message": "10.3.10", + "drupal/core-recommended": "10.3.10", "drupal/devel": "^5.1", "drupal/devel_entity_updates": "^4.1", "drupal/fontawesome": "^2.26", diff --git a/composer.lock b/composer.lock index 7c643f9..f2912b4 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": "76b580a30a0e17f5388880a88ea85f84", + "content-hash": "1e1792a5f0ea7dc8659bfb7bdcb61ae8", "packages": [ { "name": "asm89/stack-cors", @@ -269,24 +269,24 @@ }, { "name": "composer/semver", - "version": "3.4.0", + "version": "3.4.3", "source": { "type": "git", "url": "https://github.com/composer/semver.git", - "reference": "35e8d0af4486141bc745f23a29cc2091eb624a32" + "reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/semver/zipball/35e8d0af4486141bc745f23a29cc2091eb624a32", - "reference": "35e8d0af4486141bc745f23a29cc2091eb624a32", + "url": "https://api.github.com/repos/composer/semver/zipball/4313d26ada5e0c4edfbd1dc481a92ff7bff91f12", + "reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12", "shasum": "" }, "require": { "php": "^5.3.2 || ^7.0 || ^8.0" }, "require-dev": { - "phpstan/phpstan": "^1.4", - "symfony/phpunit-bridge": "^4.2 || ^5" + "phpstan/phpstan": "^1.11", + "symfony/phpunit-bridge": "^3 || ^7" }, "type": "library", "extra": { @@ -330,7 +330,7 @@ "support": { "irc": "ircs://irc.libera.chat:6697/composer", "issues": "https://github.com/composer/semver/issues", - "source": "https://github.com/composer/semver/tree/3.4.0" + "source": "https://github.com/composer/semver/tree/3.4.3" }, "funding": [ { @@ -346,7 +346,7 @@ "type": "tidelift" } ], - "time": "2023-08-31T09:50:34+00:00" + "time": "2024-09-19T14:15:21+00:00" }, { "name": "consolidation/annotated-command", @@ -989,16 +989,16 @@ }, { "name": "doctrine/annotations", - "version": "1.14.3", + "version": "1.14.4", "source": { "type": "git", "url": "https://github.com/doctrine/annotations.git", - "reference": "fb0d71a7393298a7b232cbf4c8b1f73f3ec3d5af" + "reference": "253dca476f70808a5aeed3a47cc2cc88c5cab915" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/annotations/zipball/fb0d71a7393298a7b232cbf4c8b1f73f3ec3d5af", - "reference": "fb0d71a7393298a7b232cbf4c8b1f73f3ec3d5af", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/253dca476f70808a5aeed3a47cc2cc88c5cab915", + "reference": "253dca476f70808a5aeed3a47cc2cc88c5cab915", "shasum": "" }, "require": { @@ -1009,11 +1009,11 @@ }, "require-dev": { "doctrine/cache": "^1.11 || ^2.0", - "doctrine/coding-standard": "^9 || ^10", - "phpstan/phpstan": "~1.4.10 || ^1.8.0", + "doctrine/coding-standard": "^9 || ^12", + "phpstan/phpstan": "~1.4.10 || ^1.10.28", "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "symfony/cache": "^4.4 || ^5.4 || ^6", - "vimeo/psalm": "^4.10" + "symfony/cache": "^4.4 || ^5.4 || ^6.4 || ^7", + "vimeo/psalm": "^4.30 || ^5.14" }, "suggest": { "php": "PHP 8.0 or higher comes with attributes, a native replacement for annotations" @@ -1059,9 +1059,9 @@ ], "support": { "issues": "https://github.com/doctrine/annotations/issues", - "source": "https://github.com/doctrine/annotations/tree/1.14.3" + "source": "https://github.com/doctrine/annotations/tree/1.14.4" }, - "time": "2023-02-01T09:20:38+00:00" + "time": "2024-09-05T10:15:52+00:00" }, { "name": "doctrine/common", @@ -1668,16 +1668,16 @@ }, { "name": "drupal/core", - "version": "10.2.4", + "version": "10.3.10", "source": { "type": "git", "url": "https://github.com/drupal/core.git", - "reference": "d1c5b44adfc79bda03252471491b0fba89d87eff" + "reference": "3ebb71e9c4ef0c13f683353547551fca49f9a144" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/drupal/core/zipball/d1c5b44adfc79bda03252471491b0fba89d87eff", - "reference": "d1c5b44adfc79bda03252471491b0fba89d87eff", + "url": "https://api.github.com/repos/drupal/core/zipball/3ebb71e9c4ef0c13f683353547551fca49f9a144", + "reference": "3ebb71e9c4ef0c13f683353547551fca49f9a144", "shasum": "" }, "require": { @@ -1723,7 +1723,7 @@ "symfony/serializer": "^6.4", "symfony/validator": "^6.4", "symfony/yaml": "^6.4", - "twig/twig": "^3.5.0" + "twig/twig": "^3.14.2" }, "conflict": { "drush/drush": "<12.4.3" @@ -1761,29 +1761,29 @@ "extra": { "drupal-scaffold": { "file-mapping": { - "[project-root]/.editorconfig": "assets/scaffold/files/editorconfig", - "[project-root]/.gitattributes": "assets/scaffold/files/gitattributes", - "[web-root]/.csslintrc": "assets/scaffold/files/csslintrc", - "[web-root]/.eslintignore": "assets/scaffold/files/eslintignore", - "[web-root]/.eslintrc.json": "assets/scaffold/files/eslintrc.json", - "[web-root]/.ht.router.php": "assets/scaffold/files/ht.router.php", "[web-root]/.htaccess": "assets/scaffold/files/htaccess", - "[web-root]/example.gitignore": "assets/scaffold/files/example.gitignore", - "[web-root]/index.php": "assets/scaffold/files/index.php", - "[web-root]/INSTALL.txt": "assets/scaffold/files/drupal.INSTALL.txt", "[web-root]/README.md": "assets/scaffold/files/drupal.README.md", + "[web-root]/index.php": "assets/scaffold/files/index.php", + "[web-root]/.csslintrc": "assets/scaffold/files/csslintrc", "[web-root]/robots.txt": "assets/scaffold/files/robots.txt", "[web-root]/update.php": "assets/scaffold/files/update.php", "[web-root]/web.config": "assets/scaffold/files/web.config", + "[web-root]/INSTALL.txt": "assets/scaffold/files/drupal.INSTALL.txt", + "[web-root]/.eslintignore": "assets/scaffold/files/eslintignore", + "[web-root]/.eslintrc.json": "assets/scaffold/files/eslintrc.json", + "[web-root]/.ht.router.php": "assets/scaffold/files/ht.router.php", "[web-root]/sites/README.txt": "assets/scaffold/files/sites.README.txt", + "[project-root]/.editorconfig": "assets/scaffold/files/editorconfig", + "[web-root]/example.gitignore": "assets/scaffold/files/example.gitignore", + "[web-root]/themes/README.txt": "assets/scaffold/files/themes.README.txt", + "[project-root]/.gitattributes": "assets/scaffold/files/gitattributes", + "[web-root]/modules/README.txt": "assets/scaffold/files/modules.README.txt", + "[web-root]/profiles/README.txt": "assets/scaffold/files/profiles.README.txt", + "[web-root]/sites/example.sites.php": "assets/scaffold/files/example.sites.php", "[web-root]/sites/development.services.yml": "assets/scaffold/files/development.services.yml", "[web-root]/sites/example.settings.local.php": "assets/scaffold/files/example.settings.local.php", - "[web-root]/sites/example.sites.php": "assets/scaffold/files/example.sites.php", "[web-root]/sites/default/default.services.yml": "assets/scaffold/files/default.services.yml", - "[web-root]/sites/default/default.settings.php": "assets/scaffold/files/default.settings.php", - "[web-root]/modules/README.txt": "assets/scaffold/files/modules.README.txt", - "[web-root]/profiles/README.txt": "assets/scaffold/files/profiles.README.txt", - "[web-root]/themes/README.txt": "assets/scaffold/files/themes.README.txt" + "[web-root]/sites/default/default.settings.php": "assets/scaffold/files/default.settings.php" } } }, @@ -1816,7 +1816,8 @@ "lib/Drupal/Core/DrupalKernel.php", "lib/Drupal/Core/DrupalKernelInterface.php", "lib/Drupal/Core/Installer/InstallerRedirectTrait.php", - "lib/Drupal/Core/Site/Settings.php" + "lib/Drupal/Core/Site/Settings.php", + "lib/Drupal/Component/Datetime/Time.php" ] }, "notification-url": "https://packagist.org/downloads/", @@ -1825,22 +1826,22 @@ ], "description": "Drupal is an open source content management platform powering millions of websites and applications.", "support": { - "source": "https://github.com/drupal/core/tree/10.2.4" + "source": "https://github.com/drupal/core/tree/10.3.10" }, - "time": "2024-03-06T08:23:56+00:00" + "time": "2024-11-22T12:51:33+00:00" }, { "name": "drupal/core-composer-scaffold", - "version": "10.2.4", + "version": "10.3.10", "source": { "type": "git", "url": "https://github.com/drupal/core-composer-scaffold.git", - "reference": "63effa1bc644e80a269e8b4415e627491d26fd3f" + "reference": "f58ab5c0d02d275c5aa226c4505b457e41b161cc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/drupal/core-composer-scaffold/zipball/63effa1bc644e80a269e8b4415e627491d26fd3f", - "reference": "63effa1bc644e80a269e8b4415e627491d26fd3f", + "url": "https://api.github.com/repos/drupal/core-composer-scaffold/zipball/f58ab5c0d02d275c5aa226c4505b457e41b161cc", + "reference": "f58ab5c0d02d275c5aa226c4505b457e41b161cc", "shasum": "" }, "require": { @@ -1875,13 +1876,13 @@ "drupal" ], "support": { - "source": "https://github.com/drupal/core-composer-scaffold/tree/10.2.4" + "source": "https://github.com/drupal/core-composer-scaffold/tree/10.3.10" }, - "time": "2024-01-26T14:59:30+00:00" + "time": "2024-08-22T14:31:34+00:00" }, { "name": "drupal/core-project-message", - "version": "10.2.4", + "version": "10.3.10", "source": { "type": "git", "url": "https://github.com/drupal/core-project-message.git", @@ -1916,80 +1917,80 @@ "drupal" ], "support": { - "source": "https://github.com/drupal/core-project-message/tree/10.2.4" + "source": "https://github.com/drupal/core-project-message/tree/11.1.0-beta1" }, "time": "2023-07-24T07:55:25+00:00" }, { "name": "drupal/core-recommended", - "version": "10.2.4", + "version": "10.3.10", "source": { "type": "git", "url": "https://github.com/drupal/core-recommended.git", - "reference": "550c4cb19afda15ef892d88469ab93dc38bf0b46" + "reference": "1d739e569c9324bcac1ecc7be600d414386a399b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/drupal/core-recommended/zipball/550c4cb19afda15ef892d88469ab93dc38bf0b46", - "reference": "550c4cb19afda15ef892d88469ab93dc38bf0b46", + "url": "https://api.github.com/repos/drupal/core-recommended/zipball/1d739e569c9324bcac1ecc7be600d414386a399b", + "reference": "1d739e569c9324bcac1ecc7be600d414386a399b", "shasum": "" }, "require": { "asm89/stack-cors": "~v2.2.0", "composer/semver": "~3.4.0", "doctrine/annotations": "~1.14.3", - "doctrine/deprecations": "~1.1.2", - "doctrine/lexer": "~2.1.0", - "drupal/core": "10.2.4", + "doctrine/deprecations": "~1.1.3", + "doctrine/lexer": "~2.1.1", + "drupal/core": "10.3.10", "egulias/email-validator": "~4.0.2", "guzzlehttp/guzzle": "~7.8.1", "guzzlehttp/promises": "~2.0.2", "guzzlehttp/psr7": "~2.6.2", - "masterminds/html5": "~2.8.1", - "mck89/peast": "~v1.15.4", - "pear/archive_tar": "~1.4.14", + "masterminds/html5": "~2.9.0", + "mck89/peast": "~v1.16.2", + "pear/archive_tar": "~1.5.0", "pear/console_getopt": "~v1.4.3", - "pear/pear-core-minimal": "~v1.10.14", + "pear/pear-core-minimal": "~v1.10.15", "pear/pear_exception": "~v1.0.2", "psr/cache": "~3.0.0", "psr/container": "~2.0.2", "psr/event-dispatcher": "~1.0.0", "psr/http-client": "~1.0.3", - "psr/http-factory": "~1.0.2", + "psr/http-factory": "~1.1.0", "psr/log": "~3.0.0", "ralouphie/getallheaders": "~3.0.3", - "sebastian/diff": "~4.0.5", - "symfony/console": "~v6.4.1", - "symfony/dependency-injection": "~v6.4.1", - "symfony/deprecation-contracts": "~v3.4.0", - "symfony/error-handler": "~v6.4.0", - "symfony/event-dispatcher": "~v6.4.0", - "symfony/event-dispatcher-contracts": "~v3.4.0", - "symfony/filesystem": "~v6.4.0", - "symfony/finder": "~v6.4.0", - "symfony/http-foundation": "~v6.4.0", - "symfony/http-kernel": "~v6.4.1", - "symfony/mailer": "~v6.4.0", - "symfony/mime": "~v6.4.0", - "symfony/polyfill-ctype": "~v1.28.0", - "symfony/polyfill-iconv": "~v1.28.0", - "symfony/polyfill-intl-grapheme": "~v1.28.0", - "symfony/polyfill-intl-idn": "~v1.28.0", - "symfony/polyfill-intl-normalizer": "~v1.28.0", - "symfony/polyfill-mbstring": "~v1.28.0", - "symfony/polyfill-php83": "~v1.28.0", - "symfony/process": "~v6.4.0", - "symfony/psr-http-message-bridge": "~v6.4.0", - "symfony/routing": "~v6.4.1", - "symfony/serializer": "~v6.4.1", - "symfony/service-contracts": "~v3.4.0", - "symfony/string": "~v6.4.0", - "symfony/translation-contracts": "~v3.4.0", - "symfony/validator": "~v6.4.0", - "symfony/var-dumper": "~v6.4.0", - "symfony/var-exporter": "~v6.4.1", - "symfony/yaml": "~v6.4.0", - "twig/twig": "~v3.8.0" + "sebastian/diff": "~4.0.6", + "symfony/console": "~v6.4.8", + "symfony/dependency-injection": "~v6.4.7", + "symfony/deprecation-contracts": "~v3.5.0", + "symfony/error-handler": "~v6.4.7", + "symfony/event-dispatcher": "~v6.4.7", + "symfony/event-dispatcher-contracts": "~v3.5.0", + "symfony/filesystem": "~v6.4.8", + "symfony/finder": "~v6.4.8", + "symfony/http-foundation": "~v6.4.7", + "symfony/http-kernel": "~v6.4.7", + "symfony/mailer": "~v6.4.7", + "symfony/mime": "~v6.4.7", + "symfony/polyfill-ctype": "~v1.29.0", + "symfony/polyfill-iconv": "~v1.29.0", + "symfony/polyfill-intl-grapheme": "~v1.29.0", + "symfony/polyfill-intl-idn": "~v1.29.0", + "symfony/polyfill-intl-normalizer": "~v1.29.0", + "symfony/polyfill-mbstring": "~v1.29.0", + "symfony/polyfill-php83": "~v1.29.0", + "symfony/process": "~v6.4.8", + "symfony/psr-http-message-bridge": "~v6.4.7", + "symfony/routing": "~v6.4.7", + "symfony/serializer": "~v6.4.7", + "symfony/service-contracts": "~v3.5.0", + "symfony/string": "~v6.4.8", + "symfony/translation-contracts": "~v3.5.0", + "symfony/validator": "~v6.4.7", + "symfony/var-dumper": "~v6.4.7", + "symfony/var-exporter": "~v6.4.7", + "symfony/yaml": "~v6.4.7", + "twig/twig": "~v3.14.2" }, "conflict": { "webflo/drupal-core-strict": "*" @@ -2001,9 +2002,9 @@ ], "description": "Core and its dependencies with known-compatible minor versions. Require this project INSTEAD OF drupal/core.", "support": { - "source": "https://github.com/drupal/core-recommended/tree/10.2.4" + "source": "https://github.com/drupal/core-recommended/tree/10.3.10" }, - "time": "2024-03-06T08:23:56+00:00" + "time": "2024-11-22T12:51:33+00:00" }, { "name": "drupal/devel", @@ -2303,20 +2304,20 @@ }, { "name": "drupal/social_api", - "version": "4.0.1", + "version": "4.0.2", "source": { "type": "git", "url": "https://git.drupalcode.org/project/social_api.git", - "reference": "4.0.1" + "reference": "4.0.2" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/social_api-4.0.1.zip", - "reference": "4.0.1", - "shasum": "0bb10dc21f384b252602d82864c24a2949ffa6e2" + "url": "https://ftp.drupal.org/files/projects/social_api-4.0.2.zip", + "reference": "4.0.2", + "shasum": "8da084f0262080b2dfbbaa0ffb72cc386c6221dc" }, "require": { - "drupal/core": "^9.1 || ^10", + "drupal/core": "^9.5 || ^10 || ^11", "ext-openssl": "*", "league/oauth2-client": "^2.0" }, @@ -2327,8 +2328,8 @@ "type": "drupal-module", "extra": { "drupal": { - "version": "4.0.1", - "datestamp": "1687300624", + "version": "4.0.2", + "datestamp": "1725453406", "security-coverage": { "status": "covered", "message": "Covered by Drupal's security advisory policy" @@ -2380,21 +2381,22 @@ }, { "name": "drupal/social_auth", - "version": "4.1.0", + "version": "4.1.2", "source": { "type": "git", "url": "https://git.drupalcode.org/project/social_auth.git", - "reference": "4.1.0" + "reference": "4.1.2" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/social_auth-4.1.0.zip", - "reference": "4.1.0", - "shasum": "0007d8eccb228fcddb306eba9def15b980d88562" + "url": "https://ftp.drupal.org/files/projects/social_auth-4.1.2.zip", + "reference": "4.1.2", + "shasum": "84dca21b4bce83ef9a1e6887d507f15829f9b6bc" }, "require": { - "drupal/core": "^9.3 || ^10", - "drupal/social_api": "^4" + "drupal/core": "^9.5 || ^10 || ^11", + "drupal/social_api": "^4.0", + "php": ">=8.1" }, "require-dev": { "drupal/coder": "^8.3", @@ -2403,8 +2405,8 @@ "type": "drupal-module", "extra": { "drupal": { - "version": "4.1.0", - "datestamp": "1695259412", + "version": "4.1.2", + "datestamp": "1731637091", "security-coverage": { "status": "covered", "message": "Covered by Drupal's security advisory policy" @@ -2452,22 +2454,22 @@ }, { "name": "drupal/social_auth_github", - "version": "4.0.0", + "version": "4.0.1", "source": { "type": "git", "url": "https://git.drupalcode.org/project/social_auth_github.git", - "reference": "4.0.0" + "reference": "4.0.1" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/social_auth_github-4.0.0.zip", - "reference": "4.0.0", - "shasum": "a25feb646433647196b4adc8836d3d99bb2ecd17" + "url": "https://ftp.drupal.org/files/projects/social_auth_github-4.0.1.zip", + "reference": "4.0.1", + "shasum": "20a67283ba518fe016475c1c29d8a5bfb9a753d9" }, "require": { - "drupal/core": "^9 || ^10", - "drupal/social_auth": "^4.0", - "league/oauth2-github": "^2.0" + "drupal/core": "^9.5 || ^10 || ^11", + "drupal/social_auth": "^4.1", + "league/oauth2-github": "^2.0 || ^3.1" }, "require-dev": { "drupal/coder": "^8.3", @@ -2476,8 +2478,8 @@ "type": "drupal-module", "extra": { "drupal": { - "version": "4.0.0", - "datestamp": "1683134065", + "version": "4.0.1", + "datestamp": "1725491796", "security-coverage": { "status": "covered", "message": "Covered by Drupal's security advisory policy" @@ -2593,20 +2595,20 @@ }, { "name": "drupal/webform", - "version": "6.2.2", + "version": "6.2.8", "source": { "type": "git", "url": "https://git.drupalcode.org/project/webform.git", - "reference": "6.2.2" + "reference": "6.2.8" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/webform-6.2.2.zip", - "reference": "6.2.2", - "shasum": "cfd766802232dfdf39edd5a1acf7c738d14dc6eb" + "url": "https://ftp.drupal.org/files/projects/webform-6.2.8.zip", + "reference": "6.2.8", + "shasum": "5552f9a76b5a4e33beb3ea75664beb5d47c334cc" }, "require": { - "drupal/core": "^9.4 || ^10", + "drupal/core": "^10.2", "php": ">=8.1" }, "require-dev": { @@ -2623,6 +2625,7 @@ "drupal/group": "1.x-dev", "drupal/hal": "1 - 2", "drupal/jquery_ui": "1.x-dev", + "drupal/jquery_ui_button": "2.x-dev", "drupal/jquery_ui_checkboxradio": "2.x-dev", "drupal/jquery_ui_datepicker": "2.x-dev", "drupal/mailsystem": "4.x-dev", @@ -2646,14 +2649,14 @@ "drupal/webform_ui": "*" }, "suggest": { - "drupal/jquery_ui_checkboxradio": "Provides jQuery UI Checkboxradio library. Required by the Webform jQueryUI Buttons module. The Webform jQueryUI Buttons module is deprecated because jQueryUI is no longer maintained.", + "drupal/jquery_ui_buttons": "Provides jQuery UI Checkboxradio library. Required by the Webform jQueryUI Buttons module. The Webform jQueryUI Buttons module is deprecated because jQueryUI is no longer maintained.", "drupal/jquery_ui_datepicker": "Provides jQuery UI Datepicker library. Required to support datepickers. The Webform jQueryUI Datepicker module is deprecated because jQueryUI is no longer maintained." }, "type": "drupal-module", "extra": { "drupal": { - "version": "6.2.2", - "datestamp": "1701948363", + "version": "6.2.8", + "datestamp": "1732627900", "security-coverage": { "status": "covered", "message": "Covered by Drupal's security advisory policy" @@ -3075,22 +3078,22 @@ }, { "name": "guzzlehttp/guzzle", - "version": "7.8.1", + "version": "7.8.2", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "41042bc7ab002487b876a0683fc8dce04ddce104" + "reference": "f4152d9eb85c445fe1f992001d1748e8bec070d2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/41042bc7ab002487b876a0683fc8dce04ddce104", - "reference": "41042bc7ab002487b876a0683fc8dce04ddce104", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/f4152d9eb85c445fe1f992001d1748e8bec070d2", + "reference": "f4152d9eb85c445fe1f992001d1748e8bec070d2", "shasum": "" }, "require": { "ext-json": "*", - "guzzlehttp/promises": "^1.5.3 || ^2.0.1", - "guzzlehttp/psr7": "^1.9.1 || ^2.5.1", + "guzzlehttp/promises": "^1.5.3 || ^2.0.3", + "guzzlehttp/psr7": "^1.9.1 || ^2.6.3", "php": "^7.2.5 || ^8.0", "psr/http-client": "^1.0", "symfony/deprecation-contracts": "^2.2 || ^3.0" @@ -3101,9 +3104,9 @@ "require-dev": { "bamarni/composer-bin-plugin": "^1.8.2", "ext-curl": "*", - "php-http/client-integration-tests": "dev-master#2c025848417c1135031fdf9c728ee53d0a7ceaee as 3.0.999", + "guzzle/client-integration-tests": "3.0.2", "php-http/message-factory": "^1.1", - "phpunit/phpunit": "^8.5.36 || ^9.6.15", + "phpunit/phpunit": "^8.5.39 || ^9.6.20", "psr/log": "^1.1 || ^2.0 || ^3.0" }, "suggest": { @@ -3181,7 +3184,7 @@ ], "support": { "issues": "https://github.com/guzzle/guzzle/issues", - "source": "https://github.com/guzzle/guzzle/tree/7.8.1" + "source": "https://github.com/guzzle/guzzle/tree/7.8.2" }, "funding": [ { @@ -3197,20 +3200,20 @@ "type": "tidelift" } ], - "time": "2023-12-03T20:35:24+00:00" + "time": "2024-07-18T11:12:18+00:00" }, { "name": "guzzlehttp/promises", - "version": "2.0.2", + "version": "2.0.4", "source": { "type": "git", "url": "https://github.com/guzzle/promises.git", - "reference": "bbff78d96034045e58e13dedd6ad91b5d1253223" + "reference": "f9c436286ab2892c7db7be8c8da4ef61ccf7b455" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/bbff78d96034045e58e13dedd6ad91b5d1253223", - "reference": "bbff78d96034045e58e13dedd6ad91b5d1253223", + "url": "https://api.github.com/repos/guzzle/promises/zipball/f9c436286ab2892c7db7be8c8da4ef61ccf7b455", + "reference": "f9c436286ab2892c7db7be8c8da4ef61ccf7b455", "shasum": "" }, "require": { @@ -3218,7 +3221,7 @@ }, "require-dev": { "bamarni/composer-bin-plugin": "^1.8.2", - "phpunit/phpunit": "^8.5.36 || ^9.6.15" + "phpunit/phpunit": "^8.5.39 || ^9.6.20" }, "type": "library", "extra": { @@ -3264,7 +3267,7 @@ ], "support": { "issues": "https://github.com/guzzle/promises/issues", - "source": "https://github.com/guzzle/promises/tree/2.0.2" + "source": "https://github.com/guzzle/promises/tree/2.0.4" }, "funding": [ { @@ -3280,20 +3283,20 @@ "type": "tidelift" } ], - "time": "2023-12-03T20:19:20+00:00" + "time": "2024-10-17T10:06:22+00:00" }, { "name": "guzzlehttp/psr7", - "version": "2.6.2", + "version": "2.6.3", "source": { "type": "git", "url": "https://github.com/guzzle/psr7.git", - "reference": "45b30f99ac27b5ca93cb4831afe16285f57b8221" + "reference": "6de29867b18790c0d2c846af4c13a24cc3ad56f3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/45b30f99ac27b5ca93cb4831afe16285f57b8221", - "reference": "45b30f99ac27b5ca93cb4831afe16285f57b8221", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/6de29867b18790c0d2c846af4c13a24cc3ad56f3", + "reference": "6de29867b18790c0d2c846af4c13a24cc3ad56f3", "shasum": "" }, "require": { @@ -3308,8 +3311,8 @@ }, "require-dev": { "bamarni/composer-bin-plugin": "^1.8.2", - "http-interop/http-factory-tests": "^0.9", - "phpunit/phpunit": "^8.5.36 || ^9.6.15" + "http-interop/http-factory-tests": "0.9.0", + "phpunit/phpunit": "^8.5.39 || ^9.6.20" }, "suggest": { "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" @@ -3380,7 +3383,7 @@ ], "support": { "issues": "https://github.com/guzzle/psr7/issues", - "source": "https://github.com/guzzle/psr7/tree/2.6.2" + "source": "https://github.com/guzzle/psr7/tree/2.6.3" }, "funding": [ { @@ -3396,7 +3399,7 @@ "type": "tidelift" } ], - "time": "2023-12-03T20:05:35+00:00" + "time": "2024-07-18T09:59:12+00:00" }, { "name": "kint-php/kint", @@ -3617,25 +3620,27 @@ }, { "name": "league/oauth2-github", - "version": "2.0.0", + "version": "3.1.1", "source": { "type": "git", "url": "https://github.com/thephpleague/oauth2-github.git", - "reference": "e63d64f3ec167c09232d189c6b0c397458a99357" + "reference": "84211f62b757f7266fe605a0aa874a32f52c24fd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/oauth2-github/zipball/e63d64f3ec167c09232d189c6b0c397458a99357", - "reference": "e63d64f3ec167c09232d189c6b0c397458a99357", + "url": "https://api.github.com/repos/thephpleague/oauth2-github/zipball/84211f62b757f7266fe605a0aa874a32f52c24fd", + "reference": "84211f62b757f7266fe605a0aa874a32f52c24fd", "shasum": "" }, "require": { - "league/oauth2-client": "^2.0" + "ext-json": "*", + "league/oauth2-client": "^2.0", + "php": "^7.3 || ^8.0" }, "require-dev": { - "mockery/mockery": "~0.9", - "phpunit/phpunit": "~4.0", - "squizlabs/php_codesniffer": "~2.0" + "mockery/mockery": "^1.4", + "phpunit/phpunit": "^9.5", + "squizlabs/php_codesniffer": "^3.6" }, "type": "library", "extra": { @@ -3657,6 +3662,11 @@ "name": "Steven Maguire", "email": "stevenmaguire@gmail.com", "homepage": "https://github.com/stevenmaguire" + }, + { + "name": "Woody Gilk", + "email": "woody.gilk@gmail.com", + "homepage": "https://github.com/shadowhand" } ], "description": "Github OAuth 2.0 Client Provider for The PHP League OAuth2-Client", @@ -3670,22 +3680,22 @@ ], "support": { "issues": "https://github.com/thephpleague/oauth2-github/issues", - "source": "https://github.com/thephpleague/oauth2-github/tree/master" + "source": "https://github.com/thephpleague/oauth2-github/tree/3.1.1" }, - "time": "2017-01-26T01:14:51+00:00" + "time": "2024-09-03T10:42:10+00:00" }, { "name": "masterminds/html5", - "version": "2.8.1", + "version": "2.9.0", "source": { "type": "git", "url": "https://github.com/Masterminds/html5-php.git", - "reference": "f47dcf3c70c584de14f21143c55d9939631bc6cf" + "reference": "f5ac2c0b0a2eefca70b2ce32a5809992227e75a6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Masterminds/html5-php/zipball/f47dcf3c70c584de14f21143c55d9939631bc6cf", - "reference": "f47dcf3c70c584de14f21143c55d9939631bc6cf", + "url": "https://api.github.com/repos/Masterminds/html5-php/zipball/f5ac2c0b0a2eefca70b2ce32a5809992227e75a6", + "reference": "f5ac2c0b0a2eefca70b2ce32a5809992227e75a6", "shasum": "" }, "require": { @@ -3693,7 +3703,7 @@ "php": ">=5.3.0" }, "require-dev": { - "phpunit/phpunit": "^4.8.35 || ^5.7.21 || ^6 || ^7 || ^8" + "phpunit/phpunit": "^4.8.35 || ^5.7.21 || ^6 || ^7 || ^8 || ^9" }, "type": "library", "extra": { @@ -3737,22 +3747,22 @@ ], "support": { "issues": "https://github.com/Masterminds/html5-php/issues", - "source": "https://github.com/Masterminds/html5-php/tree/2.8.1" + "source": "https://github.com/Masterminds/html5-php/tree/2.9.0" }, - "time": "2023-05-10T11:58:31+00:00" + "time": "2024-03-31T07:05:07+00:00" }, { "name": "mck89/peast", - "version": "v1.15.4", + "version": "v1.16.3", "source": { "type": "git", "url": "https://github.com/mck89/peast.git", - "reference": "1df4dc28a6b5bb7ab117ab073c1712256e954e18" + "reference": "645ec21b650bc2aced18285c85f220d22afc1430" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/mck89/peast/zipball/1df4dc28a6b5bb7ab117ab073c1712256e954e18", - "reference": "1df4dc28a6b5bb7ab117ab073c1712256e954e18", + "url": "https://api.github.com/repos/mck89/peast/zipball/645ec21b650bc2aced18285c85f220d22afc1430", + "reference": "645ec21b650bc2aced18285c85f220d22afc1430", "shasum": "" }, "require": { @@ -3765,7 +3775,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.15.4-dev" + "dev-master": "1.16.3-dev" } }, "autoload": { @@ -3786,9 +3796,9 @@ "description": "Peast is PHP library that generates AST for JavaScript code", "support": { "issues": "https://github.com/mck89/peast/issues", - "source": "https://github.com/mck89/peast/tree/v1.15.4" + "source": "https://github.com/mck89/peast/tree/v1.16.3" }, - "time": "2023-08-12T08:29:29+00:00" + "time": "2024-07-23T14:00:32+00:00" }, { "name": "nikic/php-parser", @@ -4090,16 +4100,16 @@ }, { "name": "pear/archive_tar", - "version": "1.4.14", + "version": "1.5.0", "source": { "type": "git", "url": "https://github.com/pear/Archive_Tar.git", - "reference": "4d761c5334c790e45ef3245f0864b8955c562caa" + "reference": "b439c859564f5cbb0f64ad6002d0afe84a889602" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pear/Archive_Tar/zipball/4d761c5334c790e45ef3245f0864b8955c562caa", - "reference": "4d761c5334c790e45ef3245f0864b8955c562caa", + "url": "https://api.github.com/repos/pear/Archive_Tar/zipball/b439c859564f5cbb0f64ad6002d0afe84a889602", + "reference": "b439c859564f5cbb0f64ad6002d0afe84a889602", "shasum": "" }, "require": { @@ -4130,7 +4140,7 @@ "./" ], "license": [ - "BSD-3-Clause" + "BSD-2-Clause" ], "authors": [ { @@ -4156,17 +4166,7 @@ "issues": "http://pear.php.net/bugs/search.php?cmd=display&package_name[]=Archive_Tar", "source": "https://github.com/pear/Archive_Tar" }, - "funding": [ - { - "url": "https://github.com/mrook", - "type": "github" - }, - { - "url": "https://www.patreon.com/michielrook", - "type": "patreon" - } - ], - "time": "2021-07-20T13:53:39+00:00" + "time": "2024-03-16T16:21:40+00:00" }, { "name": "pear/console_getopt", @@ -4221,16 +4221,16 @@ }, { "name": "pear/pear-core-minimal", - "version": "v1.10.14", + "version": "v1.10.16", "source": { "type": "git", "url": "https://github.com/pear/pear-core-minimal.git", - "reference": "a86fc145edb5caedbf96527214ce3cadc9de4a32" + "reference": "c0f51b45f50683bf5bbf558036854ebc9b54d033" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pear/pear-core-minimal/zipball/a86fc145edb5caedbf96527214ce3cadc9de4a32", - "reference": "a86fc145edb5caedbf96527214ce3cadc9de4a32", + "url": "https://api.github.com/repos/pear/pear-core-minimal/zipball/c0f51b45f50683bf5bbf558036854ebc9b54d033", + "reference": "c0f51b45f50683bf5bbf558036854ebc9b54d033", "shasum": "" }, "require": { @@ -4243,9 +4243,9 @@ }, "type": "library", "autoload": { - "psr-0": { - "": "src/" - } + "classmap": [ + "src/" + ] }, "notification-url": "https://packagist.org/downloads/", "include-path": [ @@ -4266,7 +4266,7 @@ "issues": "http://pear.php.net/bugs/search.php?cmd=display&package_name[]=PEAR", "source": "https://github.com/pear/pear-core-minimal" }, - "time": "2023-11-26T16:15:38+00:00" + "time": "2024-11-24T22:27:58+00:00" }, { "name": "pear/pear_exception", @@ -4689,20 +4689,20 @@ }, { "name": "psr/http-factory", - "version": "1.0.2", + "version": "1.1.0", "source": { "type": "git", "url": "https://github.com/php-fig/http-factory.git", - "reference": "e616d01114759c4c489f93b099585439f795fe35" + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-factory/zipball/e616d01114759c4c489f93b099585439f795fe35", - "reference": "e616d01114759c4c489f93b099585439f795fe35", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/2b4765fddfe3b508ac62f829e852b1501d3f6e8a", + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a", "shasum": "" }, "require": { - "php": ">=7.0.0", + "php": ">=7.1", "psr/http-message": "^1.0 || ^2.0" }, "type": "library", @@ -4726,7 +4726,7 @@ "homepage": "https://www.php-fig.org/" } ], - "description": "Common interfaces for PSR-7 HTTP message factories", + "description": "PSR-17: Common interfaces for PSR-7 HTTP message factories", "keywords": [ "factory", "http", @@ -4738,9 +4738,9 @@ "response" ], "support": { - "source": "https://github.com/php-fig/http-factory/tree/1.0.2" + "source": "https://github.com/php-fig/http-factory" }, - "time": "2023-04-10T20:10:41+00:00" + "time": "2024-04-15T12:06:14+00:00" }, { "name": "psr/http-message", @@ -4797,16 +4797,16 @@ }, { "name": "psr/log", - "version": "3.0.0", + "version": "3.0.2", "source": { "type": "git", "url": "https://github.com/php-fig/log.git", - "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001" + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001", - "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001", + "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", "shasum": "" }, "require": { @@ -4841,9 +4841,9 @@ "psr-3" ], "support": { - "source": "https://github.com/php-fig/log/tree/3.0.0" + "source": "https://github.com/php-fig/log/tree/3.0.2" }, - "time": "2021-07-14T16:46:02+00:00" + "time": "2024-09-11T13:17:53+00:00" }, { "name": "psy/psysh", @@ -5036,16 +5036,16 @@ }, { "name": "symfony/console", - "version": "v6.4.4", + "version": "v6.4.15", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "0d9e4eb5ad413075624378f474c4167ea202de78" + "reference": "f1fc6f47283e27336e7cebb9e8946c8de7bff9bd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/0d9e4eb5ad413075624378f474c4167ea202de78", - "reference": "0d9e4eb5ad413075624378f474c4167ea202de78", + "url": "https://api.github.com/repos/symfony/console/zipball/f1fc6f47283e27336e7cebb9e8946c8de7bff9bd", + "reference": "f1fc6f47283e27336e7cebb9e8946c8de7bff9bd", "shasum": "" }, "require": { @@ -5110,7 +5110,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v6.4.4" + "source": "https://github.com/symfony/console/tree/v6.4.15" }, "funding": [ { @@ -5126,20 +5126,20 @@ "type": "tidelift" } ], - "time": "2024-02-22T20:27:10+00:00" + "time": "2024-11-06T14:19:14+00:00" }, { "name": "symfony/dependency-injection", - "version": "v6.4.4", + "version": "v6.4.16", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "6236e5e843cb763e9d0f74245678b994afea5363" + "reference": "7a379d8871f6a36f01559c14e11141cc02eb8dc8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/6236e5e843cb763e9d0f74245678b994afea5363", - "reference": "6236e5e843cb763e9d0f74245678b994afea5363", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/7a379d8871f6a36f01559c14e11141cc02eb8dc8", + "reference": "7a379d8871f6a36f01559c14e11141cc02eb8dc8", "shasum": "" }, "require": { @@ -5191,7 +5191,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.4" + "source": "https://github.com/symfony/dependency-injection/tree/v6.4.16" }, "funding": [ { @@ -5207,20 +5207,20 @@ "type": "tidelift" } ], - "time": "2024-02-22T20:27:10+00:00" + "time": "2024-11-25T14:52:46+00:00" }, { "name": "symfony/deprecation-contracts", - "version": "v3.4.0", + "version": "v3.5.1", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf" + "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/7c3aff79d10325257a001fcf92d991f24fc967cf", - "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", + "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", "shasum": "" }, "require": { @@ -5229,7 +5229,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "3.4-dev" + "dev-main": "3.5-dev" }, "thanks": { "name": "symfony/contracts", @@ -5258,7 +5258,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.4.0" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.1" }, "funding": [ { @@ -5274,7 +5274,7 @@ "type": "tidelift" } ], - "time": "2023-05-23T14:45:45+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { "name": "symfony/dotenv", @@ -5352,16 +5352,16 @@ }, { "name": "symfony/error-handler", - "version": "v6.4.4", + "version": "v6.4.14", "source": { "type": "git", "url": "https://github.com/symfony/error-handler.git", - "reference": "c725219bdf2afc59423c32793d5019d2a904e13a" + "reference": "9e024324511eeb00983ee76b9aedc3e6ecd993d9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/c725219bdf2afc59423c32793d5019d2a904e13a", - "reference": "c725219bdf2afc59423c32793d5019d2a904e13a", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/9e024324511eeb00983ee76b9aedc3e6ecd993d9", + "reference": "9e024324511eeb00983ee76b9aedc3e6ecd993d9", "shasum": "" }, "require": { @@ -5407,7 +5407,7 @@ "description": "Provides tools to manage errors and ease debugging PHP code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/error-handler/tree/v6.4.4" + "source": "https://github.com/symfony/error-handler/tree/v6.4.14" }, "funding": [ { @@ -5423,20 +5423,20 @@ "type": "tidelift" } ], - "time": "2024-02-22T20:27:10+00:00" + "time": "2024-11-05T15:34:40+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v6.4.3", + "version": "v6.4.13", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "ae9d3a6f3003a6caf56acd7466d8d52378d44fef" + "reference": "0ffc48080ab3e9132ea74ef4e09d8dcf26bf897e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/ae9d3a6f3003a6caf56acd7466d8d52378d44fef", - "reference": "ae9d3a6f3003a6caf56acd7466d8d52378d44fef", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/0ffc48080ab3e9132ea74ef4e09d8dcf26bf897e", + "reference": "0ffc48080ab3e9132ea74ef4e09d8dcf26bf897e", "shasum": "" }, "require": { @@ -5487,7 +5487,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v6.4.3" + "source": "https://github.com/symfony/event-dispatcher/tree/v6.4.13" }, "funding": [ { @@ -5503,20 +5503,20 @@ "type": "tidelift" } ], - "time": "2024-01-23T14:51:35+00:00" + "time": "2024-09-25T14:18:03+00:00" }, { "name": "symfony/event-dispatcher-contracts", - "version": "v3.4.0", + "version": "v3.5.1", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher-contracts.git", - "reference": "a76aed96a42d2b521153fb382d418e30d18b59df" + "reference": "7642f5e970b672283b7823222ae8ef8bbc160b9f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/a76aed96a42d2b521153fb382d418e30d18b59df", - "reference": "a76aed96a42d2b521153fb382d418e30d18b59df", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/7642f5e970b672283b7823222ae8ef8bbc160b9f", + "reference": "7642f5e970b672283b7823222ae8ef8bbc160b9f", "shasum": "" }, "require": { @@ -5526,7 +5526,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "3.4-dev" + "dev-main": "3.5-dev" }, "thanks": { "name": "symfony/contracts", @@ -5563,7 +5563,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.4.0" + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.5.1" }, "funding": [ { @@ -5579,20 +5579,20 @@ "type": "tidelift" } ], - "time": "2023-05-23T14:45:45+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { "name": "symfony/filesystem", - "version": "v6.4.3", + "version": "v6.4.13", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "7f3b1755eb49297a0827a7575d5d2b2fd11cc9fb" + "reference": "4856c9cf585d5a0313d8d35afd681a526f038dd3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/7f3b1755eb49297a0827a7575d5d2b2fd11cc9fb", - "reference": "7f3b1755eb49297a0827a7575d5d2b2fd11cc9fb", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/4856c9cf585d5a0313d8d35afd681a526f038dd3", + "reference": "4856c9cf585d5a0313d8d35afd681a526f038dd3", "shasum": "" }, "require": { @@ -5600,6 +5600,9 @@ "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.8" }, + "require-dev": { + "symfony/process": "^5.4|^6.4|^7.0" + }, "type": "library", "autoload": { "psr-4": { @@ -5626,7 +5629,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v6.4.3" + "source": "https://github.com/symfony/filesystem/tree/v6.4.13" }, "funding": [ { @@ -5642,20 +5645,20 @@ "type": "tidelift" } ], - "time": "2024-01-23T14:51:35+00:00" + "time": "2024-10-25T15:07:50+00:00" }, { "name": "symfony/finder", - "version": "v6.4.0", + "version": "v6.4.13", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "11d736e97f116ac375a81f96e662911a34cd50ce" + "reference": "daea9eca0b08d0ed1dc9ab702a46128fd1be4958" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/11d736e97f116ac375a81f96e662911a34cd50ce", - "reference": "11d736e97f116ac375a81f96e662911a34cd50ce", + "url": "https://api.github.com/repos/symfony/finder/zipball/daea9eca0b08d0ed1dc9ab702a46128fd1be4958", + "reference": "daea9eca0b08d0ed1dc9ab702a46128fd1be4958", "shasum": "" }, "require": { @@ -5690,7 +5693,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v6.4.0" + "source": "https://github.com/symfony/finder/tree/v6.4.13" }, "funding": [ { @@ -5706,20 +5709,20 @@ "type": "tidelift" } ], - "time": "2023-10-31T17:30:12+00:00" + "time": "2024-10-01T08:30:56+00:00" }, { "name": "symfony/http-foundation", - "version": "v6.4.4", + "version": "v6.4.16", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "ebc713bc6e6f4b53f46539fc158be85dfcd77304" + "reference": "431771b7a6f662f1575b3cfc8fd7617aa9864d57" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/ebc713bc6e6f4b53f46539fc158be85dfcd77304", - "reference": "ebc713bc6e6f4b53f46539fc158be85dfcd77304", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/431771b7a6f662f1575b3cfc8fd7617aa9864d57", + "reference": "431771b7a6f662f1575b3cfc8fd7617aa9864d57", "shasum": "" }, "require": { @@ -5729,12 +5732,12 @@ "symfony/polyfill-php83": "^1.27" }, "conflict": { - "symfony/cache": "<6.3" + "symfony/cache": "<6.4.12|>=7.0,<7.1.5" }, "require-dev": { "doctrine/dbal": "^2.13.1|^3|^4", "predis/predis": "^1.1|^2.0", - "symfony/cache": "^6.3|^7.0", + "symfony/cache": "^6.4.12|^7.1.5", "symfony/dependency-injection": "^5.4|^6.0|^7.0", "symfony/expression-language": "^5.4|^6.0|^7.0", "symfony/http-kernel": "^5.4.12|^6.0.12|^6.1.4|^7.0", @@ -5767,7 +5770,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.4" + "source": "https://github.com/symfony/http-foundation/tree/v6.4.16" }, "funding": [ { @@ -5783,20 +5786,20 @@ "type": "tidelift" } ], - "time": "2024-02-08T15:01:18+00:00" + "time": "2024-11-13T18:58:10+00:00" }, { "name": "symfony/http-kernel", - "version": "v6.4.5", + "version": "v6.4.16", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "f6947cb939d8efee137797382cb4db1af653ef75" + "reference": "8838b5b21d807923b893ccbfc2cbeda0f1bc00f0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/f6947cb939d8efee137797382cb4db1af653ef75", - "reference": "f6947cb939d8efee137797382cb4db1af653ef75", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/8838b5b21d807923b893ccbfc2cbeda0f1bc00f0", + "reference": "8838b5b21d807923b893ccbfc2cbeda0f1bc00f0", "shasum": "" }, "require": { @@ -5851,6 +5854,7 @@ "symfony/translation-contracts": "^2.5|^3", "symfony/uid": "^5.4|^6.0|^7.0", "symfony/validator": "^6.4|^7.0", + "symfony/var-dumper": "^5.4|^6.4|^7.0", "symfony/var-exporter": "^6.2|^7.0", "twig/twig": "^2.13|^3.0.4" }, @@ -5880,7 +5884,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.5" + "source": "https://github.com/symfony/http-kernel/tree/v6.4.16" }, "funding": [ { @@ -5896,20 +5900,20 @@ "type": "tidelift" } ], - "time": "2024-03-04T21:00:47+00:00" + "time": "2024-11-27T12:49:36+00:00" }, { "name": "symfony/mailer", - "version": "v6.4.4", + "version": "v6.4.13", "source": { "type": "git", "url": "https://github.com/symfony/mailer.git", - "reference": "791c5d31a8204cf3db0c66faab70282307f4376b" + "reference": "c2f7e0d8d7ac8fe25faccf5d8cac462805db2663" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mailer/zipball/791c5d31a8204cf3db0c66faab70282307f4376b", - "reference": "791c5d31a8204cf3db0c66faab70282307f4376b", + "url": "https://api.github.com/repos/symfony/mailer/zipball/c2f7e0d8d7ac8fe25faccf5d8cac462805db2663", + "reference": "c2f7e0d8d7ac8fe25faccf5d8cac462805db2663", "shasum": "" }, "require": { @@ -5960,7 +5964,7 @@ "description": "Helps sending emails", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/mailer/tree/v6.4.4" + "source": "https://github.com/symfony/mailer/tree/v6.4.13" }, "funding": [ { @@ -5976,20 +5980,20 @@ "type": "tidelift" } ], - "time": "2024-02-03T21:33:47+00:00" + "time": "2024-09-25T14:18:03+00:00" }, { "name": "symfony/mime", - "version": "v6.4.3", + "version": "v6.4.13", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "5017e0a9398c77090b7694be46f20eb796262a34" + "reference": "1de1cf14d99b12c7ebbb850491ec6ae3ed468855" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/5017e0a9398c77090b7694be46f20eb796262a34", - "reference": "5017e0a9398c77090b7694be46f20eb796262a34", + "url": "https://api.github.com/repos/symfony/mime/zipball/1de1cf14d99b12c7ebbb850491ec6ae3ed468855", + "reference": "1de1cf14d99b12c7ebbb850491ec6ae3ed468855", "shasum": "" }, "require": { @@ -6003,16 +6007,17 @@ "phpdocumentor/reflection-docblock": "<3.2.2", "phpdocumentor/type-resolver": "<1.4.0", "symfony/mailer": "<5.4", - "symfony/serializer": "<6.3.2" + "symfony/serializer": "<6.4.3|>7.0,<7.0.3" }, "require-dev": { "egulias/email-validator": "^2.1.10|^3.1|^4", "league/html-to-markdown": "^5.0", "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/process": "^5.4|^6.4|^7.0", "symfony/property-access": "^5.4|^6.0|^7.0", "symfony/property-info": "^5.4|^6.0|^7.0", - "symfony/serializer": "^6.3.2|^7.0" + "symfony/serializer": "^6.4.3|^7.0.3" }, "type": "library", "autoload": { @@ -6044,7 +6049,7 @@ "mime-type" ], "support": { - "source": "https://github.com/symfony/mime/tree/v6.4.3" + "source": "https://github.com/symfony/mime/tree/v6.4.13" }, "funding": [ { @@ -6060,20 +6065,20 @@ "type": "tidelift" } ], - "time": "2024-01-30T08:32:12+00:00" + "time": "2024-10-25T15:07:50+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.28.0", + "version": "v1.29.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb" + "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb", - "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ef4d7e442ca910c4764bce785146269b30cb5fc4", + "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4", "shasum": "" }, "require": { @@ -6087,9 +6092,6 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" @@ -6126,7 +6128,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.28.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.29.0" }, "funding": [ { @@ -6142,20 +6144,20 @@ "type": "tidelift" } ], - "time": "2023-01-26T09:26:14+00:00" + "time": "2024-01-29T20:11:03+00:00" }, { "name": "symfony/polyfill-iconv", - "version": "v1.28.0", + "version": "v1.29.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-iconv.git", - "reference": "6de50471469b8c9afc38164452ab2b6170ee71c1" + "reference": "cd4226d140ecd3d0f13d32ed0a4a095ffe871d2f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/6de50471469b8c9afc38164452ab2b6170ee71c1", - "reference": "6de50471469b8c9afc38164452ab2b6170ee71c1", + "url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/cd4226d140ecd3d0f13d32ed0a4a095ffe871d2f", + "reference": "cd4226d140ecd3d0f13d32ed0a4a095ffe871d2f", "shasum": "" }, "require": { @@ -6169,9 +6171,6 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" @@ -6209,7 +6208,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-iconv/tree/v1.28.0" + "source": "https://github.com/symfony/polyfill-iconv/tree/v1.29.0" }, "funding": [ { @@ -6225,20 +6224,20 @@ "type": "tidelift" } ], - "time": "2023-01-26T09:26:14+00:00" + "time": "2024-01-29T20:11:03+00:00" }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.28.0", + "version": "v1.29.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "875e90aeea2777b6f135677f618529449334a612" + "reference": "32a9da87d7b3245e09ac426c83d334ae9f06f80f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/875e90aeea2777b6f135677f618529449334a612", - "reference": "875e90aeea2777b6f135677f618529449334a612", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/32a9da87d7b3245e09ac426c83d334ae9f06f80f", + "reference": "32a9da87d7b3245e09ac426c83d334ae9f06f80f", "shasum": "" }, "require": { @@ -6249,9 +6248,6 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" @@ -6290,7 +6286,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.28.0" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.29.0" }, "funding": [ { @@ -6306,20 +6302,20 @@ "type": "tidelift" } ], - "time": "2023-01-26T09:26:14+00:00" + "time": "2024-01-29T20:11:03+00:00" }, { "name": "symfony/polyfill-intl-idn", - "version": "v1.28.0", + "version": "v1.29.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-idn.git", - "reference": "ecaafce9f77234a6a449d29e49267ba10499116d" + "reference": "a287ed7475f85bf6f61890146edbc932c0fff919" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/ecaafce9f77234a6a449d29e49267ba10499116d", - "reference": "ecaafce9f77234a6a449d29e49267ba10499116d", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/a287ed7475f85bf6f61890146edbc932c0fff919", + "reference": "a287ed7475f85bf6f61890146edbc932c0fff919", "shasum": "" }, "require": { @@ -6332,9 +6328,6 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" @@ -6377,7 +6370,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.28.0" + "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.29.0" }, "funding": [ { @@ -6393,20 +6386,20 @@ "type": "tidelift" } ], - "time": "2023-01-26T09:30:37+00:00" + "time": "2024-01-29T20:11:03+00:00" }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.28.0", + "version": "v1.29.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92" + "reference": "bc45c394692b948b4d383a08d7753968bed9a83d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92", - "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/bc45c394692b948b4d383a08d7753968bed9a83d", + "reference": "bc45c394692b948b4d383a08d7753968bed9a83d", "shasum": "" }, "require": { @@ -6417,9 +6410,6 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" @@ -6461,7 +6451,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.28.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.29.0" }, "funding": [ { @@ -6477,20 +6467,20 @@ "type": "tidelift" } ], - "time": "2023-01-26T09:26:14+00:00" + "time": "2024-01-29T20:11:03+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.28.0", + "version": "v1.29.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "42292d99c55abe617799667f454222c54c60e229" + "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/42292d99c55abe617799667f454222c54c60e229", - "reference": "42292d99c55abe617799667f454222c54c60e229", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9773676c8a1bb1f8d4340a62efe641cf76eda7ec", + "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec", "shasum": "" }, "require": { @@ -6504,9 +6494,6 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" @@ -6544,7 +6531,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.28.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.29.0" }, "funding": [ { @@ -6560,40 +6547,32 @@ "type": "tidelift" } ], - "time": "2023-07-28T09:04:16+00:00" + "time": "2024-01-29T20:11:03+00:00" }, { "name": "symfony/polyfill-php72", - "version": "v1.29.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "861391a8da9a04cbad2d232ddd9e4893220d6e25" + "reference": "fa2ae56c44f03bed91a39bfc9822e31e7c5c38ce" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/861391a8da9a04cbad2d232ddd9e4893220d6e25", - "reference": "861391a8da9a04cbad2d232ddd9e4893220d6e25", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/fa2ae56c44f03bed91a39bfc9822e31e7c5c38ce", + "reference": "fa2ae56c44f03bed91a39bfc9822e31e7c5c38ce", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, - "type": "library", + "type": "metapackage", "extra": { "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" } }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Php72\\": "" - } - }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" @@ -6617,7 +6596,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php72/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-php72/tree/v1.31.0" }, "funding": [ { @@ -6633,24 +6612,24 @@ "type": "tidelift" } ], - "time": "2024-01-29T20:11:03+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-php80", - "version": "v1.29.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b" + "reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/87b68208d5c1188808dd7839ee1e6c8ec3b02f1b", - "reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/60328e362d4c2c802a54fcbf04f9d3fb892b4cf8", + "reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "type": "library", "extra": { @@ -6697,7 +6676,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.31.0" }, "funding": [ { @@ -6713,24 +6692,24 @@ "type": "tidelift" } ], - "time": "2024-01-29T20:11:03+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-php81", - "version": "v1.29.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php81.git", - "reference": "c565ad1e63f30e7477fc40738343c62b40bc672d" + "reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/c565ad1e63f30e7477fc40738343c62b40bc672d", - "reference": "c565ad1e63f30e7477fc40738343c62b40bc672d", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c", + "reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "type": "library", "extra": { @@ -6773,7 +6752,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php81/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-php81/tree/v1.31.0" }, "funding": [ { @@ -6789,20 +6768,20 @@ "type": "tidelift" } ], - "time": "2024-01-29T20:11:03+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-php83", - "version": "v1.28.0", + "version": "v1.29.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php83.git", - "reference": "b0f46ebbeeeda3e9d2faebdfbf4b4eae9b59fa11" + "reference": "86fcae159633351e5fd145d1c47de6c528f8caff" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/b0f46ebbeeeda3e9d2faebdfbf4b4eae9b59fa11", - "reference": "b0f46ebbeeeda3e9d2faebdfbf4b4eae9b59fa11", + "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/86fcae159633351e5fd145d1c47de6c528f8caff", + "reference": "86fcae159633351e5fd145d1c47de6c528f8caff", "shasum": "" }, "require": { @@ -6811,9 +6790,6 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" @@ -6853,7 +6829,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php83/tree/v1.28.0" + "source": "https://github.com/symfony/polyfill-php83/tree/v1.29.0" }, "funding": [ { @@ -6869,20 +6845,20 @@ "type": "tidelift" } ], - "time": "2023-08-16T06:22:46+00:00" + "time": "2024-01-29T20:11:03+00:00" }, { "name": "symfony/process", - "version": "v6.4.4", + "version": "v6.4.15", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "710e27879e9be3395de2b98da3f52a946039f297" + "reference": "3cb242f059c14ae08591c5c4087d1fe443564392" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/710e27879e9be3395de2b98da3f52a946039f297", - "reference": "710e27879e9be3395de2b98da3f52a946039f297", + "url": "https://api.github.com/repos/symfony/process/zipball/3cb242f059c14ae08591c5c4087d1fe443564392", + "reference": "3cb242f059c14ae08591c5c4087d1fe443564392", "shasum": "" }, "require": { @@ -6914,7 +6890,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v6.4.4" + "source": "https://github.com/symfony/process/tree/v6.4.15" }, "funding": [ { @@ -6930,20 +6906,20 @@ "type": "tidelift" } ], - "time": "2024-02-20T12:31:00+00:00" + "time": "2024-11-06T14:19:14+00:00" }, { "name": "symfony/psr-http-message-bridge", - "version": "v6.4.3", + "version": "v6.4.13", "source": { "type": "git", "url": "https://github.com/symfony/psr-http-message-bridge.git", - "reference": "49cfb0223ec64379f7154214dcc1f7c46f3c7a47" + "reference": "c9cf83326a1074f83a738fc5320945abf7fb7fec" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/49cfb0223ec64379f7154214dcc1f7c46f3c7a47", - "reference": "49cfb0223ec64379f7154214dcc1f7c46f3c7a47", + "url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/c9cf83326a1074f83a738fc5320945abf7fb7fec", + "reference": "c9cf83326a1074f83a738fc5320945abf7fb7fec", "shasum": "" }, "require": { @@ -6997,7 +6973,7 @@ "psr-7" ], "support": { - "source": "https://github.com/symfony/psr-http-message-bridge/tree/v6.4.3" + "source": "https://github.com/symfony/psr-http-message-bridge/tree/v6.4.13" }, "funding": [ { @@ -7013,20 +6989,20 @@ "type": "tidelift" } ], - "time": "2024-01-23T14:51:35+00:00" + "time": "2024-09-25T14:18:03+00:00" }, { "name": "symfony/routing", - "version": "v6.4.5", + "version": "v6.4.16", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "7fe30068e207d9c31c0138501ab40358eb2d49a4" + "reference": "91e02e606b4b705c2f4fb42f7e7708b7923a3220" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/7fe30068e207d9c31c0138501ab40358eb2d49a4", - "reference": "7fe30068e207d9c31c0138501ab40358eb2d49a4", + "url": "https://api.github.com/repos/symfony/routing/zipball/91e02e606b4b705c2f4fb42f7e7708b7923a3220", + "reference": "91e02e606b4b705c2f4fb42f7e7708b7923a3220", "shasum": "" }, "require": { @@ -7080,7 +7056,7 @@ "url" ], "support": { - "source": "https://github.com/symfony/routing/tree/v6.4.5" + "source": "https://github.com/symfony/routing/tree/v6.4.16" }, "funding": [ { @@ -7096,20 +7072,20 @@ "type": "tidelift" } ], - "time": "2024-02-27T12:33:30+00:00" + "time": "2024-11-13T15:31:34+00:00" }, { "name": "symfony/serializer", - "version": "v6.4.4", + "version": "v6.4.15", "source": { "type": "git", "url": "https://github.com/symfony/serializer.git", - "reference": "88da7f8fe03c5f4c2a69da907f1de03fab2e6872" + "reference": "9d862d66198f3c2e30404228629ef4c18d5d608e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/serializer/zipball/88da7f8fe03c5f4c2a69da907f1de03fab2e6872", - "reference": "88da7f8fe03c5f4c2a69da907f1de03fab2e6872", + "url": "https://api.github.com/repos/symfony/serializer/zipball/9d862d66198f3c2e30404228629ef4c18d5d608e", + "reference": "9d862d66198f3c2e30404228629ef4c18d5d608e", "shasum": "" }, "require": { @@ -7178,7 +7154,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.4" + "source": "https://github.com/symfony/serializer/tree/v6.4.15" }, "funding": [ { @@ -7194,25 +7170,26 @@ "type": "tidelift" } ], - "time": "2024-02-22T20:27:10+00:00" + "time": "2024-10-23T13:25:59+00:00" }, { "name": "symfony/service-contracts", - "version": "v3.4.1", + "version": "v3.5.1", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "fe07cbc8d837f60caf7018068e350cc5163681a0" + "reference": "e53260aabf78fb3d63f8d79d69ece59f80d5eda0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/fe07cbc8d837f60caf7018068e350cc5163681a0", - "reference": "fe07cbc8d837f60caf7018068e350cc5163681a0", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/e53260aabf78fb3d63f8d79d69ece59f80d5eda0", + "reference": "e53260aabf78fb3d63f8d79d69ece59f80d5eda0", "shasum": "" }, "require": { "php": ">=8.1", - "psr/container": "^1.1|^2.0" + "psr/container": "^1.1|^2.0", + "symfony/deprecation-contracts": "^2.5|^3" }, "conflict": { "ext-psr": "<1.1|>=2" @@ -7220,7 +7197,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "3.4-dev" + "dev-main": "3.5-dev" }, "thanks": { "name": "symfony/contracts", @@ -7260,7 +7237,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v3.4.1" + "source": "https://github.com/symfony/service-contracts/tree/v3.5.1" }, "funding": [ { @@ -7276,20 +7253,20 @@ "type": "tidelift" } ], - "time": "2023-12-26T14:02:43+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { "name": "symfony/string", - "version": "v6.4.4", + "version": "v6.4.15", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "4e465a95bdc32f49cf4c7f07f751b843bbd6dcd9" + "reference": "73a5e66ea2e1677c98d4449177c5a9cf9d8b4c6f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/4e465a95bdc32f49cf4c7f07f751b843bbd6dcd9", - "reference": "4e465a95bdc32f49cf4c7f07f751b843bbd6dcd9", + "url": "https://api.github.com/repos/symfony/string/zipball/73a5e66ea2e1677c98d4449177c5a9cf9d8b4c6f", + "reference": "73a5e66ea2e1677c98d4449177c5a9cf9d8b4c6f", "shasum": "" }, "require": { @@ -7346,7 +7323,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v6.4.4" + "source": "https://github.com/symfony/string/tree/v6.4.15" }, "funding": [ { @@ -7362,20 +7339,20 @@ "type": "tidelift" } ], - "time": "2024-02-01T13:16:41+00:00" + "time": "2024-11-13T13:31:12+00:00" }, { "name": "symfony/translation-contracts", - "version": "v3.4.1", + "version": "v3.5.1", "source": { "type": "git", "url": "https://github.com/symfony/translation-contracts.git", - "reference": "06450585bf65e978026bda220cdebca3f867fde7" + "reference": "4667ff3bd513750603a09c8dedbea942487fb07c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/06450585bf65e978026bda220cdebca3f867fde7", - "reference": "06450585bf65e978026bda220cdebca3f867fde7", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/4667ff3bd513750603a09c8dedbea942487fb07c", + "reference": "4667ff3bd513750603a09c8dedbea942487fb07c", "shasum": "" }, "require": { @@ -7384,7 +7361,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "3.4-dev" + "dev-main": "3.5-dev" }, "thanks": { "name": "symfony/contracts", @@ -7424,7 +7401,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/translation-contracts/tree/v3.4.1" + "source": "https://github.com/symfony/translation-contracts/tree/v3.5.1" }, "funding": [ { @@ -7440,20 +7417,20 @@ "type": "tidelift" } ], - "time": "2023-12-26T14:02:43+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { "name": "symfony/validator", - "version": "v6.4.4", + "version": "v6.4.16", "source": { "type": "git", "url": "https://github.com/symfony/validator.git", - "reference": "1cf92edc9a94d16275efef949fa6748d11cc8f47" + "reference": "9b0d1988b56511706bc91d96ead39acd77aaf34d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/validator/zipball/1cf92edc9a94d16275efef949fa6748d11cc8f47", - "reference": "1cf92edc9a94d16275efef949fa6748d11cc8f47", + "url": "https://api.github.com/repos/symfony/validator/zipball/9b0d1988b56511706bc91d96ead39acd77aaf34d", + "reference": "9b0d1988b56511706bc91d96ead39acd77aaf34d", "shasum": "" }, "require": { @@ -7500,7 +7477,8 @@ "Symfony\\Component\\Validator\\": "" }, "exclude-from-classmap": [ - "/Tests/" + "/Tests/", + "/Resources/bin/" ] }, "notification-url": "https://packagist.org/downloads/", @@ -7520,7 +7498,7 @@ "description": "Provides tools to validate values", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/validator/tree/v6.4.4" + "source": "https://github.com/symfony/validator/tree/v6.4.16" }, "funding": [ { @@ -7536,20 +7514,20 @@ "type": "tidelift" } ], - "time": "2024-02-22T20:27:10+00:00" + "time": "2024-11-27T09:48:51+00:00" }, { "name": "symfony/var-dumper", - "version": "v6.4.4", + "version": "v6.4.15", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "b439823f04c98b84d4366c79507e9da6230944b1" + "reference": "38254d5a5ac2e61f2b52f9caf54e7aa3c9d36b80" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/b439823f04c98b84d4366c79507e9da6230944b1", - "reference": "b439823f04c98b84d4366c79507e9da6230944b1", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/38254d5a5ac2e61f2b52f9caf54e7aa3c9d36b80", + "reference": "38254d5a5ac2e61f2b52f9caf54e7aa3c9d36b80", "shasum": "" }, "require": { @@ -7605,7 +7583,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v6.4.4" + "source": "https://github.com/symfony/var-dumper/tree/v6.4.15" }, "funding": [ { @@ -7621,20 +7599,20 @@ "type": "tidelift" } ], - "time": "2024-02-15T11:23:52+00:00" + "time": "2024-11-08T15:28:48+00:00" }, { "name": "symfony/var-exporter", - "version": "v6.4.4", + "version": "v6.4.13", "source": { "type": "git", "url": "https://github.com/symfony/var-exporter.git", - "reference": "0bd342e24aef49fc82a21bd4eedd3e665d177e5b" + "reference": "0f605f72a363f8743001038a176eeb2a11223b51" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-exporter/zipball/0bd342e24aef49fc82a21bd4eedd3e665d177e5b", - "reference": "0bd342e24aef49fc82a21bd4eedd3e665d177e5b", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/0f605f72a363f8743001038a176eeb2a11223b51", + "reference": "0f605f72a363f8743001038a176eeb2a11223b51", "shasum": "" }, "require": { @@ -7642,6 +7620,8 @@ "symfony/deprecation-contracts": "^2.5|^3" }, "require-dev": { + "symfony/property-access": "^6.4|^7.0", + "symfony/serializer": "^6.4|^7.0", "symfony/var-dumper": "^5.4|^6.0|^7.0" }, "type": "library", @@ -7680,7 +7660,7 @@ "serialize" ], "support": { - "source": "https://github.com/symfony/var-exporter/tree/v6.4.4" + "source": "https://github.com/symfony/var-exporter/tree/v6.4.13" }, "funding": [ { @@ -7696,20 +7676,20 @@ "type": "tidelift" } ], - "time": "2024-02-26T08:37:45+00:00" + "time": "2024-09-25T14:18:03+00:00" }, { "name": "symfony/yaml", - "version": "v6.4.3", + "version": "v6.4.13", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "d75715985f0f94f978e3a8fa42533e10db921b90" + "reference": "e99b4e94d124b29ee4cf3140e1b537d2dad8cec9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/d75715985f0f94f978e3a8fa42533e10db921b90", - "reference": "d75715985f0f94f978e3a8fa42533e10db921b90", + "url": "https://api.github.com/repos/symfony/yaml/zipball/e99b4e94d124b29ee4cf3140e1b537d2dad8cec9", + "reference": "e99b4e94d124b29ee4cf3140e1b537d2dad8cec9", "shasum": "" }, "require": { @@ -7752,7 +7732,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v6.4.3" + "source": "https://github.com/symfony/yaml/tree/v6.4.13" }, "funding": [ { @@ -7768,34 +7748,41 @@ "type": "tidelift" } ], - "time": "2024-01-23T14:51:35+00:00" + "time": "2024-09-25T14:18:03+00:00" }, { "name": "twig/twig", - "version": "v3.8.0", + "version": "v3.14.2", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "9d15f0ac07f44dc4217883ec6ae02fd555c6f71d" + "reference": "0b6f9d8370bb3b7f1ce5313ed8feb0fafd6e399a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/9d15f0ac07f44dc4217883ec6ae02fd555c6f71d", - "reference": "9d15f0ac07f44dc4217883ec6ae02fd555c6f71d", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/0b6f9d8370bb3b7f1ce5313ed8feb0fafd6e399a", + "reference": "0b6f9d8370bb3b7f1ce5313ed8feb0fafd6e399a", "shasum": "" }, "require": { - "php": ">=7.2.5", + "php": ">=8.0.2", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-ctype": "^1.8", "symfony/polyfill-mbstring": "^1.3", - "symfony/polyfill-php80": "^1.22" + "symfony/polyfill-php81": "^1.29" }, "require-dev": { "psr/container": "^1.0|^2.0", - "symfony/phpunit-bridge": "^5.4.9|^6.3|^7.0" + "symfony/phpunit-bridge": "^5.4.9|^6.4|^7.0" }, "type": "library", "autoload": { + "files": [ + "src/Resources/core.php", + "src/Resources/debug.php", + "src/Resources/escaper.php", + "src/Resources/string_loader.php" + ], "psr-4": { "Twig\\": "src/" } @@ -7828,7 +7815,7 @@ ], "support": { "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/v3.8.0" + "source": "https://github.com/twigphp/Twig/tree/v3.14.2" }, "funding": [ { @@ -7840,7 +7827,7 @@ "type": "tidelift" } ], - "time": "2023-11-21T18:54:41+00:00" + "time": "2024-11-07T12:36:22+00:00" }, { "name": "webflo/drupal-finder", diff --git a/models/Aquila-VL-2B.yml b/models/Aquila-VL-2B.yml new file mode 100644 index 0000000..3248749 --- /dev/null +++ b/models/Aquila-VL-2B.yml @@ -0,0 +1,117 @@ +framework: + name: 'Model Openness Framework' + version: '1.0' + date: '2024-12-15' +release: + name: Aquila-VL-2B + version: 2.18B + date: '2024-11-22' + type: multimodal + architecture: 'transformer decoder' + origin: 'Qwen2.5-1.5B-instruct ' + producer: 'Beijing Academy of Artificial Intelligence(BAAl)' + contact: 403969556@qq.com + huggingface: 'https://huggingface.co/https://huggingface.co/BAAI/Aquila-VL-2B-llava-qwen' + components: + - + name: 'Model architecture' + description: "Well commented code for the model's architecture" + location: 'https://huggingface.co/Qwen/Qwen2.5-1.5B-Instruct' + license_name: Apache-2.0 + license_path: 'https://huggingface.co/Qwen/Qwen2.5-1.5B-Instruct/blob/main/LICENSE' + - + name: 'Data preprocessing code' + description: 'Code for data cleansing, normalization, and augmentation' + location: 'https://huggingface.co/datasets/BAAI/Infinity-MM/tree/main/preprocessing' + license_name: Apache-2.0 + license_path: 'https://huggingface.co/datasets/choosealicense/licenses/blob/main/markdown/apache-2.0.md' + - + name: 'Training code' + description: 'Code used for training the model' + location: 'https://github.com/LLaVA-VL/LLaVA-NeXT' + license_name: Apache-2.0 + license_path: 'https://github.com/LLaVA-VL/LLaVA-NeXT?tab=Apache-2.0-1-ov-file' + - + name: 'Inference code' + description: 'Code used for running the model to make predictions' + location: 'https://github.com/LLaVA-VL/LLaVA-NeXT' + license_name: Apache-2.0 + license_path: 'https://github.com/LLaVA-VL/LLaVA-NeXT?tab=Apache-2.0-1-ov-file' + - + name: 'Evaluation code' + description: 'Code used for evaluating the model' + location: 'https://github.com/open-compass/VLMEvalKit?tab=Apache-2.0-1-ov-file' + license_name: Apache-2.0 + license_path: 'https://github.com/open-compass/VLMEvalKit?tab=Apache-2.0-1-ov-file' + - + name: 'Supporting libraries and tools' + description: "Libraries and tools used in the model's development" + location: 'https://github.com/huggingface/transformers' + license_name: Apache-2.0 + license_path: 'https://github.com/huggingface/transformers?tab=Apache-2.0-1-ov-file' + - + name: 'Model parameters (Final)' + description: 'Trained model parameters, weights and biases' + location: 'https://huggingface.co/BAAI/Aquila-VL-2B-llava-qwen' + license_name: Apache-2.0 + license_path: 'https://huggingface.co/datasets/choosealicense/licenses/blob/main/markdown/apache-2.0.md' + - + name: 'Model parameters (Intermediate)' + description: 'Trained model parameters, weights and biases' + location: 'https://huggingface.co/BAAI/Aquila-VL-2B-Intermediate' + license_name: CDLA-Permissive-2.0 + license_path: 'https://huggingface.co/datasets/choosealicense/licenses/blob/main/markdown/apache-2.0.md' + - + name: Datasets + description: 'Training, validation and testing datasets used for the model' + location: 'https://huggingface.co/datasets/BAAI/Infinity-MM' + license_name: CC-BY-4.0 + license_path: 'https://choosealicense.com/licenses/cc-by-sa-4.0/' + - + name: 'Evaluation data' + description: 'Data used for evaluating the model' + location: 'https://github.com/open-compass/VLMEvalKit?tab=Apache-2.0-1-ov-file' + license_name: CDLA-Permissive-2.0 + license_path: 'https://github.com/open-compass/VLMEvalKit?tab=Apache-2.0-1-ov-file' + - + name: 'Model metadata' + description: 'Any model metadata including training configuration and optimizer states' + location: '' + license_name: 'Component not included' + license_path: '' + - + name: 'Sample model outputs' + description: 'Examples of outputs generated by the model' + location: '' + license_name: 'Component not included' + license_path: '' + - + name: 'Model card' + description: 'Model details including performance metrics, intended use, and limitations' + location: 'https://huggingface.co/BAAI/Aquila-VL-2B-llava-qwen' + license_name: Apache-2.0 + license_path: 'https://choosealicense.com/licenses/apache-2.0/' + - + name: 'Data card' + description: 'Documentation for datasets including source, characteristics, and preprocessing details' + location: 'https://huggingface.co/datasets/BAAI/Infinity-MM' + license_name: CC-BY-4.0 + license_path: 'https://choosealicense.com/licenses/cc-by-sa-4.0/' + - + name: 'Technical report' + description: 'Technical report detailing capabilities and usage instructions for the model' + location: 'https://arxiv.org/abs/2410.18558' + license_name: CC-BY-4.0 + license_path: 'https://creativecommons.org/licenses/by/4.0/' + - + name: 'Research paper' + description: 'Research paper detailing the development and capabilities of the model' + location: 'https://arxiv.org/abs/2410.18558' + license_name: CC-BY-4.0 + license_path: 'https://creativecommons.org/licenses/by/4.0/' + - + name: 'Evaluation results' + description: 'The results from evaluating the model' + location: 'https://huggingface.co/BAAI/Aquila-VL-2B-llava-qwen' + license_name: Apache-2.0 + license_path: 'https://choosealicense.com/licenses/apache-2.0/' diff --git a/models/Jiang-Base.yml b/models/Jiang-Base.yml new file mode 100644 index 0000000..4f72206 --- /dev/null +++ b/models/Jiang-Base.yml @@ -0,0 +1,117 @@ +framework: + name: 'Model Openness Framework' + version: '1.0' + date: '2024-12-15' +release: + name: Jiang-Base + version: 30B + date: '2024-11-14' + type: language + architecture: 'transformer decoder' + origin: '' + producer: KDF + contact: '' + huggingface: 'https://huggingface.co/kdf/jiang-base' + components: + - + name: 'Model architecture' + description: "Well commented code for the model's architecture" + location: '' + license_name: 'Component Not Included' + license_path: '' + - + name: 'Data preprocessing code' + description: 'Code for data cleansing, normalization, and augmentation' + location: '' + license_name: 'Component Not Included' + license_path: '' + - + name: 'Training code' + description: 'Code used for training the model' + location: '' + license_name: 'Component Not Included' + license_path: '' + - + name: 'Inference code' + description: 'Code used for running the model to make predictions' + location: '' + license_name: apache-2.0 + license_path: '' + - + name: 'Evaluation code' + description: 'Code used for evaluating the model' + location: '' + license_name: 'Component Not Included' + license_path: '' + - + name: 'Supporting libraries and tools' + description: "Libraries and tools used in the model's development" + location: '' + license_name: 'Component Not Included' + license_path: '' + - + name: 'Model parameters (Final)' + description: 'Trained model parameters, weights and biases' + location: '' + license_name: 'License not specified' + license_path: '' + - + name: 'Model parameters (Intermediate)' + description: 'Trained model parameters, weights and biases' + location: '' + license_name: 'Component Not Included' + license_path: '' + - + name: Datasets + description: 'Training, validation and testing datasets used for the model' + location: '' + license_name: 'License not specified' + license_path: '' + - + name: 'Evaluation data' + description: 'Data used for evaluating the model' + location: '' + license_name: 'Component Not Included' + license_path: '' + - + name: 'Model metadata' + description: 'Any model metadata including training configuration and optimizer states' + location: '' + license_name: 'Component Not Included' + license_path: '' + - + name: 'Sample model outputs' + description: 'Examples of outputs generated by the model' + location: '' + license_name: 'Component Not Included' + license_path: '' + - + name: 'Model card' + description: 'Model details including performance metrics, intended use, and limitations' + location: '' + license_name: 'License not specified' + license_path: '' + - + name: 'Data card' + description: 'Documentation for datasets including source, characteristics, and preprocessing details' + location: '' + license_name: 'Component Not Included' + license_path: '' + - + name: 'Technical report' + description: 'Technical report detailing capabilities and usage instructions for the model' + location: '' + license_name: 'Component Not Included' + license_path: '' + - + name: 'Research paper' + description: 'Research paper detailing the development and capabilities of the model' + location: '' + license_name: 'License not specified' + license_path: '' + - + name: 'Evaluation results' + description: 'The results from evaluating the model' + location: '' + license_name: 'License not specified' + license_path: '' diff --git a/models/Jurassic-1-Jumbo.yml b/models/Jurassic-1-Jumbo.yml new file mode 100644 index 0000000..2363461 --- /dev/null +++ b/models/Jurassic-1-Jumbo.yml @@ -0,0 +1,116 @@ +framework: + name: 'Model Openness Framework' + version: '1.0' + date: '2024-12-15' +release: + name: Jurassic-1-Jumbo + version: 178B + date: '2024-11-14' + type: language + architecture: 'transformer decoder' + origin: '' + producer: 'AI21 Labs' + contact: '' + components: + - + name: 'Model architecture' + description: "Well commented code for the model's architecture" + location: '' + license_name: 'License not specified' + license_path: '' + - + name: 'Data preprocessing code' + description: 'Code for data cleansing, normalization, and augmentation' + location: '' + license_name: 'Component Not Included' + license_path: '' + - + name: 'Training code' + description: 'Code used for training the model' + location: '' + license_name: 'Component Not Included' + license_path: '' + - + name: 'Inference code' + description: 'Code used for running the model to make predictions' + location: '' + license_name: 'Component Not Included' + license_path: '' + - + name: 'Evaluation code' + description: 'Code used for evaluating the model' + location: '' + license_name: 'License not specified' + license_path: '' + - + name: 'Supporting libraries and tools' + description: "Libraries and tools used in the model's development" + location: '' + license_name: 'Component Not Included' + license_path: '' + - + name: 'Model parameters (Final)' + description: 'Trained model parameters, weights and biases' + location: '' + license_name: 'Component Not Included' + license_path: '' + - + name: 'Model parameters (Intermediate)' + description: 'Trained model parameters, weights and biases' + location: '' + license_name: 'Component Not Included' + license_path: '' + - + name: Datasets + description: 'Training, validation and testing datasets used for the model' + location: '' + license_name: 'License not specified' + license_path: '' + - + name: 'Evaluation data' + description: 'Data used for evaluating the model' + location: '' + license_name: 'Component Not Included' + license_path: '' + - + name: 'Model metadata' + description: 'Any model metadata including training configuration and optimizer states' + location: '' + license_name: 'Component Not Included' + license_path: '' + - + name: 'Sample model outputs' + description: 'Examples of outputs generated by the model' + location: '' + license_name: 'Component Not Included' + license_path: '' + - + name: 'Model card' + description: 'Model details including performance metrics, intended use, and limitations' + location: '' + license_name: 'Component Not Included' + license_path: '' + - + name: 'Data card' + description: 'Documentation for datasets including source, characteristics, and preprocessing details' + location: '' + license_name: 'Component Not Included' + license_path: '' + - + name: 'Technical report' + description: 'Technical report detailing capabilities and usage instructions for the model' + location: '' + license_name: 'Component Not Included' + license_path: '' + - + name: 'Research paper' + description: 'Research paper detailing the development and capabilities of the model' + location: '' + license_name: 'License not specified' + license_path: '' + - + name: 'Evaluation results' + description: 'The results from evaluating the model' + location: '' + license_name: 'License not specified' + license_path: '' diff --git a/models/MiniCPM3-4B.yml b/models/MiniCPM3-4B.yml new file mode 100644 index 0000000..7f893c0 --- /dev/null +++ b/models/MiniCPM3-4B.yml @@ -0,0 +1,116 @@ +framework: + name: 'Model Openness Framework' + version: '1.0' + date: '2024-12-15' +release: + name: 'MiniCPM3-4B ' + version: 4B + date: '2024-11-14' + type: language + architecture: decoder + origin: '' + producer: OpenBMB + contact: '' + components: + - + name: 'Model architecture' + description: "Well commented code for the model's architecture" + location: '' + license_name: 'License not specified' + license_path: '' + - + name: 'Data preprocessing code' + description: 'Code for data cleansing, normalization, and augmentation' + location: '' + license_name: 'Component not included' + license_path: '' + - + name: 'Training code' + description: 'Code used for training the model' + location: '' + license_name: 'Component not included' + license_path: '' + - + name: 'Inference code' + description: 'Code used for running the model to make predictions' + location: '' + license_name: Apache-2.0 + license_path: '' + - + name: 'Evaluation code' + description: 'Code used for evaluating the model' + location: '' + license_name: 'Component not included' + license_path: '' + - + name: 'Supporting libraries and tools' + description: "Libraries and tools used in the model's development" + location: '' + license_name: Apache-2.0 + license_path: '' + - + name: 'Model parameters (Final)' + description: 'Trained model parameters, weights and biases' + location: '' + license_name: 'Component not included' + license_path: '' + - + name: 'Model parameters (Intermediate)' + description: 'Trained model parameters, weights and biases' + location: '' + license_name: 'Component not included' + license_path: '' + - + name: Datasets + description: 'Training, validation and testing datasets used for the model' + location: '' + license_name: 'Component not included' + license_path: '' + - + name: 'Evaluation data' + description: 'Data used for evaluating the model' + location: '' + license_name: 'Component not included' + license_path: '' + - + name: 'Model metadata' + description: 'Any model metadata including training configuration and optimizer states' + location: '' + license_name: 'Component not included' + license_path: '' + - + name: 'Sample model outputs' + description: 'Examples of outputs generated by the model' + location: '' + license_name: 'Component not included' + license_path: '' + - + name: 'Model card' + description: 'Model details including performance metrics, intended use, and limitations' + location: '' + license_name: 'License not specified' + license_path: '' + - + name: 'Data card' + description: 'Documentation for datasets including source, characteristics, and preprocessing details' + location: '' + license_name: 'Component not included' + license_path: '' + - + name: 'Technical report' + description: 'Technical report detailing capabilities and usage instructions for the model' + location: '' + license_name: 'License not specified' + license_path: '' + - + name: 'Research paper' + description: 'Research paper detailing the development and capabilities of the model' + location: '' + license_name: 'License not specified' + license_path: '' + - + name: 'Evaluation results' + description: 'The results from evaluating the model' + location: '' + license_name: 'License not specified' + license_path: '' diff --git a/models/PanGu-a.yml b/models/PanGu-a.yml index 960ff79..2df326b 100644 --- a/models/PanGu-a.yml +++ b/models/PanGu-a.yml @@ -5,8 +5,8 @@ framework: release: name: PanGu-α version: 200B - date: '2024-10-03' - type: '' + date: '2024-11-14' + type: language architecture: decoder origin: '' producer: Huawei diff --git a/models/StellarX-4B-V0.yml b/models/StellarX-4B-V0.yml new file mode 100644 index 0000000..1a4b961 --- /dev/null +++ b/models/StellarX-4B-V0.yml @@ -0,0 +1,117 @@ +framework: + name: 'Model Openness Framework' + version: '1.0' + date: '2024-12-15' +release: + name: StellarX-4B-V0 + version: 4B + date: '2024-11-14' + type: '' + architecture: decoder + origin: StellarX-4B-V0 + producer: 'Dampish, Arkane Industries' + contact: '' + huggingface: 'https://huggingface.co/Dampish/StellarX-4B-V0' + components: + - + name: 'Model architecture' + description: "Well commented code for the model's architecture" + location: '' + license_name: 'Component not include' + license_path: '' + - + name: 'Data preprocessing code' + description: 'Code for data cleansing, normalization, and augmentation' + location: '' + license_name: 'Component not included' + license_path: '' + - + name: 'Training code' + description: 'Code used for training the model' + location: '' + license_name: 'Component not included' + license_path: '' + - + name: 'Inference code' + description: 'Code used for running the model to make predictions' + location: '' + license_name: 'commercial use restrcitions; CC-BY-NC-SA-4.0' + license_path: '' + - + name: 'Evaluation code' + description: 'Code used for evaluating the model' + location: '' + license_name: 'Component not included' + license_path: '' + - + name: 'Supporting libraries and tools' + description: "Libraries and tools used in the model's development" + location: '' + license_name: 'License not specified' + license_path: '' + - + name: 'Model parameters (Final)' + description: 'Trained model parameters, weights and biases' + location: '' + license_name: 'Component not include.' + license_path: '' + - + name: 'Model parameters (Intermediate)' + description: 'Trained model parameters, weights and biases' + location: '' + license_name: 'Component not included' + license_path: '' + - + name: Datasets + description: 'Training, validation and testing datasets used for the model' + location: '' + license_name: 'License not specified' + license_path: '' + - + name: 'Evaluation data' + description: 'Data used for evaluating the model' + location: '' + license_name: 'Component not included' + license_path: '' + - + name: 'Model metadata' + description: 'Any model metadata including training configuration and optimizer states' + location: '' + license_name: 'License not specified' + license_path: '' + - + name: 'Sample model outputs' + description: 'Examples of outputs generated by the model' + location: '' + license_name: 'Component not included' + license_path: '' + - + name: 'Model card' + description: 'Model details including performance metrics, intended use, and limitations' + location: '' + license_name: 'License not specified' + license_path: '' + - + name: 'Data card' + description: 'Documentation for datasets including source, characteristics, and preprocessing details' + location: '' + license_name: 'License not specified' + license_path: '' + - + name: 'Technical report' + description: 'Technical report detailing capabilities and usage instructions for the model' + location: '' + license_name: 'License not specified' + license_path: '' + - + name: 'Research paper' + description: 'Research paper detailing the development and capabilities of the model' + location: '' + license_name: 'License not specified' + license_path: '' + - + name: 'Evaluation results' + description: 'The results from evaluating the model' + location: '' + license_name: 'License not specified' + license_path: '' diff --git a/web/modules/mof/config/install/rest.resource.model_v1.yml b/web/modules/mof/config/install/rest.resource.model_v1.yml new file mode 100644 index 0000000..ebaee0c --- /dev/null +++ b/web/modules/mof/config/install/rest.resource.model_v1.yml @@ -0,0 +1,17 @@ +langcode: en +status: true +dependencies: + module: + - mof + - serialization + - user +id: model_v1 +plugin_id: model_v1 +granularity: resource +configuration: + methods: + - GET + formats: + - json + authentication: + - cookie diff --git a/web/modules/mof/mof.info.yml b/web/modules/mof/mof.info.yml index 482f04e..f3342f1 100644 --- a/web/modules/mof/mof.info.yml +++ b/web/modules/mof/mof.info.yml @@ -1,8 +1,9 @@ name: 'Model Openness Framework' type: module -description: '@todo Add description.' -package: '@todo Add package' +description: 'Implements the model openness framework in Drupal' +package: 'Model Openness Tool' core_version_requirement: ^10 dependencies: - drupal:options + - drupal:rest - social_auth_github:social_auth_github diff --git a/web/modules/mof/mof.install b/web/modules/mof/mof.install new file mode 100644 index 0000000..755eab7 --- /dev/null +++ b/web/modules/mof/mof.install @@ -0,0 +1,29 @@ +install([ + 'rest', + 'config', + 'dynamic_page_cache', + 'page_cache' + ]); + + // Enable MOT REST plugin. + \Drupal::service('config.installer')->installDefaultConfig('module', 'mof'); + + // Add permission to use REST API for anonymous and authenticated users. + foreach (['anonymous', 'authenticated'] as $role_name) { + $role = \Drupal\user\Entity\Role::load($role_name); + if ($role) { + $role->grantPermission('restful get model_v1'); + $role->save(); + } + } +} + diff --git a/web/modules/mof/mof.module b/web/modules/mof/mof.module index de6abcc..0cbef7e 100644 --- a/web/modules/mof/mof.module +++ b/web/modules/mof/mof.module @@ -1,6 +1,4 @@ -hasRole('admin') && (int)$user->id() !== 1) { + $base_table = $query->getTables()['base_table']['alias']; + $query->leftJoin('model_field_data', 'mfd', "mfd.id = $base_table.id"); + $query->condition('mfd.status', 'approved', '='); + } + + return $query; +} diff --git a/web/modules/mof/mof.services.yml b/web/modules/mof/mof.services.yml index ddc95cc..2812273 100644 --- a/web/modules/mof/mof.services.yml +++ b/web/modules/mof/mof.services.yml @@ -1,5 +1,22 @@ services: + logger.channel.mot: + parent: logger.channel_base + arguments: ['mot'] + + mof.api.rate_limiter: + class: Drupal\mof\RateLimitMiddleware + arguments: + - '@cache.default' + - '@logger.channel.mot' + tags: + - { name: http_middleware, priority: 400 } + + mof.api.exception_subscriber: + class: Drupal\mof\EventSubscriber\ApiExceptionSubscriber + tags: + - { name: event_subscriber } + license_handler: class: Drupal\mof\LicenseHandler arguments: @@ -24,6 +41,7 @@ services: - '@serializer' - '@model_evaluator' - '@component.manager' + - '@logger.channel.mot' model_validator: class: Drupal\mof\ModelValidator diff --git a/web/modules/mof/src/Controller/ModelController.php b/web/modules/mof/src/Controller/ModelController.php index 43dbdfc..daffc7e 100644 --- a/web/modules/mof/src/Controller/ModelController.php +++ b/web/modules/mof/src/Controller/ModelController.php @@ -120,13 +120,19 @@ public function badge(ModelInterface $model, int $class): Response { * Return a yaml representation of the model. */ public function yaml(ModelInterface $model): Response { - $yaml = $this->modelSerializer->toYaml($model); - $response = new Response(); - $response->setContent($yaml); - $response->headers->set('Content-Type', 'application/yaml'); - $response->headers->set('Content-Length', (string)strlen($yaml)); - $response->headers->set('Content-Disposition', 'attachment; filename="mof.yml"'); + + try { + $yaml = $this->modelSerializer->toYaml($model); + $response->setContent($yaml); + $response->headers->set('Content-Type', 'application/yaml'); + $response->headers->set('Content-Length', (string)strlen($yaml)); + $response->headers->set('Content-Disposition', 'attachment; filename="mof.yml"'); + } + catch (\RuntimeException $e) { + $response->setContent($e->getMessage()); + $response->setStatusCode(Response::HTTP_UNPROCESSABLE_ENTITY); + } return $response; } @@ -135,13 +141,19 @@ public function yaml(ModelInterface $model): Response { * Return a json file representation of the model. */ public function json(ModelInterface $model): Response { - $json = $this->modelSerializer->toJson($model); - $response = new Response(); - $response->setContent($json); - $response->headers->set('Content-Type', 'application/json'); - $response->headers->set('Content-Length', (string)strlen($json)); - $response->headers->set('Content-Disposition', 'attachment; filename="mof.json"'); + + try { + $json = $this->modelSerializer->toJson($model); + $response->setContent($json); + $response->headers->set('Content-Type', 'application/json'); + $response->headers->set('Content-Length', (string)strlen($json)); + $response->headers->set('Content-Disposition', 'attachment; filename="mof.json"'); + } + catch (\RuntimeException $e) { + $response->setContent($e->getMessage()); + $response->setStatusCode(Response::HTTP_UNPROCESSABLE_ENTITY); + } return $response; } diff --git a/web/modules/mof/src/EventSubscriber/ApiExceptionSubscriber.php b/web/modules/mof/src/EventSubscriber/ApiExceptionSubscriber.php new file mode 100644 index 0000000..1752b79 --- /dev/null +++ b/web/modules/mof/src/EventSubscriber/ApiExceptionSubscriber.php @@ -0,0 +1,47 @@ + 'onException']; + } + + /** + * Handles the exception event. + * + * @param \Symfony\Component\HttpKernel\Event\ExceptionEvent $event + * The exception event. + */ + public function onException(ExceptionEvent $event) { + $request = $event->getRequest(); + + // Only handle exceptions for API hits. + if (strpos($request->getPathInfo(), '/api') === 0) { + $exception = $event->getThrowable(); + + $json = [ + 'error' => [ + 'code' => $exception->getStatusCode(), + 'message' => $exception->getMessage(), + ]]; + + $response = new JsonResponse($json, $exception->getStatusCode()); + $event->setResponse($response); + } + } + +} + diff --git a/web/modules/mof/src/ModelEvaluator.php b/web/modules/mof/src/ModelEvaluator.php index 09a84c7..83046ab 100644 --- a/web/modules/mof/src/ModelEvaluator.php +++ b/web/modules/mof/src/ModelEvaluator.php @@ -274,7 +274,7 @@ private function isOpenSourceLicense(int $cid): bool { * @return float * Progress percentage */ - private function getProgress(int $class): float { + public function getProgress(int $class): float { $required = $this->getRequiredComponents(); $evaluate = $this->evaluate(); diff --git a/web/modules/mof/src/ModelEvaluatorInterface.php b/web/modules/mof/src/ModelEvaluatorInterface.php index afeedd8..81a42a1 100644 --- a/web/modules/mof/src/ModelEvaluatorInterface.php +++ b/web/modules/mof/src/ModelEvaluatorInterface.php @@ -1,6 +1,4 @@ -getOwner(); $data = [ @@ -78,32 +77,33 @@ private function processModel(ModelInterface $model): array { } /** - * Return a YAML representation of the model. - * - * @param \Drupal\mof\ModelInterface $model - * The model to convert to YAML. - * @return string - * A string representing the model in YAML format. + * {@inheritdoc} */ public function toYaml(ModelInterface $model): string { - return Yaml::encode($this->processModel($model)); + try { + return Yaml::encode($this->normalize($model)); + } + catch (InvalidDataTypeException $e) { + $this->logger->error('@exception', ['@exception' => $e->getMessage()]); + throw new \RuntimeException('Failed to convert model to YAML.', $e->getCode(), $e); + } } /** - * Return a JSON representation of the model. - * - * @param \Drupal\mof\ModelInterface $model - * The model to convert to JSON. - * @return string - * A string representing the model in JSON format. + * {@inheritdoc} */ public function toJson(ModelInterface $model): string { - return $this - ->serializer - ->serialize($this - ->processModel($model), 'json', [ - 'json_encode_options' => \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES - ]); + try { + return $this + ->serializer + ->serialize($this->normalize($model), 'json', [ + 'json_encode_options' => \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES + ]); + } + catch (UnsupportedFormatException $e) { + $this->logger->error('@exception', ['@exception' => $e->getMessage()]); + throw new \RuntimeException('Failed to convert model to JSON.', $e->getCode(), $e); + } } } diff --git a/web/modules/mof/src/ModelSerializerInterface.php b/web/modules/mof/src/ModelSerializerInterface.php new file mode 100644 index 0000000..d03d9d0 --- /dev/null +++ b/web/modules/mof/src/ModelSerializerInterface.php @@ -0,0 +1,41 @@ +modelStorage = $entity_type_manager->getStorage('model'); + } + + /** + * {@inheritdoc} + */ + public static function create( + ContainerInterface $container, + array $configuration, + $plugin_id, + $plugin_definition + ) { + return new static( + $configuration, + $plugin_id, + $plugin_definition, + $container->getParameter('serializer.formats'), + $container->get('logger.factory')->get('api/v1/model'), + $container->get('entity_type.manager'), + $container->get('model_serializer'), + $container->get('model_evaluator') + ); + } + + /** + * Responds to model_v1 GET requests. + * + * @param \Symfony\Component\HttpFoundation\Request $request + * The incoming request. + * @param \Drupal\mof\ModelInterface $model + * The model entity. If NULL a model collection is returned. + * + * @return \Drupal\Core\Cache\CacheableJsonResponse + * The response containing model data. + */ + public function get(Request $request, ?ModelInterface $model = NULL): CacheableJsonResponse { + return ($model) ? $this->getModel($model) : $this->listModels($request); + } + + /** + * Retrieve a single model. + * + * This method returns a cacheable JSON response + * containing a model with classification information. + * + * @param \Drupal\mof\ModelInterface $model + * The model entity. + * + * @return \Drupal\Core\Cache\CacheableJsonResponse + * The response containing the model. + */ + protected function getModel(ModelInterface $model): CacheableJsonResponse { + $json = $this->classify($model); + $response = new CacheableJsonResponse($json); + $response->addCacheableDependency($model); + return $response; + } + + /** + * Retrieve a collection of models. + * + * This method returns a cacheable JSON response containing + * a list of models with pagination details. + * + * Query parameters: + * - page (int): Current page number (1-indexed). + * Defaults to 1 if not specified. + * - limit (int): The maximum number of models to display per page. + * Defaults to 100 if not specified. + * + * @param \Symfony\Component\HttpFoundation\Request $request + * The incoming request. + * + * @return \Drupal\Core\Cache\CacheableJsonResponse + * The response containing models and pager details. + */ + protected function listModels(Request $request): CacheableJsonResponse { + $collection = ['pager' => [], 'models' => []]; + + $page = max(1, (int) $request->query->get('page', 1)); + $limit = max(1, (int) $request->query->get('limit', 100)); + + $pager = new Pager($this->getModelCount(), $limit, $page); + $collection['pager']['total_items'] = $pager->getTotalItems(); + $collection['pager']['total_pages'] = $pager->getTotalPages(); + $collection['pager']['current_page'] = $page; + + $models = $this + ->modelStorage + ->getQuery() + ->accessCheck(TRUE) + ->sort('id', 'ASC') + ->range(($page - 1) * $limit, $limit) + ->execute(); + + foreach ($this + ->modelStorage + ->loadMultiple($models) as $model) { + + $collection['models'][] = $this->classify($model); + } + + $cache_metadata = new CacheableMetadata(); + $cache_metadata->setCacheMaxAge(3600); + $cache_metadata->addCacheContexts(['url.query_args:limit', 'url.query_args:page']); + + $response = new CacheableJsonResponse($collection); + $response->addCacheableDependency($cache_metadata); + return $response; + } + + /** + * Return a total number of models in the database. + * + * @return int + * The number of models. + */ + protected function getModelCount(): int { + return $this + ->modelStorage + ->getQuery() + ->accessCheck(TRUE) + ->count() + ->execute(); + } + + /** + * Evaluate and add classification information to model. + * + * @param \Drupal\mof\ModelInterface $model + * The model entity. + * + * @return array + * An array containing model data suitable for JSON encoding. + */ + protected function classify(ModelInterface $model): array { + $evaluator = $this->modelEvaluator->setModel($model); + + $json = $this->modelSerializer->toJson($model); + $json = json_decode($json, TRUE); + + $class = $evaluator->getClassification(FALSE); + $json['classification']['class'] = $class; + $json['classification']['label'] = $evaluator->getClassLabel($class); + + for ($i = 1; $i <= 3; ++$i) { + $json['classification']['progress'][$i] = $evaluator->getProgress($i); + } + + return ['id' => $model->id(), ...$json]; + } + + /** + * {@inheritdoc} + */ + public function routes() { + $routes = new RouteCollection(); + $definition = $this->getPluginDefinition(); + + foreach ($definition['uri_paths'] as $key => $uri) { + $route = $this->getBaseRoute($uri, 'GET'); + + if (strstr($uri, '{model}')) { + $route->setOption('parameters', ['model' => ['type' => 'entity:model']]); + $route->setRequirement('_entity_access', 'model.view'); + $route->setRequirement('model', '\d+'); + } + + $routes->add("{$this->pluginId}.{$key}.GET", $route); + } + + return $routes; + } + +} + diff --git a/web/modules/mof/src/RateLimitMiddleware.php b/web/modules/mof/src/RateLimitMiddleware.php new file mode 100644 index 0000000..31bc501 --- /dev/null +++ b/web/modules/mof/src/RateLimitMiddleware.php @@ -0,0 +1,86 @@ +isApiRequest($request)) { + return $this->http->handle($request, $type, $catch); + } + return $this->rateLimit($request) ?: $this->http->handle($request, $type, $catch); + } + + /** + * Checks if the request path is for an API endpoint. + * + * @param \Symfony\Component\HttpFoundation\Request $request + * The HTTP request. + * + * @return bool + * TRUE if the request path begins with "/api", FALSE otherwise. + */ + private function isApiRequest(Request $request): bool { + return strpos($request->getPathInfo(), '/api') === 0; + } + + /** + * Applies rate limiting based on client IP address. + * + * Checks the number of requests made by the IP in the last interval. + * If the count exceeds the limit, returns a JSON error response. + * Otherwise, increments the request count and stores it in the cache. + * + * @param \Symfony\Component\HttpFoundation\Request $request + * The HTTP request. + * + * @return \Symfony\Component\HttpFoundation\JsonResponse|null + * A JSON response with an error if the rate limit is exceeded, or NULL if allowed. + */ + private function rateLimit(Request $request): ?JsonResponse { + $cache_key = 'rate_limit:' . $request->getClientIp(); + $request_count = $this->cache->get($cache_key)->data ?? 1; + + if ($request_count > self::LIMIT) { + $this->logger->notice('Rate limit exceeded for @ip', ['@ip' => $request->getClientIp()]); + return new JsonResponse(['error' => [ + 'code' => Response::HTTP_TOO_MANY_REQUESTS, + 'message' => 'Rate limit exceeded. Try again later.']], Response::HTTP_TOO_MANY_REQUESTS); + } + + $this->cache->set($cache_key, $request_count + 1, time() + self::INTERVAL); + return NULL; + } + +} + From 007d1678fe74c7245cc2fab4c40d19a41296db86 Mon Sep 17 00:00:00 2001 From: Greg Date: Mon, 2 Dec 2024 19:25:19 -0500 Subject: [PATCH 3/3] Add caching contexts to list builder --- web/modules/mof/src/Form/ModelSearchForm.php | 8 +++----- web/modules/mof/src/ModelAdminListBuilder.php | 13 ++++++++++++- web/modules/mof/src/ModelListBuilder.php | 13 ++++++++++++- 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/web/modules/mof/src/Form/ModelSearchForm.php b/web/modules/mof/src/Form/ModelSearchForm.php index 13745ab..ed62f0c 100644 --- a/web/modules/mof/src/Form/ModelSearchForm.php +++ b/web/modules/mof/src/Form/ModelSearchForm.php @@ -30,11 +30,9 @@ public function getFormId() { /** * {@inheritdoc} */ - public function buildForm(array $form, FormStateInterface $form_state, string $collection_name = NULL) { + public function buildForm(array $form, FormStateInterface $form_state) { $req = $this->request; - $form['collection'] = $collection_name; - $form['search'] = [ '#type' => 'details', '#title' => $this->t('Search filters'), @@ -95,14 +93,14 @@ public function submitForm(array &$form, FormStateInterface $form_state) { unset($query['org']); } - $form_state->setRedirect($form['collection'], $query); + $form_state->setRedirect($this->request->attributes->get('_route'), $query); } /** * Reset the form. */ public function resetForm(array $form, FormStateInterface $form_state) { - $form_state->setRedirect($form['collection']); + $form_state->setRedirect($this->request->attributes->get('_route')); } } diff --git a/web/modules/mof/src/ModelAdminListBuilder.php b/web/modules/mof/src/ModelAdminListBuilder.php index 4d20422..faf0908 100644 --- a/web/modules/mof/src/ModelAdminListBuilder.php +++ b/web/modules/mof/src/ModelAdminListBuilder.php @@ -153,12 +153,23 @@ public function render(): array|RedirectResponse { $build = parent::render(); $build['#attached']['library'][] = 'mof/model-list'; - $build['search'] = $this->formBuilder->getForm('\Drupal\mof\Form\ModelSearchForm', 'entity.model.admin_collection'); + $build['search'] = $this->formBuilder->getForm('\Drupal\mof\Form\ModelSearchForm'); $build['search']['#weight'] = -100; $build['table']['#attributes']['class'][] = 'tablesaw'; $build['table']['#attributes']['class'][] = 'tablesaw-stack'; $build['table']['#attributes']['data-tablesaw-mode'] = 'stack'; + $build['#cache'] = [ + 'contexts' => [ + 'url.query_args:label', + 'url.query_args:org', + 'url.query_args:page', + 'url.query_args:limit', + 'url.query_args:sort', + 'url.query_args:order', + ], + ]; + return $build; } diff --git a/web/modules/mof/src/ModelListBuilder.php b/web/modules/mof/src/ModelListBuilder.php index ee854cc..9ee47ad 100644 --- a/web/modules/mof/src/ModelListBuilder.php +++ b/web/modules/mof/src/ModelListBuilder.php @@ -71,12 +71,23 @@ public function render(): array|RedirectResponse { $build = parent::render(); $build['#attached']['library'][] = 'mof/model-list'; - $build['search'] = $this->formBuilder->getForm('\Drupal\mof\Form\ModelSearchForm', 'entity.model.collection'); + $build['search'] = $this->formBuilder->getForm('\Drupal\mof\Form\ModelSearchForm'); $build['search']['#weight'] = -100; $build['table']['#attributes']['class'][] = 'tablesaw'; $build['table']['#attributes']['class'][] = 'tablesaw-stack'; $build['table']['#attributes']['data-tablesaw-mode'] = 'stack'; + $build['#cache'] = [ + 'contexts' => [ + 'url.query_args:label', + 'url.query_args:org', + 'url.query_args:page', + 'url.query_args:limit', + 'url.query_args:sort', + 'url.query_args:order', + ], + ]; + return $build; }