Merge pull request #1 from Part-DB/master

pull master
This commit is contained in:
d-buchmann 2023-11-10 08:10:51 +01:00 committed by GitHub
commit 6c77661d57
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
63 changed files with 1395 additions and 904 deletions

View file

@ -57,7 +57,7 @@ jobs:
${{ runner.os }}-yarn- ${{ runner.os }}-yarn-
- name: Setup node - name: Setup node
uses: actions/setup-node@v3 uses: actions/setup-node@v4
with: with:
node-version: '18' node-version: '18'

View file

@ -87,7 +87,7 @@ jobs:
run: composer install --prefer-dist --no-progress run: composer install --prefer-dist --no-progress
- name: Setup node - name: Setup node
uses: actions/setup-node@v3 uses: actions/setup-node@v4
with: with:
node-version: '18' node-version: '18'

View file

@ -9,7 +9,7 @@
![Docker Build Status](https://github.com/Part-DB/Part-DB-symfony/workflows/Docker%20Image%20Build/badge.svg) ![Docker Build Status](https://github.com/Part-DB/Part-DB-symfony/workflows/Docker%20Image%20Build/badge.svg)
[![Crowdin](https://badges.crowdin.net/e/8325196085d4bee8c04b75f7c915452a/localized.svg)](https://part-db.crowdin.com/part-db) [![Crowdin](https://badges.crowdin.net/e/8325196085d4bee8c04b75f7c915452a/localized.svg)](https://part-db.crowdin.com/part-db)
**[Documentation](https://docs.part-db.de/)** | **[Demo](https://part-db.herokuapp.com)** | **[Docker Image](https://hub.docker.com/r/jbtronics/part-db1)** **[Documentation](https://docs.part-db.de/)** | **[Demo](https://demo.part-db.de/)** | **[Docker Image](https://hub.docker.com/r/jbtronics/part-db1)**
# Part-DB # Part-DB
@ -24,8 +24,8 @@ for everybody.
## Demo ## Demo
If you want to test Part-DB without installing it, you can use [this](https://part-db.herokuapp.com) Heroku instance. If you want to test Part-DB without installing it, you can use [this](https://demo.part-db.de/) Heroku instance.
(Or this link for the [German Version](https://part-db.herokuapp.com/de/)). (Or this link for the [German Version](https://demo.part-db.de/de/)).
You can log in with username: *user* and password: *user*. You can log in with username: *user* and password: *user*.
@ -101,24 +101,20 @@ for a detailed guide how to install Part-DB.**
In bigger instances with concurrent accesses, MySQL is more performant. This can not be changed easily later, so In bigger instances with concurrent accesses, MySQL is more performant. This can not be changed easily later, so
choose wisely. choose wisely.
4. Install composer dependencies and generate autoload files: `composer install -o --no-dev` 4. Install composer dependencies and generate autoload files: `composer install -o --no-dev`
5. If you have put Part-DB into a subdirectory on your server (like `part-db/`), you have to edit the file 5. Install client side dependencies and build it: `yarn install` and `yarn build`
`webpack.config.js` and uncomment the lines (remove the `//` before the lines) `.setPublicPath('/part-db/build')` ( 6. _Optional_ (speeds up first load): Warmup cache: `php bin/console cache:warmup`
line 43) and 7. Upgrade database to new scheme (or create it, when it was empty): `php bin/console doctrine:migrations:migrate` and
`.setManifestKeyPrefix('build/')` (line 44). You have to replace `/part-db` with your own path on line 44.
6. Install client side dependencies and build it: `yarn install` and `yarn build`
7. _Optional_ (speeds up first load): Warmup cache: `php bin/console cache:warmup`
8. Upgrade database to new scheme (or create it, when it was empty): `php bin/console doctrine:migrations:migrate` and
follow the instructions given. During the process the password for the admin is user is shown. Copy it. **Caution**: follow the instructions given. During the process the password for the admin is user is shown. Copy it. **Caution**:
This steps tamper with your database and could potentially destroy it. So make sure to make a backup of your This steps tamper with your database and could potentially destroy it. So make sure to make a backup of your
database. database.
9. You can configure Part-DB via `config/parameters.yaml`. You should check if settings match your expectations, after 8. You can configure Part-DB via `config/parameters.yaml`. You should check if settings match your expectations, after
you installed/upgraded Part-DB. Check if `partdb.default_currency` matches your mainly used currency (this can not be you installed/upgraded Part-DB. Check if `partdb.default_currency` matches your mainly used currency (this can not be
changed after creating price information). changed after creating price information).
Run `php bin/console cache:clear` when you changed something. Run `php bin/console cache:clear` when you changed something.
10. Access Part-DB in your browser (under the URL you put it) and login with user *admin*. Password is the one outputted 9. Access Part-DB in your browser (under the URL you put it) and login with user *admin*. Password is the one outputted
during DB setup. during DB setup.
If you can not remember the password, set a new one with `php bin/console app:set-password admin`. You can create If you can not remember the password, set a new one with `php bin/console app:set-password admin`. You can create
new users with the admin user and start using Part-DB. new users with the admin user and start using Part-DB.
When you want to upgrade to a newer version, then just copy the new files into the folder When you want to upgrade to a newer version, then just copy the new files into the folder
and repeat the steps 4. to 7. and repeat the steps 4. to 7.

View file

@ -1 +1 @@
1.8.1 1.9.0-dev

View file

@ -85,6 +85,9 @@ const PLACEHOLDERS = [
['[[COMMENT_T]]', 'Comment (plain text)'], ['[[COMMENT_T]]', 'Comment (plain text)'],
['[[LAST_MODIFIED]]', 'Last modified datetime'], ['[[LAST_MODIFIED]]', 'Last modified datetime'],
['[[CREATION_DATE]]', 'Creation datetime'], ['[[CREATION_DATE]]', 'Creation datetime'],
['[[IPN_BARCODE_QR]]', 'IPN as QR code'],
['[[IPN_BARCODE_C128]]', 'IPN as Code 128 barcode'],
['[[IPN_BARCODE_C39]]', 'IPN as Code 39 barcode'],
] ]
}, },
{ {

View file

@ -48,6 +48,9 @@ Object.assign( window.CKEDITOR_TRANSLATIONS[ 'de' ].dictionary, {
'Comment (plain text)': 'Kommentar (Nur-Text)', 'Comment (plain text)': 'Kommentar (Nur-Text)',
'Last modified datetime': 'Zuletzt geändert', 'Last modified datetime': 'Zuletzt geändert',
'Creation datetime': 'Erstellt', 'Creation datetime': 'Erstellt',
'IPN as QR code': 'IPN als QR Code',
'IPN as Code 128 barcode': 'IPN als Code 128 Barcode',
'IPN as Code 39 barcode': 'IPN als Code 39 Barcode',
'Lot ID': 'Lot ID', 'Lot ID': 'Lot ID',
'Lot name': 'Lot Name', 'Lot name': 'Lot Name',

View file

@ -4,6 +4,13 @@
use App\Kernel; use App\Kernel;
use Symfony\Bundle\FrameworkBundle\Console\Application; use Symfony\Bundle\FrameworkBundle\Console\Application;
//Increase xdebug.max_nesting_level to 1000 if required (see issue #411)
//Check if xdebug extension is active, and xdebug.max_nesting_level is set to 256 or lower
if (extension_loaded('xdebug') && ((int) ini_get('xdebug.max_nesting_level')) <= 256) {
//Increase xdebug.max_nesting_level to 1000
ini_set('xdebug.max_nesting_level', '1000');
}
if (!is_file(dirname(__DIR__).'/vendor/autoload_runtime.php')) { if (!is_file(dirname(__DIR__).'/vendor/autoload_runtime.php')) {
throw new LogicException('Symfony Runtime is missing. Try running "composer require symfony/runtime".'); throw new LogicException('Symfony Runtime is missing. Try running "composer require symfony/runtime".');
} }

View file

@ -70,6 +70,7 @@
"symfony/runtime": "6.3.*", "symfony/runtime": "6.3.*",
"symfony/security-bundle": "6.3.*", "symfony/security-bundle": "6.3.*",
"symfony/serializer": "6.3.*", "symfony/serializer": "6.3.*",
"symfony/string": "6.3.*",
"symfony/translation": "6.3.*", "symfony/translation": "6.3.*",
"symfony/twig-bundle": "6.3.*", "symfony/twig-bundle": "6.3.*",
"symfony/ux-translator": "^2.10", "symfony/ux-translator": "^2.10",

708
composer.lock generated

File diff suppressed because it is too large Load diff

View file

@ -8,6 +8,8 @@ api_platform:
# eager_loading: # eager_loading:
# max_joins: 100 # max_joins: 100
keep_legacy_inflector: false
swagger: swagger:
api_keys: api_keys:
# overridden in OpenApiFactoryDecorator # overridden in OpenApiFactoryDecorator

View file

@ -12,8 +12,8 @@ It is installed on a web server and so can be accessed with any browser without
{: .important-title } {: .important-title }
> Demo > Demo
> >
> If you want to test Part-DB without installing it, you can use [this](https://part-db.herokuapp.com) Heroku instance. > If you want to test Part-DB without installing it, you can use [this](https://demo.part-db.de/) Heroku instance.
> (Or this link for the [German Version](https://part-db.herokuapp.com/de/)). > (Or this link for the [German Version](https://demo.part-db.de/de/)).
> >
> You can log in with username: **user** and password: **user**, to change/create data. > You can log in with username: **user** and password: **user**, to change/create data.
> >

View file

@ -150,6 +150,7 @@ services:
database: database:
container_name: partdb_database container_name: partdb_database
image: mysql:8.0 image: mysql:8.0
restart: unless-stopped
command: --default-authentication-plugin=mysql_native_password command: --default-authentication-plugin=mysql_native_password
environment: environment:
# Change this Password # Change this Password

View file

@ -160,7 +160,7 @@ EOD;
21840,21840,21840,21840,21840,21520,21520,21520,20480,21520,20480, 21840,21840,21840,21840,21840,21520,21520,21520,20480,21520,20480,
20480,20480,20480,20480,21504,20480), 20480,20480,20480,20480,21504,20480),
( (
2,'admin', '${admin_pw}','','', 2,'admin', '$admin_pw','','',
'','',1,1,21845,21845,21845,21,85,21,349525,21845,21845,21845,21845 '','',1,1,21845,21845,21845,21,85,21,349525,21845,21845,21845,21845
,21845,21845,21845,21845,21845,21845,21845,21845,21845,21845,21845, ,21845,21845,21845,21845,21845,21845,21845,21845,21845,21845,21845,
21845,21845,21845,21845,21845,21845); 21845,21845,21845,21845,21845,21845);

View file

@ -234,8 +234,8 @@ final class Version20190902140506 extends AbstractMultiPlatformMigration
'orderdetails', 'pricedetails', 'storelocations', 'suppliers', ]; 'orderdetails', 'pricedetails', 'storelocations', 'suppliers', ];
foreach ($tables as $table) { foreach ($tables as $table) {
$this->addSql("UPDATE ${table} SET datetime_added = NOW() WHERE datetime_added = '0000-00-00 00:00:00'"); $this->addSql("UPDATE $table SET datetime_added = NOW() WHERE datetime_added = '0000-00-00 00:00:00'");
$this->addSql("UPDATE ${table} SET last_modified = datetime_added WHERE last_modified = '0000-00-00 00:00:00'"); $this->addSql("UPDATE $table SET last_modified = datetime_added WHERE last_modified = '0000-00-00 00:00:00'");
} }
//Set the dbVersion to a high value, to prevent the old Part-DB versions to upgrade DB! //Set the dbVersion to a high value, to prevent the old Part-DB versions to upgrade DB!

View file

@ -26,7 +26,7 @@ parameters:
checkUninitializedProperties: true checkUninitializedProperties: true
checkFunctionNameCase: true checkFunctionNameCase: false
checkAlwaysTrueInstanceof: false checkAlwaysTrueInstanceof: false
checkAlwaysTrueCheckTypeFunctionCall: false checkAlwaysTrueCheckTypeFunctionCall: false

View file

@ -26,6 +26,7 @@ namespace App\ApiResource;
use ApiPlatform\Metadata\ApiFilter; use ApiPlatform\Metadata\ApiFilter;
use ApiPlatform\Metadata\ApiResource; use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Get; use ApiPlatform\Metadata\Get;
use ApiPlatform\OpenApi\Model\Operation;
use ApiPlatform\Serializer\Filter\PropertyFilter; use ApiPlatform\Serializer\Filter\PropertyFilter;
use App\State\PartDBInfoProvider; use App\State\PartDBInfoProvider;
@ -35,7 +36,7 @@ use App\State\PartDBInfoProvider;
#[ApiResource( #[ApiResource(
uriTemplate: '/info.{_format}', uriTemplate: '/info.{_format}',
description: 'Basic information about Part-DB like version, title, etc.', description: 'Basic information about Part-DB like version, title, etc.',
operations: [new Get(openapiContext: ['summary' => 'Get basic information about the installed Part-DB instance.'])], operations: [new Get(openapi: new Operation(summary: 'Get basic information about the installed Part-DB instance.'))],
provider: PartDBInfoProvider::class provider: PartDBInfoProvider::class
)] )]
#[ApiFilter(PropertyFilter::class)] #[ApiFilter(PropertyFilter::class)]

View file

@ -42,8 +42,10 @@ declare(strict_types=1);
namespace App\Controller; namespace App\Controller;
use App\Form\LabelSystem\ScanDialogType; use App\Form\LabelSystem\ScanDialogType;
use App\Services\LabelSystem\Barcodes\BarcodeNormalizer; use App\Services\LabelSystem\Barcodes\BarcodeScanHelper;
use App\Services\LabelSystem\Barcodes\BarcodeRedirector; use App\Services\LabelSystem\Barcodes\BarcodeRedirector;
use App\Services\LabelSystem\Barcodes\BarcodeScanResult;
use App\Services\LabelSystem\Barcodes\BarcodeSourceType;
use Doctrine\ORM\EntityNotFoundException; use Doctrine\ORM\EntityNotFoundException;
use InvalidArgumentException; use InvalidArgumentException;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
@ -55,7 +57,7 @@ use Symfony\Component\Routing\Annotation\Route;
#[Route(path: '/scan')] #[Route(path: '/scan')]
class ScanController extends AbstractController class ScanController extends AbstractController
{ {
public function __construct(protected BarcodeRedirector $barcodeParser, protected BarcodeNormalizer $barcodeNormalizer) public function __construct(protected BarcodeRedirector $barcodeParser, protected BarcodeScanHelper $barcodeNormalizer)
{ {
} }
@ -73,10 +75,9 @@ class ScanController extends AbstractController
if ($input !== null) { if ($input !== null) {
try { try {
[$type, $id] = $this->barcodeNormalizer->normalizeBarcodeContent($input); $scan_result = $this->barcodeNormalizer->scanBarcodeContent($input);
try { try {
return $this->redirect($this->barcodeParser->getRedirectURL($type, $id)); return $this->redirect($this->barcodeParser->getRedirectURL($scan_result));
} catch (EntityNotFoundException) { } catch (EntityNotFoundException) {
$this->addFlash('success', 'scan.qr_not_found'); $this->addFlash('success', 'scan.qr_not_found');
} }
@ -95,10 +96,23 @@ class ScanController extends AbstractController
*/ */
public function scanQRCode(string $type, int $id): Response public function scanQRCode(string $type, int $id): Response
{ {
$type = strtolower($type);
try { try {
$this->addFlash('success', 'scan.qr_success'); $this->addFlash('success', 'scan.qr_success');
return $this->redirect($this->barcodeParser->getRedirectURL($type, $id)); if (!isset(BarcodeScanHelper::QR_TYPE_MAP[$type])) {
throw new InvalidArgumentException('Unknown type: '.$type);
}
//Construct the scan result manually, as we don't have a barcode here
$scan_result = new BarcodeScanResult(
target_type: BarcodeScanHelper::QR_TYPE_MAP[$type],
target_id: $id,
//The routes are only used on the internal generated QR codes
source_type: BarcodeSourceType::INTERNAL
);
return $this->redirect($this->barcodeParser->getRedirectURL($scan_result));
} catch (EntityNotFoundException) { } catch (EntityNotFoundException) {
$this->addFlash('success', 'scan.qr_not_found'); $this->addFlash('success', 'scan.qr_not_found');

View file

@ -100,7 +100,16 @@ class ProjectBomEntriesDataTable implements DataTableTypeInterface
throw new \Exception('This should never happen!'); throw new \Exception('This should never happen!');
}, },
]) ])
->add('ipn', TextColumn::class, [
'label' => $this->translator->trans('part.table.ipn'),
'orderField' => 'part.ipn',
'visible' => false,
'render' => function ($value, ProjectBOMEntry $context) {
if($context->getPart() instanceof Part) {
return $context->getPart()->getIpn();
}
}
])
->add('description', MarkdownColumn::class, [ ->add('description', MarkdownColumn::class, [
'label' => $this->translator->trans('part.table.description'), 'label' => $this->translator->trans('part.table.description'),
'data' => function (ProjectBOMEntry $context) { 'data' => function (ProjectBOMEntry $context) {

View file

@ -36,7 +36,7 @@ class Field2 extends FunctionNode
private $values = []; private $values = [];
public function parse(\Doctrine\ORM\Query\Parser $parser) public function parse(\Doctrine\ORM\Query\Parser $parser): void
{ {
$parser->match(Lexer::T_IDENTIFIER); $parser->match(Lexer::T_IDENTIFIER);
$parser->match(Lexer::T_OPEN_PARENTHESIS); $parser->match(Lexer::T_OPEN_PARENTHESIS);
@ -58,7 +58,7 @@ class Field2 extends FunctionNode
$parser->match(Lexer::T_CLOSE_PARENTHESIS); $parser->match(Lexer::T_CLOSE_PARENTHESIS);
} }
public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker) public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker): string
{ {
$query = 'FIELD2('; $query = 'FIELD2(';

View file

@ -33,6 +33,7 @@ use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\Link; use ApiPlatform\Metadata\Link;
use ApiPlatform\Metadata\Patch; use ApiPlatform\Metadata\Patch;
use ApiPlatform\Metadata\Post; use ApiPlatform\Metadata\Post;
use ApiPlatform\OpenApi\Model\Operation;
use ApiPlatform\Serializer\Filter\PropertyFilter; use ApiPlatform\Serializer\Filter\PropertyFilter;
use App\ApiPlatform\Filter\LikeFilter; use App\ApiPlatform\Filter\LikeFilter;
use App\Entity\Parts\Footprint; use App\Entity\Parts\Footprint;
@ -70,7 +71,7 @@ use Symfony\Component\Validator\Constraints as Assert;
#[ApiResource( #[ApiResource(
uriTemplate: '/attachment_types/{id}/children.{_format}', uriTemplate: '/attachment_types/{id}/children.{_format}',
operations: [ operations: [
new GetCollection(openapiContext: ['summary' => 'Retrieves the children elements of an attachment type.'], new GetCollection(openapi: new Operation(summary: 'Retrieves the children elements of an attachment type.'),
security: 'is_granted("@attachment_types.read")') security: 'is_granted("@attachment_types.read")')
], ],
uriVariables: [ uriVariables: [

View file

@ -135,17 +135,17 @@ class OAuthToken extends AbstractNamedDBElement implements AccessTokenInterface
$this->expires_at = self::unixTimestampToDatetime($accessToken->getExpires() ?? time() + self::DEFAULT_EXPIRATION_TIME); $this->expires_at = self::unixTimestampToDatetime($accessToken->getExpires() ?? time() + self::DEFAULT_EXPIRATION_TIME);
} }
public function getExpires() public function getExpires(): ?int
{ {
return $this->expires_at->getTimestamp(); return $this->expires_at->getTimestamp();
} }
public function hasExpired() public function hasExpired(): bool
{ {
return $this->isExpired(); return $this->isExpired();
} }
public function getValues() public function getValues(): array
{ {
return []; return [];
} }

View file

@ -34,6 +34,7 @@ use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\Link; use ApiPlatform\Metadata\Link;
use ApiPlatform\Metadata\Patch; use ApiPlatform\Metadata\Patch;
use ApiPlatform\Metadata\Post; use ApiPlatform\Metadata\Post;
use ApiPlatform\OpenApi\Model\Operation;
use ApiPlatform\Serializer\Filter\PropertyFilter; use ApiPlatform\Serializer\Filter\PropertyFilter;
use App\ApiPlatform\Filter\LikeFilter; use App\ApiPlatform\Filter\LikeFilter;
use App\Entity\Attachments\Attachment; use App\Entity\Attachments\Attachment;
@ -72,8 +73,10 @@ use Symfony\Component\Validator\Constraints as Assert;
#[ApiResource( #[ApiResource(
uriTemplate: '/categories/{id}/children.{_format}', uriTemplate: '/categories/{id}/children.{_format}',
operations: [ operations: [
new GetCollection(openapiContext: ['summary' => 'Retrieves the children elements of a category.'], new GetCollection(
security: 'is_granted("@categories.read")') openapi: new Operation(summary: 'Retrieves the children elements of a category.'),
security: 'is_granted("@categories.read")'
)
], ],
uriVariables: [ uriVariables: [
'id' => new Link(fromProperty: 'children', fromClass: Category::class) 'id' => new Link(fromProperty: 'children', fromClass: Category::class)

View file

@ -34,6 +34,7 @@ use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\Link; use ApiPlatform\Metadata\Link;
use ApiPlatform\Metadata\Patch; use ApiPlatform\Metadata\Patch;
use ApiPlatform\Metadata\Post; use ApiPlatform\Metadata\Post;
use ApiPlatform\OpenApi\Model\Operation;
use ApiPlatform\Serializer\Filter\PropertyFilter; use ApiPlatform\Serializer\Filter\PropertyFilter;
use App\ApiPlatform\Filter\LikeFilter; use App\ApiPlatform\Filter\LikeFilter;
use App\Entity\Attachments\Attachment; use App\Entity\Attachments\Attachment;
@ -72,8 +73,10 @@ use Symfony\Component\Validator\Constraints as Assert;
#[ApiResource( #[ApiResource(
uriTemplate: '/footprints/{id}/children.{_format}', uriTemplate: '/footprints/{id}/children.{_format}',
operations: [ operations: [
new GetCollection(openapiContext: ['summary' => 'Retrieves the children elements of a footprint.'], new GetCollection(
security: 'is_granted("@footprints.read")') openapi: new Operation(summary: 'Retrieves the children elements of a footprint.'),
security: 'is_granted("@footprints.read")'
)
], ],
uriVariables: [ uriVariables: [
'id' => new Link(fromProperty: 'children', fromClass: Footprint::class) 'id' => new Link(fromProperty: 'children', fromClass: Footprint::class)

View file

@ -33,6 +33,7 @@ use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\Link; use ApiPlatform\Metadata\Link;
use ApiPlatform\Metadata\Patch; use ApiPlatform\Metadata\Patch;
use ApiPlatform\Metadata\Post; use ApiPlatform\Metadata\Post;
use ApiPlatform\OpenApi\Model\Operation;
use ApiPlatform\Serializer\Filter\PropertyFilter; use ApiPlatform\Serializer\Filter\PropertyFilter;
use App\ApiPlatform\Filter\LikeFilter; use App\ApiPlatform\Filter\LikeFilter;
use App\Entity\Attachments\Attachment; use App\Entity\Attachments\Attachment;
@ -71,8 +72,10 @@ use Symfony\Component\Validator\Constraints as Assert;
#[ApiResource( #[ApiResource(
uriTemplate: '/manufacturers/{id}/children.{_format}', uriTemplate: '/manufacturers/{id}/children.{_format}',
operations: [ operations: [
new GetCollection(openapiContext: ['summary' => 'Retrieves the children elements of a manufacturer.'], new GetCollection(
security: 'is_granted("@manufacturers.read")') openapi: new Operation(summary: 'Retrieves the children elements of a manufacturer.'),
security: 'is_granted("@manufacturers.read")'
)
], ],
uriVariables: [ uriVariables: [
'id' => new Link(fromProperty: 'children', fromClass: Manufacturer::class) 'id' => new Link(fromProperty: 'children', fromClass: Manufacturer::class)

View file

@ -33,6 +33,7 @@ use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\Link; use ApiPlatform\Metadata\Link;
use ApiPlatform\Metadata\Patch; use ApiPlatform\Metadata\Patch;
use ApiPlatform\Metadata\Post; use ApiPlatform\Metadata\Post;
use ApiPlatform\OpenApi\Model\Operation;
use ApiPlatform\Serializer\Filter\PropertyFilter; use ApiPlatform\Serializer\Filter\PropertyFilter;
use App\ApiPlatform\Filter\LikeFilter; use App\ApiPlatform\Filter\LikeFilter;
use App\Entity\Attachments\Attachment; use App\Entity\Attachments\Attachment;
@ -75,8 +76,10 @@ use Symfony\Component\Validator\Constraints as Assert;
#[ApiResource( #[ApiResource(
uriTemplate: '/footprints/{id}/children.{_format}', uriTemplate: '/footprints/{id}/children.{_format}',
operations: [ operations: [
new GetCollection(openapiContext: ['summary' => 'Retrieves the children elements of a MeasurementUnit.'], new GetCollection(
security: 'is_granted("@measurement_units.read")') openapi: new Operation(summary: 'Retrieves the children elements of a MeasurementUnit.'),
security: 'is_granted("@measurement_units.read")'
)
], ],
uriVariables: [ uriVariables: [
'id' => new Link(fromProperty: 'children', fromClass: MeasurementUnit::class) 'id' => new Link(fromProperty: 'children', fromClass: MeasurementUnit::class)

View file

@ -33,6 +33,7 @@ use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\Link; use ApiPlatform\Metadata\Link;
use ApiPlatform\Metadata\Patch; use ApiPlatform\Metadata\Patch;
use ApiPlatform\Metadata\Post; use ApiPlatform\Metadata\Post;
use ApiPlatform\OpenApi\Model\Operation;
use ApiPlatform\Serializer\Filter\PropertyFilter; use ApiPlatform\Serializer\Filter\PropertyFilter;
use App\ApiPlatform\Filter\LikeFilter; use App\ApiPlatform\Filter\LikeFilter;
use App\Entity\Attachments\Attachment; use App\Entity\Attachments\Attachment;
@ -71,8 +72,10 @@ use Symfony\Component\Validator\Constraints as Assert;
#[ApiResource( #[ApiResource(
uriTemplate: '/storage_locations/{id}/children.{_format}', uriTemplate: '/storage_locations/{id}/children.{_format}',
operations: [ operations: [
new GetCollection(openapiContext: ['summary' => 'Retrieves the children elements of a storage location.'], new GetCollection(
security: 'is_granted("@storelocations.read")') openapi: new Operation(summary: 'Retrieves the children elements of a storage location.'),
security: 'is_granted("@storelocations.read")'
)
], ],
uriVariables: [ uriVariables: [
'id' => new Link(fromProperty: 'children', fromClass: Manufacturer::class) 'id' => new Link(fromProperty: 'children', fromClass: Manufacturer::class)

View file

@ -33,6 +33,7 @@ use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\Link; use ApiPlatform\Metadata\Link;
use ApiPlatform\Metadata\Patch; use ApiPlatform\Metadata\Patch;
use ApiPlatform\Metadata\Post; use ApiPlatform\Metadata\Post;
use ApiPlatform\OpenApi\Model\Operation;
use ApiPlatform\Serializer\Filter\PropertyFilter; use ApiPlatform\Serializer\Filter\PropertyFilter;
use App\ApiPlatform\Filter\LikeFilter; use App\ApiPlatform\Filter\LikeFilter;
use App\Entity\Attachments\Attachment; use App\Entity\Attachments\Attachment;
@ -75,8 +76,10 @@ use Symfony\Component\Validator\Constraints as Assert;
)] )]
#[ApiResource( #[ApiResource(
uriTemplate: '/suppliers/{id}/children.{_format}', uriTemplate: '/suppliers/{id}/children.{_format}',
operations: [new GetCollection(openapiContext: ['summary' => 'Retrieves the children elements of a supplier'], operations: [new GetCollection(
security: 'is_granted("@manufacturers.read")')], openapi: new Operation(summary: 'Retrieves the children elements of a supplier.'),
security: 'is_granted("@manufacturers.read")'
)],
uriVariables: [ uriVariables: [
'id' => new Link(fromClass: Supplier::class, fromProperty: 'children') 'id' => new Link(fromClass: Supplier::class, fromProperty: 'children')
], ],

View file

@ -33,6 +33,7 @@ use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\Link; use ApiPlatform\Metadata\Link;
use ApiPlatform\Metadata\Patch; use ApiPlatform\Metadata\Patch;
use ApiPlatform\Metadata\Post; use ApiPlatform\Metadata\Post;
use ApiPlatform\OpenApi\Model\Operation;
use ApiPlatform\Serializer\Filter\PropertyFilter; use ApiPlatform\Serializer\Filter\PropertyFilter;
use App\ApiPlatform\Filter\LikeFilter; use App\ApiPlatform\Filter\LikeFilter;
use App\Entity\Attachments\Attachment; use App\Entity\Attachments\Attachment;
@ -75,8 +76,10 @@ use Symfony\Component\Validator\Constraints as Assert;
#[ApiResource( #[ApiResource(
uriTemplate: '/currencies/{id}/children.{_format}', uriTemplate: '/currencies/{id}/children.{_format}',
operations: [ operations: [
new GetCollection(openapiContext: ['summary' => 'Retrieves the children elements of a currency.'], new GetCollection(
security: 'is_granted("@currencies.read")') openapi: new Operation(summary: 'Retrieves the children elements of a currency.'),
security: 'is_granted("@currencies.read")'
)
], ],
uriVariables: [ uriVariables: [
'id' => new Link(fromProperty: 'children', fromClass: Currency::class) 'id' => new Link(fromProperty: 'children', fromClass: Currency::class)

View file

@ -34,6 +34,7 @@ use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\Link; use ApiPlatform\Metadata\Link;
use ApiPlatform\Metadata\Patch; use ApiPlatform\Metadata\Patch;
use ApiPlatform\Metadata\Post; use ApiPlatform\Metadata\Post;
use ApiPlatform\OpenApi\Model\Operation;
use ApiPlatform\Serializer\Filter\PropertyFilter; use ApiPlatform\Serializer\Filter\PropertyFilter;
use App\ApiPlatform\Filter\LikeFilter; use App\ApiPlatform\Filter\LikeFilter;
use Doctrine\DBAL\Types\Types; use Doctrine\DBAL\Types\Types;
@ -73,8 +74,10 @@ use Symfony\Component\Validator\Constraints as Assert;
#[ApiResource( #[ApiResource(
uriTemplate: '/parts/{id}/orderdetails.{_format}', uriTemplate: '/parts/{id}/orderdetails.{_format}',
operations: [ operations: [
new GetCollection(openapiContext: ['summary' => 'Retrieves the orderdetails of a part.'], new GetCollection(
security: 'is_granted("@parts.read")') openapi: new Operation(summary: 'Retrieves the orderdetails of a part.'),
security: 'is_granted("@parts.read")'
)
], ],
uriVariables: [ uriVariables: [
'id' => new Link(toProperty: 'part', fromClass: Part::class) 'id' => new Link(toProperty: 'part', fromClass: Part::class)

View file

@ -33,6 +33,7 @@ use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\Link; use ApiPlatform\Metadata\Link;
use ApiPlatform\Metadata\Patch; use ApiPlatform\Metadata\Patch;
use ApiPlatform\Metadata\Post; use ApiPlatform\Metadata\Post;
use ApiPlatform\OpenApi\Model\Operation;
use ApiPlatform\Serializer\Filter\PropertyFilter; use ApiPlatform\Serializer\Filter\PropertyFilter;
use App\ApiPlatform\Filter\LikeFilter; use App\ApiPlatform\Filter\LikeFilter;
use App\Entity\Attachments\Attachment; use App\Entity\Attachments\Attachment;
@ -74,8 +75,10 @@ use Symfony\Component\Validator\Context\ExecutionContextInterface;
#[ApiResource( #[ApiResource(
uriTemplate: '/projects/{id}/children.{_format}', uriTemplate: '/projects/{id}/children.{_format}',
operations: [ operations: [
new GetCollection(openapiContext: ['summary' => 'Retrieves the children elements of a project.'], new GetCollection(
security: 'is_granted("@projects.read")') openapi: new Operation(summary: 'Retrieves the children elements of a project.'),
security: 'is_granted("@projects.read")'
)
], ],
uriVariables: [ uriVariables: [
'id' => new Link(fromProperty: 'children', fromClass: Project::class) 'id' => new Link(fromProperty: 'children', fromClass: Project::class)

View file

@ -32,6 +32,7 @@ use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\Link; use ApiPlatform\Metadata\Link;
use ApiPlatform\Metadata\Patch; use ApiPlatform\Metadata\Patch;
use ApiPlatform\Metadata\Post; use ApiPlatform\Metadata\Post;
use ApiPlatform\OpenApi\Model\Operation;
use ApiPlatform\Serializer\Filter\PropertyFilter; use ApiPlatform\Serializer\Filter\PropertyFilter;
use App\ApiPlatform\Filter\LikeFilter; use App\ApiPlatform\Filter\LikeFilter;
use App\Validator\UniqueValidatableInterface; use App\Validator\UniqueValidatableInterface;
@ -69,8 +70,10 @@ use Symfony\Component\Validator\Context\ExecutionContextInterface;
#[ApiResource( #[ApiResource(
uriTemplate: '/projects/{id}/bom.{_format}', uriTemplate: '/projects/{id}/bom.{_format}',
operations: [ operations: [
new GetCollection(openapiContext: ['summary' => 'Retrieves the BOM entries of the given project.'], new GetCollection(
security: 'is_granted("@projects.read")') openapi: new Operation(summary: 'Retrieves the BOM entries of the given project.'),
security: 'is_granted("@projects.read")'
)
], ],
uriVariables: [ uriVariables: [
'id' => new Link(fromProperty: 'bom_entries', fromClass: Project::class) 'id' => new Link(fromProperty: 'bom_entries', fromClass: Project::class)

View file

@ -26,6 +26,7 @@ namespace App\Entity\UserSystem;
use ApiPlatform\Metadata\ApiFilter; use ApiPlatform\Metadata\ApiFilter;
use ApiPlatform\Metadata\ApiResource; use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Get; use ApiPlatform\Metadata\Get;
use ApiPlatform\OpenApi\Model\Operation;
use ApiPlatform\Serializer\Filter\PropertyFilter; use ApiPlatform\Serializer\Filter\PropertyFilter;
use App\Entity\Base\AbstractNamedDBElement; use App\Entity\Base\AbstractNamedDBElement;
use App\Entity\Base\TimestampTrait; use App\Entity\Base\TimestampTrait;
@ -46,7 +47,9 @@ use Symfony\Component\Validator\Constraints\NotBlank;
#[ApiResource( #[ApiResource(
uriTemplate: '/tokens/current.{_format}', uriTemplate: '/tokens/current.{_format}',
description: 'A token used to authenticate API requests.', description: 'A token used to authenticate API requests.',
operations: [new Get(openapiContext: ['summary' => 'Get information about the API token that is currently used.'])], operations: [new Get(
openapi: new Operation(summary: 'Get information about the API token that is currently used.'),
)],
normalizationContext: ['groups' => ['token:read', 'api:basic:read'], 'openapi_definition_name' => 'Read'], normalizationContext: ['groups' => ['token:read', 'api:basic:read'], 'openapi_definition_name' => 'Read'],
provider: CurrentApiTokenProvider::class, provider: CurrentApiTokenProvider::class,
)] )]

View file

@ -31,6 +31,7 @@ use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Get; use ApiPlatform\Metadata\Get;
use ApiPlatform\Metadata\GetCollection; use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\Post; use ApiPlatform\Metadata\Post;
use ApiPlatform\OpenApi\Model\Operation;
use ApiPlatform\Serializer\Filter\PropertyFilter; use ApiPlatform\Serializer\Filter\PropertyFilter;
use App\ApiPlatform\Filter\LikeFilter; use App\ApiPlatform\Filter\LikeFilter;
use App\Entity\Attachments\Attachment; use App\Entity\Attachments\Attachment;
@ -86,10 +87,14 @@ use Jbtronics\TFAWebauthn\Model\TwoFactorInterface as WebauthnTwoFactorInterface
#[ApiResource( #[ApiResource(
shortName: 'User', shortName: 'User',
operations: [ operations: [
new Get(openapiContext: ['summary' => 'Get a specific user.'], new Get(
security: 'is_granted("read", object)'), openapi: new Operation(summary: 'Get information about the current user.'),
new GetCollection(openapiContext: ['summary' => 'Get all users defined in the system.'], security: 'is_granted("read", object)'
security: 'is_granted("@users.read")'), ),
new GetCollection(
openapi: new Operation(summary: 'Get all users defined in the system.'),
security: 'is_granted("@users.read")'
),
], ],
normalizationContext: ['groups' => ['user:read'], 'openapi_definition_name' => 'Read'], normalizationContext: ['groups' => ['user:read'], 'openapi_definition_name' => 'Read'],
)] )]

View file

@ -38,7 +38,7 @@ class SwitchUserEventSubscriber implements EventSubscriberInterface
{ {
} }
public static function getSubscribedEvents() public static function getSubscribedEvents(): array
{ {
return [ return [
'security.switch_user' => 'onSwitchUser', 'security.switch_user' => 'onSwitchUser',

View file

@ -0,0 +1,57 @@
<?php
/*
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
*
* Copyright (C) 2019 - 2023 Jan Böhmer (https://github.com/jbtronics)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace App\EventSubscriber;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\WebpackEncoreBundle\Event\RenderAssetTagEvent;
/**
* This class fixes the wrong pathes generated by webpack using the auto publicPath mode.
* Basically it replaces the wrong /auto/ part of the path with the correct /build/ in all encore entrypoints.
*/
class WebpackAutoPathSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents(): array
{
return [
RenderAssetTagEvent::class => 'onRenderAssetTag'
];
}
public function onRenderAssetTag(RenderAssetTagEvent $event): void
{
if ($event->isScriptTag()) {
$event->setAttribute('src', $this->resolveAuto($event->getUrl()));
}
if ($event->isLinkTag()) {
$event->setAttribute('href', $this->resolveAuto($event->getUrl()));
}
}
private function resolveAuto(string $path): string
{
//Replace the first occurence of /auto/ with /build/ to get the correct path
return preg_replace('/\/auto\//', '/build/', $path, 1);
}
}

View file

@ -43,7 +43,7 @@ class ProviderSelectType extends AbstractType
return ChoiceType::class; return ChoiceType::class;
} }
public function configureOptions(OptionsResolver $resolver) public function configureOptions(OptionsResolver $resolver): void
{ {
$resolver->setDefaults([ $resolver->setDefaults([
'choices' => $this->providerRegistry->getActiveProviders(), 'choices' => $this->providerRegistry->getActiveProviders(),

View file

@ -46,7 +46,7 @@ class PasswordTypeExtension extends AbstractTypeExtension
$resolver->setAllowedTypes('password_estimator', 'bool'); $resolver->setAllowedTypes('password_estimator', 'bool');
} }
public function finishView(FormView $view, FormInterface $form, array $options) public function finishView(FormView $view, FormInterface $form, array $options): void
{ {
$view->vars['password_estimator'] = $options['password_estimator']; $view->vars['password_estimator'] = $options['password_estimator'];
} }

View file

@ -35,7 +35,7 @@ use Symfony\Component\Validator\Constraints\NotNull;
class ProjectAddPartsType extends AbstractType class ProjectAddPartsType extends AbstractType
{ {
public function buildForm(FormBuilderInterface $builder, array $options) public function buildForm(FormBuilderInterface $builder, array $options): void
{ {
$builder->add('project', StructuralEntityType::class, [ $builder->add('project', StructuralEntityType::class, [
'class' => Project::class, 'class' => Project::class,
@ -73,7 +73,7 @@ class ProjectAddPartsType extends AbstractType
}); });
} }
public function configureOptions(OptionsResolver $resolver) public function configureOptions(OptionsResolver $resolver): void
{ {
$resolver->setDefaults([ $resolver->setDefaults([
'project' => null, 'project' => null,

View file

@ -40,7 +40,7 @@ class AttachmentNormalizer implements NormalizerInterface
} }
public function normalize(mixed $object, string $format = null, array $context = []) public function normalize(mixed $object, string $format = null, array $context = []): array|null
{ {
if (!$object instanceof Attachment) { if (!$object instanceof Attachment) {
throw new \InvalidArgumentException('This normalizer only supports Attachment objects!'); throw new \InvalidArgumentException('This normalizer only supports Attachment objects!');

View file

@ -58,7 +58,7 @@ class BigNumberNormalizer implements NormalizerInterface, DenormalizerInterface
]; ];
} }
public function denormalize(mixed $data, string $type, string $format = null, array $context = []) public function denormalize(mixed $data, string $type, string $format = null, array $context = []): BigNumber|null
{ {
if (!is_a($type, BigNumber::class, true)) { if (!is_a($type, BigNumber::class, true)) {
throw new \InvalidArgumentException('This normalizer only supports BigNumber objects!'); throw new \InvalidArgumentException('This normalizer only supports BigNumber objects!');
@ -67,7 +67,7 @@ class BigNumberNormalizer implements NormalizerInterface, DenormalizerInterface
return $type::of($data); return $type::of($data);
} }
public function supportsDenormalization(mixed $data, string $type, string $format = null) public function supportsDenormalization(mixed $data, string $type, string $format = null, array $context = []): bool
{ {
//data must be a string or a number (int, float, etc.) and the type must be BigNumber or BigDecimal //data must be a string or a number (int, float, etc.) and the type must be BigNumber or BigDecimal
return (is_string($data) || is_numeric($data)) && (is_subclass_of($type, BigNumber::class)); return (is_string($data) || is_numeric($data)) && (is_subclass_of($type, BigNumber::class));

View file

@ -41,6 +41,8 @@ class PriceDTO
public readonly ?string $currency_iso_code, public readonly ?string $currency_iso_code,
/** @var bool If the price includes tax */ /** @var bool If the price includes tax */
public readonly ?bool $includes_tax = true, public readonly ?bool $includes_tax = true,
/** @var float the price related quantity */
public readonly ?float $price_related_quantity = 1.0,
) )
{ {
$this->price_as_big_decimal = BigDecimal::of($this->price); $this->price_as_big_decimal = BigDecimal::of($this->price);
@ -54,4 +56,4 @@ class PriceDTO
{ {
return $this->price_as_big_decimal; return $this->price_as_big_decimal;
} }
} }

View file

@ -87,6 +87,7 @@ final class DTOtoEntityConverter
{ {
$entity->setMinDiscountQuantity($dto->minimum_discount_amount); $entity->setMinDiscountQuantity($dto->minimum_discount_amount);
$entity->setPrice($dto->getPriceAsBigDecimal()); $entity->setPrice($dto->getPriceAsBigDecimal());
$entity->setPriceRelatedQuantity($dto->price_related_quantity);
//Currency TODO //Currency TODO
if ($dto->currency_iso_code !== null) { if ($dto->currency_iso_code !== null) {
@ -95,7 +96,6 @@ final class DTOtoEntityConverter
$entity->setCurrency(null); $entity->setCurrency(null);
} }
return $entity; return $entity;
} }
@ -289,7 +289,7 @@ final class DTOtoEntityConverter
//If the entity was newly created, set the file filter //If the entity was newly created, set the file filter
if ($tmp->getID() === null) { if ($tmp->getID() === null) {
$tmp->setFiletypeFilter('image/*'); $tmp->setFiletypeFilter('image/*');
$tmp->setAlternativeNames(self::TYPE_DATASHEETS_NAME); $tmp->setAlternativeNames(self::TYPE_IMAGE_NAME);
} }
return $tmp; return $tmp;

View file

@ -76,11 +76,11 @@ final class BarcodeContentGenerator
{ {
$type = $this->classToString(self::URL_MAP, $target); $type = $this->classToString(self::URL_MAP, $target);
return $this->urlGenerator->generate('scan_qr', [ return $this->urlGenerator->generate('scan_qr', [
'type' => $type, 'type' => $type,
'id' => $target->getID() ?? 0, 'id' => $target->getID() ?? 0,
'_locale' => null, '_locale' => null,
], UrlGeneratorInterface::ABSOLUTE_URL); ], UrlGeneratorInterface::ABSOLUTE_URL);
} }
/** /**

View file

@ -0,0 +1,96 @@
<?php
/*
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
*
* Copyright (C) 2019 - 2023 Jan Böhmer (https://github.com/jbtronics)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace App\Services\LabelSystem\Barcodes;
use App\Entity\LabelSystem\BarcodeType;
use Com\Tecnick\Barcode\Barcode;
/**
* This function is used to generate barcodes of various types using arbitrary (text) content.
*/
class BarcodeHelper
{
/**
* Generates a barcode with the given content and type and returns it as SVG string.
* @param string $content
* @param BarcodeType $type
* @return string
*/
public function barcodeAsSVG(string $content, BarcodeType $type): string
{
$barcode = new Barcode();
$type_str = match ($type) {
BarcodeType::NONE => throw new \InvalidArgumentException('Barcode type must not be NONE! This would make no sense...'),
BarcodeType::QR => 'QRCODE',
BarcodeType::DATAMATRIX => 'DATAMATRIX',
BarcodeType::CODE39 => 'C39',
BarcodeType::CODE93 => 'C93',
BarcodeType::CODE128 => 'C128A',
};
return $barcode->getBarcodeObj($type_str, $content)->getSvgCode();
}
/**
* Generates a barcode with the given content and type and returns it as HTML image tag.
* @param string $content
* @param BarcodeType $type
* @param string $width Width of the image tag
* @param string|null $alt_text The alt text of the image tag. If null, the content is used.
* @return string
*/
public function barcodeAsHTML(string $content, BarcodeType $type, string $width = '100%', ?string $alt_text = null): string
{
$svg = $this->barcodeAsSVG($content, $type);
$base64 = $this->dataUri($svg, 'image/svg+xml');
$alt_text = $alt_text ?? $content;
return '<img src="'.$base64.'" width="'.$width.'" style="min-height: 25px;" alt="'.$alt_text.'"/>';
}
/**
* Creates a data URI (RFC 2397).
* Based on the Twig implementation from HTMLExtension
*
* Length validation is not performed on purpose, validation should
* be done before calling this filter.
*
* @return string The generated data URI
*/
private function dataUri(string $data, string $mime): string
{
$repr = 'data:';
$repr .= $mime;
if (str_starts_with($mime, 'text/')) {
$repr .= ','.rawurlencode($data);
} else {
$repr .= ';base64,'.base64_encode($data);
}
return $repr;
}
}

View file

@ -41,6 +41,7 @@ declare(strict_types=1);
namespace App\Services\LabelSystem\Barcodes; namespace App\Services\LabelSystem\Barcodes;
use App\Entity\LabelSystem\LabelSupportedElement;
use App\Entity\Parts\PartLot; use App\Entity\Parts\PartLot;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityNotFoundException; use Doctrine\ORM\EntityNotFoundException;
@ -59,32 +60,30 @@ final class BarcodeRedirector
/** /**
* Determines the URL to which the user should be redirected, when scanning a QR code. * Determines the URL to which the user should be redirected, when scanning a QR code.
* *
* @param string $type The type of the element that was scanned (e.g. 'part', 'lot', etc.) * @param BarcodeScanResult $barcodeScan The result of the barcode scan
* @param int $id The ID of the element that was scanned
*
* @return string the URL to which should be redirected * @return string the URL to which should be redirected
* *
* @throws EntityNotFoundException * @throws EntityNotFoundException
*/ */
public function getRedirectURL(string $type, int $id): string public function getRedirectURL(BarcodeScanResult $barcodeScan): string
{ {
switch ($type) { switch ($barcodeScan->target_type) {
case 'part': case LabelSupportedElement::PART:
return $this->urlGenerator->generate('app_part_show', ['id' => $id]); return $this->urlGenerator->generate('app_part_show', ['id' => $barcodeScan->target_id]);
case 'lot': case LabelSupportedElement::PART_LOT:
//Try to determine the part to the given lot //Try to determine the part to the given lot
$lot = $this->em->find(PartLot::class, $id); $lot = $this->em->find(PartLot::class, $barcodeScan->target_id);
if (!$lot instanceof PartLot) { if (!$lot instanceof PartLot) {
throw new EntityNotFoundException(); throw new EntityNotFoundException();
} }
return $this->urlGenerator->generate('app_part_show', ['id' => $lot->getPart()->getID()]); return $this->urlGenerator->generate('app_part_show', ['id' => $lot->getPart()->getID()]);
case 'location': case LabelSupportedElement::STORELOCATION:
return $this->urlGenerator->generate('part_list_store_location', ['id' => $id]); return $this->urlGenerator->generate('part_list_store_location', ['id' => $barcodeScan->target_id]);
default: default:
throw new InvalidArgumentException('Unknown $type: '.$type); throw new InvalidArgumentException('Unknown $type: '.$barcodeScan->target_type->name);
} }
} }
} }

View file

@ -41,24 +41,59 @@ declare(strict_types=1);
namespace App\Services\LabelSystem\Barcodes; namespace App\Services\LabelSystem\Barcodes;
use App\Entity\LabelSystem\LabelSupportedElement;
use InvalidArgumentException; use InvalidArgumentException;
/** /**
* @see \App\Tests\Services\LabelSystem\Barcodes\BarcodeNormalizerTest * @see \App\Tests\Services\LabelSystem\Barcodes\BarcodeNormalizerTest
*/ */
final class BarcodeNormalizer final class BarcodeScanHelper
{ {
private const PREFIX_TYPE_MAP = [ private const PREFIX_TYPE_MAP = [
'L' => 'lot', 'L' => LabelSupportedElement::PART_LOT,
'P' => 'part', 'P' => LabelSupportedElement::PART,
'S' => 'location', 'S' => LabelSupportedElement::STORELOCATION,
];
public const QR_TYPE_MAP = [
'lot' => LabelSupportedElement::PART_LOT,
'part' => LabelSupportedElement::PART,
'location' => LabelSupportedElement::STORELOCATION,
]; ];
/** /**
* Parses barcode content and normalizes it. * Parse the given barcode content and return the target type and ID.
* Returns an array in the format ['part', 1]: First entry contains element type, second the ID of the element. * If the barcode could not be parsed, an exception is thrown.
* Using the $type parameter, you can specify how the barcode should be parsed. If set to null, the function
* will try to guess the type.
* @param string $input
* @param BarcodeSourceType|null $type
* @return BarcodeScanResult
*/ */
public function normalizeBarcodeContent(string $input): array public function scanBarcodeContent(string $input, ?BarcodeSourceType $type = null): BarcodeScanResult
{
//Do specific parsing
if ($type === BarcodeSourceType::INTERNAL) {
return $this->parseInternalBarcode($input) ?? throw new InvalidArgumentException('Could not parse barcode');
}
//Null means auto and we try the different formats
$result = $this->parseInternalBarcode($input);
if ($result !== null) {
return $result;
}
throw new InvalidArgumentException('Unknown barcode format');
}
/**
* This function tries to interpret the given barcode content as an internal barcode.
* If the barcode could not be parsed at all, null is returned. If the barcode is a valid format, but could
* not be found in the database, an exception is thrown.
* @param string $input
* @return BarcodeScanResult|null
*/
private function parseInternalBarcode(string $input): ?BarcodeScanResult
{ {
$input = trim($input); $input = trim($input);
$matches = []; $matches = [];
@ -68,7 +103,11 @@ final class BarcodeNormalizer
//Extract parts from QR code's URL //Extract parts from QR code's URL
if (preg_match('#^https?://.*/scan/(\w+)/(\d+)/?$#', $input, $matches)) { if (preg_match('#^https?://.*/scan/(\w+)/(\d+)/?$#', $input, $matches)) {
return [$matches[1], (int) $matches[2]]; return new BarcodeScanResult(
target_type: self::QR_TYPE_MAP[strtolower($matches[1])],
target_id: (int) $matches[2],
source_type: BarcodeSourceType::INTERNAL
);
} }
//New Code39 barcode use L0001 format //New Code39 barcode use L0001 format
@ -80,7 +119,11 @@ final class BarcodeNormalizer
throw new InvalidArgumentException('Unknown prefix '.$prefix); throw new InvalidArgumentException('Unknown prefix '.$prefix);
} }
return [self::PREFIX_TYPE_MAP[$prefix], $id]; return new BarcodeScanResult(
target_type: self::PREFIX_TYPE_MAP[$prefix],
target_id: $id,
source_type: BarcodeSourceType::INTERNAL
);
} }
//During development the L-000001 format was used //During development the L-000001 format was used
@ -92,19 +135,32 @@ final class BarcodeNormalizer
throw new InvalidArgumentException('Unknown prefix '.$prefix); throw new InvalidArgumentException('Unknown prefix '.$prefix);
} }
return [self::PREFIX_TYPE_MAP[$prefix], $id]; return new BarcodeScanResult(
target_type: self::PREFIX_TYPE_MAP[$prefix],
target_id: $id,
source_type: BarcodeSourceType::INTERNAL
);
} }
//Legacy Part-DB location labels used $L00336 format //Legacy Part-DB location labels used $L00336 format
if (preg_match('#^\$L(\d{5,})$#', $input, $matches)) { if (preg_match('#^\$L(\d{5,})$#', $input, $matches)) {
return ['location', (int) $matches[1]]; return new BarcodeScanResult(
target_type: LabelSupportedElement::STORELOCATION,
target_id: (int) $matches[1],
source_type: BarcodeSourceType::INTERNAL
);
} }
//Legacy Part-DB used EAN8 barcodes for part labels. Format 0000001(2) (note the optional 8th digit => checksum) //Legacy Part-DB used EAN8 barcodes for part labels. Format 0000001(2) (note the optional 8th digit => checksum)
if (preg_match('#^(\d{7})\d?$#', $input, $matches)) { if (preg_match('#^(\d{7})\d?$#', $input, $matches)) {
return ['part', (int) $matches[1]]; return new BarcodeScanResult(
target_type: LabelSupportedElement::PART,
target_id: (int) $matches[1],
source_type: BarcodeSourceType::INTERNAL
);
} }
throw new InvalidArgumentException('Unknown barcode format!'); //This function abstain from further parsing
return null;
} }
} }

View file

@ -0,0 +1,39 @@
<?php
/*
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
*
* Copyright (C) 2019 - 2023 Jan Böhmer (https://github.com/jbtronics)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace App\Services\LabelSystem\Barcodes;
use App\Entity\LabelSystem\LabelSupportedElement;
/**
* This class represents the result of a barcode scan, with the target type and the ID of the element
*/
class BarcodeScanResult
{
public function __construct(
public readonly LabelSupportedElement $target_type,
public readonly int $target_id,
public readonly BarcodeSourceType $source_type,
) {
}
}

View file

@ -0,0 +1,33 @@
<?php
/*
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
*
* Copyright (C) 2019 - 2023 Jan Böhmer (https://github.com/jbtronics)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace App\Services\LabelSystem\Barcodes;
/**
* This enum represents the different types, where a barcode/QR-code can be generated from
*/
enum BarcodeSourceType
{
/** This Barcode was generated using Part-DB internal recommended barcode generator */
case INTERNAL;
}

View file

@ -46,67 +46,47 @@ use App\Entity\Base\AbstractStructuralDBElement;
use App\Entity\LabelSystem\BarcodeType; use App\Entity\LabelSystem\BarcodeType;
use App\Entity\LabelSystem\LabelOptions; use App\Entity\LabelSystem\LabelOptions;
use App\Services\LabelSystem\Barcodes\BarcodeContentGenerator; use App\Services\LabelSystem\Barcodes\BarcodeContentGenerator;
use App\Services\LabelSystem\Barcodes\BarcodeHelper;
use Com\Tecnick\Barcode\Barcode; use Com\Tecnick\Barcode\Barcode;
use InvalidArgumentException; use InvalidArgumentException;
/** /**
* @see \App\Tests\Services\LabelSystem\BarcodeGeneratorTest * @see \App\Tests\Services\LabelSystem\BarcodeGeneratorTest
*/ */
final class BarcodeGenerator final class LabelBarcodeGenerator
{ {
public function __construct(private readonly BarcodeContentGenerator $barcodeContentGenerator) public function __construct(private readonly BarcodeContentGenerator $barcodeContentGenerator, private readonly BarcodeHelper $barcodeHelper)
{ {
} }
public function generateHTMLBarcode(LabelOptions $options, object $target): ?string /**
{ * Generate the barcode for the given label as HTML image tag.
$svg = $this->generateSVG($options, $target); * @param LabelOptions $options
$base64 = $this->dataUri($svg, 'image/svg+xml'); * @param AbstractDBElement $target
return '<img src="'.$base64.'" width="100%" style="min-height: 25px;" alt="'. $this->getContent($options, $target) . '" />'; * @return string|null
}
/**
* Creates a data URI (RFC 2397).
* Based on the Twig implementaion from HTMLExtension
*
* Length validation is not performed on purpose, validation should
* be done before calling this filter.
*
* @return string The generated data URI
*/ */
private function dataUri(string $data, string $mime): string public function generateHTMLBarcode(LabelOptions $options, AbstractDBElement $target): ?string
{ {
$repr = 'data:'; if ($options->getBarcodeType() === BarcodeType::NONE) {
$repr .= $mime;
if (str_starts_with($mime, 'text/')) {
$repr .= ','.rawurlencode($data);
} else {
$repr .= ';base64,'.base64_encode($data);
}
return $repr;
}
public function generateSVG(LabelOptions $options, object $target): ?string
{
$barcode = new Barcode();
$type = match ($options->getBarcodeType()) {
BarcodeType::NONE => null,
BarcodeType::QR => 'QRCODE',
BarcodeType::DATAMATRIX => 'DATAMATRIX',
BarcodeType::CODE39 => 'C39',
BarcodeType::CODE93 => 'C93',
BarcodeType::CODE128 => 'C128A',
};
if ($type === null) {
return null; return null;
} }
return $this->barcodeHelper->barcodeAsHTML($this->getContent($options, $target), $options->getBarcodeType());
}
return $barcode->getBarcodeObj($type, $this->getContent($options, $target))->getSvgCode(); /**
* Generate the barcode for the given label as SVG string.
* @param LabelOptions $options
* @param AbstractDBElement $target
* @return string|null
*/
public function generateSVG(LabelOptions $options, AbstractDBElement $target): ?string
{
if ($options->getBarcodeType() === BarcodeType::NONE) {
return null;
}
return $this->barcodeHelper->barcodeAsSVG($this->getContent($options, $target), $options->getBarcodeType());
} }
public function getContent(LabelOptions $options, AbstractDBElement $target): ?string public function getContent(LabelOptions $options, AbstractDBElement $target): ?string

View file

@ -53,7 +53,7 @@ use Twig\Error\Error;
final class LabelHTMLGenerator final class LabelHTMLGenerator
{ {
public function __construct(private readonly ElementTypeNameGenerator $elementTypeNameGenerator, private readonly LabelTextReplacer $replacer, private readonly Environment $twig, private readonly BarcodeGenerator $barcodeGenerator, private readonly SandboxedTwigProvider $sandboxedTwigProvider, private readonly Security $security, private readonly string $partdb_title) public function __construct(private readonly ElementTypeNameGenerator $elementTypeNameGenerator, private readonly LabelTextReplacer $replacer, private readonly Environment $twig, private readonly LabelBarcodeGenerator $barcodeGenerator, private readonly SandboxedTwigProvider $sandboxedTwigProvider, private readonly Security $security, private readonly string $partdb_title)
{ {
} }

View file

@ -24,12 +24,18 @@ namespace App\Services\LabelSystem\PlaceholderProviders;
use App\Entity\LabelSystem\BarcodeType; use App\Entity\LabelSystem\BarcodeType;
use App\Entity\LabelSystem\LabelOptions; use App\Entity\LabelSystem\LabelOptions;
use App\Services\LabelSystem\BarcodeGenerator; use App\Entity\Parts\Part;
use App\Entity\Parts\PartLot;
use App\Services\LabelSystem\Barcodes\BarcodeHelper;
use App\Services\LabelSystem\LabelBarcodeGenerator;
use App\Services\LabelSystem\Barcodes\BarcodeContentGenerator; use App\Services\LabelSystem\Barcodes\BarcodeContentGenerator;
use Com\Tecnick\Barcode\Exception;
final class BarcodeProvider implements PlaceholderProviderInterface final class BarcodeProvider implements PlaceholderProviderInterface
{ {
public function __construct(private readonly BarcodeGenerator $barcodeGenerator, private readonly BarcodeContentGenerator $barcodeContentGenerator) public function __construct(private readonly LabelBarcodeGenerator $barcodeGenerator,
private readonly BarcodeContentGenerator $barcodeContentGenerator,
private readonly BarcodeHelper $barcodeHelper)
{ {
} }
@ -69,6 +75,37 @@ final class BarcodeProvider implements PlaceholderProviderInterface
return $this->barcodeGenerator->generateHTMLBarcode($label_options, $label_target); return $this->barcodeGenerator->generateHTMLBarcode($label_options, $label_target);
} }
if (($label_target instanceof Part || $label_target instanceof PartLot)
&& str_starts_with($placeholder, '[[IPN_BARCODE_')) {
if ($label_target instanceof PartLot) {
$label_target = $label_target->getPart();
}
if ($label_target === null || $label_target->getIPN() === null || $label_target->getIPN() === '') {
//Replace with empty result, if no IPN is set
return '';
}
try {
//Add placeholders for the IPN barcode
if ('[[IPN_BARCODE_C39]]' === $placeholder) {
return $this->barcodeHelper->barcodeAsHTML($label_target->getIPN(), BarcodeType::CODE39);
}
if ('[[IPN_BARCODE_C128]]' === $placeholder) {
return $this->barcodeHelper->barcodeAsHTML($label_target->getIPN(), BarcodeType::CODE128);
}
if ('[[IPN_BARCODE_QR]]' === $placeholder) {
return $this->barcodeHelper->barcodeAsHTML($label_target->getIPN(), BarcodeType::QR);
}
} catch (Exception $e) {
//If an error occurs, output it
return '<b>IPN Barcode ERROR!</b>: '.$e->getMessage();
}
}
return null; return null;
} }
} }

View file

@ -41,7 +41,7 @@ class SnakeCasePropertyAccessExtractor implements PropertyAccessExtractorInterfa
//$this->reflectionExtractor = new ReflectionExtractor(); //$this->reflectionExtractor = new ReflectionExtractor();
} }
public function isReadable(string $class, string $property, array $context = []) public function isReadable(string $class, string $property, array $context = []): ?bool
{ {
//Null means skip this extractor //Null means skip this extractor
return null; return null;
@ -56,7 +56,7 @@ class SnakeCasePropertyAccessExtractor implements PropertyAccessExtractorInterfa
} }
public function isWritable(string $class, string $property, array $context = []) public function isWritable(string $class, string $property, array $context = []): ?bool
{ {
//Check writeablity using a camelized property name //Check writeablity using a camelized property name
$isWriteable = $this->reflectionExtractor->isWritable($class, $this->camelize($property), $context); $isWriteable = $this->reflectionExtractor->isWritable($class, $this->camelize($property), $context);

View file

@ -32,7 +32,7 @@ use Symfony\Component\Validator\Exception\UnexpectedValueException;
class UniqueObjectCollectionValidator extends ConstraintValidator class UniqueObjectCollectionValidator extends ConstraintValidator
{ {
public function validate(mixed $value, Constraint $constraint) public function validate(mixed $value, Constraint $constraint): void
{ {
if (!$constraint instanceof UniqueObjectCollection) { if (!$constraint instanceof UniqueObjectCollection) {
throw new UnexpectedTypeException($constraint, UniqueObjectCollection::class); throw new UnexpectedTypeException($constraint, UniqueObjectCollection::class);

View file

@ -23,7 +23,7 @@
<div class="d-none" {{ stimulus_controller('turbo/locale_menu') }}> <div class="d-none" {{ stimulus_controller('turbo/locale_menu') }}>
{% for locale in locale_menu %} {% for locale in locale_menu %}
<a class="dropdown-item" data-turbo="false" data-turbo-frame="_top" href="{{ path(app.request.attributes.get('_route'), <a class="dropdown-item" data-turbo="false" data-turbo-frame="_top" href="{{ path(app.request.attributes.get('_route'),
app.request.attributes.get('_route_params')|merge({'_locale': locale})) }}"> app.request.query.all|merge(app.request.attributes.get('_route_params'))|merge({'_locale': locale})) }}">
{{ locale|language_name }} ({{ locale|upper }})</a> {{ locale|language_name }} ({{ locale|upper }})</a>
{% endfor %} {% endfor %}
</div> </div>

View file

@ -70,11 +70,13 @@ class DTOtoEntityConverterTest extends WebTestCase
price: "10.0", price: "10.0",
currency_iso_code: 'CNY', currency_iso_code: 'CNY',
includes_tax: true, includes_tax: true,
price_related_quantity: 10.0,
); );
$entity = $this->service->convertPrice($dto); $entity = $this->service->convertPrice($dto);
$this->assertEquals($dto->minimum_discount_amount, $entity->getMinDiscountQuantity()); $this->assertEquals($dto->minimum_discount_amount, $entity->getMinDiscountQuantity());
$this->assertEquals((float) $dto->price, (float) (string) $entity->getPrice()); $this->assertEquals((float) $dto->price, (float) (string) $entity->getPrice());
$this->assertEquals($dto->price_related_quantity, $entity->getPriceRelatedQuantity());
//For non-base currencies, a new currency entity is created //For non-base currencies, a new currency entity is created
$currency = $entity->getCurrency(); $currency = $entity->getCurrency();

View file

@ -0,0 +1,68 @@
<?php
/*
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
*
* Copyright (C) 2019 - 2023 Jan Böhmer (https://github.com/jbtronics)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
namespace App\Tests\Services\LabelSystem\Barcodes;
use App\Entity\LabelSystem\BarcodeType;
use App\Services\LabelSystem\Barcodes\BarcodeHelper;
use PHPUnit\Framework\TestCase;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
class BarcodeHelperTest extends WebTestCase
{
protected ?BarcodeHelper $service = null;
protected function setUp(): void
{
self::bootKernel();
$this->service = self::getContainer()->get(BarcodeHelper::class);
}
public function testBarcodeAsHTML(): void
{
$html = $this->service->barcodeAsHTML('Test', BarcodeType::QR);
$this->assertStringStartsWith('<img', $html);
$this->assertStringContainsString('alt="Test"', $html);
}
public function testBarcodeAsSVG(): void
{
//Test that all barcodes types are supported
foreach (BarcodeType::cases() as $type) {
//Skip NONE type
if (BarcodeType::NONE === $type) {
continue;
}
$svg = $this->service->barcodeAsSVG('1234', $type);
$this->assertStringContainsStringIgnoringCase('SVG', $svg);
}
}
public function testBarcodeAsSVGNoneType(): void
{
//On NONE type, service must throw an exception.
$this->expectException(\InvalidArgumentException::class);
$this->service->barcodeAsSVG('test', BarcodeType::NONE);
}
}

View file

@ -1,115 +0,0 @@
<?php
/*
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
*
* Copyright (C) 2019 - 2022 Jan Böhmer (https://github.com/jbtronics)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
/**
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
*
* Copyright (C) 2019 - 2020 Jan Böhmer (https://github.com/jbtronics)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
namespace App\Tests\Services\LabelSystem\Barcodes;
use App\Services\LabelSystem\Barcodes\BarcodeNormalizer;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
class BarcodeNormalizerTest extends WebTestCase
{
/**
* @var BarcodeNormalizer
*/
protected $service;
protected function setUp(): void
{
self::bootKernel();
$this->service = self::getContainer()->get(BarcodeNormalizer::class);
}
public function dataProvider(): \Iterator
{
//QR URL content:
yield [['lot', 1], 'https://localhost:8000/scan/lot/1'];
yield [['part', 123], 'https://localhost:8000/scan/part/123'];
yield [['location', 4], 'http://foo.bar/part-db/scan/location/4'];
yield [['under_score', 10], 'http://test/part-db/sub/scan/under_score/10/'];
//Current Code39 format:
yield [['lot', 10], 'L0010'];
yield [['lot', 123], 'L0123'];
yield [['lot', 123456], 'L123456'];
yield [['part', 2], 'P0002'];
//Development phase Code39 barcodes:
yield [['lot', 10], 'L-000010'];
yield [['lot', 10], 'Lß000010'];
yield [['part', 123], 'P-000123'];
yield [['location', 123], 'S-000123'];
yield [['lot', 12_345_678], 'L-12345678'];
//Legacy storelocation format
yield [['location', 336], '$L00336'];
yield [['location', 12_345_678], '$L12345678'];
//Legacy Part format
yield [['part', 123], '0000123'];
yield [['part', 123], '00001236'];
yield [['part', 1_234_567], '12345678'];
}
public function invalidDataProvider(): array
{
return [
['https://localhost/part/1'], //Without scan
['L-'], //Without number
['L-123'], //Too short
['X-123456'], //Unknown prefix
['XXXWADSDF sdf'], //Garbage
[''], //Empty
];
}
/**
* @dataProvider dataProvider
*/
public function testNormalizeBarcodeContent(array $expected, string $input): void
{
$this->assertSame($expected, $this->service->normalizeBarcodeContent($input));
}
/**
* @dataProvider invalidDataProvider
*/
public function testInvalidFormats(string $input): void
{
$this->expectException(\InvalidArgumentException::class);
$this->service->normalizeBarcodeContent($input);
}
}

View file

@ -41,13 +41,16 @@ declare(strict_types=1);
namespace App\Tests\Services\LabelSystem\Barcodes; namespace App\Tests\Services\LabelSystem\Barcodes;
use App\Entity\LabelSystem\LabelSupportedElement;
use App\Services\LabelSystem\Barcodes\BarcodeRedirector; use App\Services\LabelSystem\Barcodes\BarcodeRedirector;
use App\Services\LabelSystem\Barcodes\BarcodeScanResult;
use App\Services\LabelSystem\Barcodes\BarcodeSourceType;
use Doctrine\ORM\EntityNotFoundException; use Doctrine\ORM\EntityNotFoundException;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
class BarcodeRedirectorTest extends KernelTestCase final class BarcodeRedirectorTest extends KernelTestCase
{ {
private ?object $service = null; private ?BarcodeRedirector $service = null;
protected function setUp(): void protected function setUp(): void
{ {
@ -55,13 +58,13 @@ class BarcodeRedirectorTest extends KernelTestCase
$this->service = self::getContainer()->get(BarcodeRedirector::class); $this->service = self::getContainer()->get(BarcodeRedirector::class);
} }
public function urlDataProvider(): array public static function urlDataProvider(): array
{ {
return [ return [
['part', '/en/part/1'], [new BarcodeScanResult(LabelSupportedElement::PART, 1, BarcodeSourceType::INTERNAL), '/en/part/1'],
//Part lot redirects to Part info page (Part lot 1 is associated with part 3 //Part lot redirects to Part info page (Part lot 1 is associated with part 3)
['lot', '/en/part/3'], [new BarcodeScanResult(LabelSupportedElement::PART_LOT, 1, BarcodeSourceType::INTERNAL), '/en/part/3'],
['location', '/en/store_location/1/parts'], [new BarcodeScanResult(LabelSupportedElement::STORELOCATION, 1, BarcodeSourceType::INTERNAL), '/en/store_location/1/parts'],
]; ];
} }
@ -69,21 +72,16 @@ class BarcodeRedirectorTest extends KernelTestCase
* @dataProvider urlDataProvider * @dataProvider urlDataProvider
* @group DB * @group DB
*/ */
public function testGetRedirectURL(string $type, string $url): void public function testGetRedirectURL(BarcodeScanResult $scanResult, string $url): void
{ {
$this->assertSame($url, $this->service->getRedirectURL($type, 1)); $this->assertSame($url, $this->service->getRedirectURL($scanResult));
} }
public function testGetRedirectEntityNotFount(): void public function testGetRedirectEntityNotFount(): void
{ {
$this->expectException(EntityNotFoundException::class); $this->expectException(EntityNotFoundException::class);
//If we encounter an invalid lot, we must throw an exception //If we encounter an invalid lot, we must throw an exception
$this->service->getRedirectURL('lot', 12_345_678); $this->service->getRedirectURL(new BarcodeScanResult(LabelSupportedElement::PART_LOT,
} 12_345_678, BarcodeSourceType::INTERNAL));
public function testInvalidType(): void
{
$this->expectException(\InvalidArgumentException::class);
$this->service->getRedirectURL('invalid', 1);
} }
} }

View file

@ -0,0 +1,136 @@
<?php
/*
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
*
* Copyright (C) 2019 - 2022 Jan Böhmer (https://github.com/jbtronics)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
/**
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
*
* Copyright (C) 2019 - 2020 Jan Böhmer (https://github.com/jbtronics)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
namespace App\Tests\Services\LabelSystem\Barcodes;
use App\Entity\LabelSystem\LabelSupportedElement;
use App\Services\LabelSystem\Barcodes\BarcodeScanHelper;
use App\Services\LabelSystem\Barcodes\BarcodeScanResult;
use App\Services\LabelSystem\Barcodes\BarcodeSourceType;
use Com\Tecnick\Barcode\Barcode;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
class BarcodeScanHelperTest extends WebTestCase
{
private ?BarcodeScanHelper $service = null;
protected function setUp(): void
{
self::bootKernel();
$this->service = self::getContainer()->get(BarcodeScanHelper::class);
}
public static function dataProvider(): \Iterator
{
//QR URL content:
yield [new BarcodeScanResult(LabelSupportedElement::PART_LOT, 1, BarcodeSourceType::INTERNAL),
'https://localhost:8000/scan/lot/1'];
yield [new BarcodeScanResult(LabelSupportedElement::PART, 123, BarcodeSourceType::INTERNAL),
'https://localhost:8000/scan/part/123'];
yield [new BarcodeScanResult(LabelSupportedElement::STORELOCATION, 4, BarcodeSourceType::INTERNAL),
'http://foo.bar/part-db/scan/location/4'];
//Current Code39 format:
yield [new BarcodeScanResult(LabelSupportedElement::PART_LOT, 10, BarcodeSourceType::INTERNAL),
'L0010'];
yield [new BarcodeScanResult(LabelSupportedElement::PART_LOT, 123, BarcodeSourceType::INTERNAL),
'L0123'];
yield [new BarcodeScanResult(LabelSupportedElement::PART_LOT, 123456, BarcodeSourceType::INTERNAL),
'L123456'];
yield [new BarcodeScanResult(LabelSupportedElement::PART, 2, BarcodeSourceType::INTERNAL),
'P0002'];
//Development phase Code39 barcodes:
yield [new BarcodeScanResult(LabelSupportedElement::PART_LOT, 10, BarcodeSourceType::INTERNAL),
'L-000010'];
yield [new BarcodeScanResult(LabelSupportedElement::PART_LOT, 10, BarcodeSourceType::INTERNAL),
'Lß000010'];
yield [new BarcodeScanResult(LabelSupportedElement::PART, 123, BarcodeSourceType::INTERNAL),
'P-000123'];
yield [new BarcodeScanResult(LabelSupportedElement::STORELOCATION, 123, BarcodeSourceType::INTERNAL),
'S-000123'];
yield [new BarcodeScanResult(LabelSupportedElement::PART_LOT, 12_345_678, BarcodeSourceType::INTERNAL),
'L-12345678'];
//Legacy storelocation format
yield [new BarcodeScanResult(LabelSupportedElement::STORELOCATION, 336, BarcodeSourceType::INTERNAL),
'$L00336'];
yield [new BarcodeScanResult(LabelSupportedElement::STORELOCATION, 12_345_678, BarcodeSourceType::INTERNAL),
'$L12345678'];
//Legacy Part format
yield [new BarcodeScanResult(LabelSupportedElement::PART, 123, BarcodeSourceType::INTERNAL),
'0000123'];
yield [new BarcodeScanResult(LabelSupportedElement::PART, 123, BarcodeSourceType::INTERNAL),
'00001236'];
yield [new BarcodeScanResult(LabelSupportedElement::PART, 1_234_567, BarcodeSourceType::INTERNAL),
'12345678'];
}
public static function invalidDataProvider(): array
{
return [
['https://localhost/part/1'], //Without scan
['L-'], //Without number
['L-123'], //Too short
['X-123456'], //Unknown prefix
['XXXWADSDF sdf'], //Garbage
[''], //Empty
];
}
/**
* @dataProvider dataProvider
*/
public function testNormalizeBarcodeContent(BarcodeScanResult $expected, string $input): void
{
$this->assertEquals($expected, $this->service->scanBarcodeContent($input));
}
/**
* @dataProvider invalidDataProvider
*/
public function testInvalidFormats(string $input): void
{
$this->expectException(\InvalidArgumentException::class);
$this->service->scanBarcodeContent($input);
}
}

View file

@ -44,20 +44,17 @@ namespace App\Tests\Services\LabelSystem;
use App\Entity\LabelSystem\BarcodeType; use App\Entity\LabelSystem\BarcodeType;
use App\Entity\LabelSystem\LabelOptions; use App\Entity\LabelSystem\LabelOptions;
use App\Entity\Parts\Part; use App\Entity\Parts\Part;
use App\Services\LabelSystem\BarcodeGenerator; use App\Services\LabelSystem\LabelBarcodeGenerator;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
final class BarcodeGeneratorTest extends WebTestCase final class LabelBarcodeGeneratorTest extends WebTestCase
{ {
/** protected ?LabelBarcodeGenerator $service = null;
* @var BarcodeGenerator
*/
protected $services;
protected function setUp(): void protected function setUp(): void
{ {
self::bootKernel(); self::bootKernel();
$this->services = self::getContainer()->get(BarcodeGenerator::class); $this->service = self::getContainer()->get(LabelBarcodeGenerator::class);
} }
public function testGetContent(): void public function testGetContent(): void
@ -69,7 +66,7 @@ final class BarcodeGeneratorTest extends WebTestCase
foreach (BarcodeType::cases() as $type) { foreach (BarcodeType::cases() as $type) {
$options = new LabelOptions(); $options = new LabelOptions();
$options->setBarcodeType($type); $options->setBarcodeType($type);
$content = $this->services->generateSVG($options, $part); $content = $this->service->generateSVG($options, $part);
//When type is none, service must return null. //When type is none, service must return null.
if (BarcodeType::NONE === $type) { if (BarcodeType::NONE === $type) {
@ -89,7 +86,7 @@ final class BarcodeGeneratorTest extends WebTestCase
foreach (BarcodeType::cases() as $type) { foreach (BarcodeType::cases() as $type) {
$options = new LabelOptions(); $options = new LabelOptions();
$options->setBarcodeType($type); $options->setBarcodeType($type);
$svg = $this->services->generateSVG($options, $part); $svg = $this->service->generateSVG($options, $part);
//When type is none, service must return null. //When type is none, service must return null.
if (BarcodeType::NONE === $type) { if (BarcodeType::NONE === $type) {

View file

@ -28,22 +28,21 @@ use Scheb\TwoFactorBundle\Model\Google\TwoFactorInterface;
use Scheb\TwoFactorBundle\Security\TwoFactor\Provider\Google\GoogleAuthenticatorInterface; use Scheb\TwoFactorBundle\Security\TwoFactor\Provider\Google\GoogleAuthenticatorInterface;
use Symfony\Bundle\SecurityBundle\Security; use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Validator\ConstraintValidator;
use Symfony\Component\Validator\ConstraintValidatorInterface;
use Symfony\Component\Validator\Test\ConstraintValidatorTestCase; use Symfony\Component\Validator\Test\ConstraintValidatorTestCase;
class ValidGoogleAuthCodeValidatorTest extends ConstraintValidatorTestCase class ValidGoogleAuthCodeValidatorTest extends ConstraintValidatorTestCase
{ {
protected function createValidator() protected function createValidator(): ConstraintValidatorInterface
{ {
$googleAuth = new class implements GoogleAuthenticatorInterface $googleAuth = new class implements GoogleAuthenticatorInterface
{ {
public function checkCode(TwoFactorInterface $user, string $code): bool public function checkCode(TwoFactorInterface $user, string $code): bool
{ {
if ($code === '123456') { return $code === '123456';
return true;
}
return false;
} }
public function getQRContent(TwoFactorInterface $user): string public function getQRContent(TwoFactorInterface $user): string

View file

@ -36,16 +36,9 @@ if (!Encore.isRuntimeEnvironmentConfigured()) {
Encore Encore
// directory where compiled assets will be stored // directory where compiled assets will be stored
.setOutputPath('public/build/') .setOutputPath('public/build/')
// public path used by the web server to access the output path // This value doesn't matter, as the public path is set to auto later down. This is just to prevent a warning
.setPublicPath('/build') .setPublicPath('/build')
// only needed for CDN's or subdirectory deploy // only needed for CDN's or subdirectory deploy (this should not be needeed, as we use auto public path)
//.setManifestKeyPrefix('build/')
/**
* If you are putting Part-DB into a sub directory you have to uncomment these lines and
* replace "part-db/" with your path to Part-DB
*/
//.setPublicPath('/part-db/build')
//.setManifestKeyPrefix('build/') //.setManifestKeyPrefix('build/')
/* /*
@ -189,3 +182,7 @@ if (Encore.isDev()) {
module.exports = Encore.getWebpackConfig(); module.exports = Encore.getWebpackConfig();
//Enable webpack auto public path (this only works in combination with WebpackAutoPathSubscriber!!)
//We do it here to supress a warning caused by webpack Encore
module.exports.output.publicPath = 'auto';

518
yarn.lock
View file

@ -990,10 +990,10 @@
"@ckeditor/ckeditor5-utils" "40.0.0" "@ckeditor/ckeditor5-utils" "40.0.0"
lodash-es "4.17.21" lodash-es "4.17.21"
"@ckeditor/ckeditor5-dev-translations@^39.1.0": "@ckeditor/ckeditor5-dev-translations@^39.1.0", "@ckeditor/ckeditor5-dev-translations@^39.2.0":
version "39.1.0" version "39.2.0"
resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-dev-translations/-/ckeditor5-dev-translations-39.1.0.tgz#d78f383f658d61934cc318ce8198f37cbc045bb5" resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-dev-translations/-/ckeditor5-dev-translations-39.2.0.tgz#9414e7ee37aba9792269fba941792be01135d956"
integrity sha512-QvgIHjjn7p9sJuJb1COdMINAajcv6iTLJUnsg9bf2/xSqvbz3c3KixeNXddlDHsLTaD6ZVopQvdGKMus0HuLLQ== integrity sha512-Bz57yt70Kb4g4snkZwIZ0fKZo5vLphyX0G05ETiPu1hDcZN0oQSy7aK/kn4eJ3ptO3/7lwJhQZUE0opzkfWSqQ==
dependencies: dependencies:
"@babel/parser" "^7.18.9" "@babel/parser" "^7.18.9"
"@babel/traverse" "^7.18.9" "@babel/traverse" "^7.18.9"
@ -1003,11 +1003,11 @@
webpack-sources "^2.0.1" webpack-sources "^2.0.1"
"@ckeditor/ckeditor5-dev-utils@^39.1.0": "@ckeditor/ckeditor5-dev-utils@^39.1.0":
version "39.1.0" version "39.2.0"
resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-dev-utils/-/ckeditor5-dev-utils-39.1.0.tgz#c23b057db8fde233175d85f00f00158cbafeee8c" resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-dev-utils/-/ckeditor5-dev-utils-39.2.0.tgz#d4b44d6f54a546808a184b0ad39aa32da5f038c8"
integrity sha512-rIUzpS00xbBaFqar8EThDDLZS1IQ5xuYDsi9hiOAhMAM5hqxGktjY666/yqXtuXp3FHW8pYUFwCjHj9T1rWVSw== integrity sha512-mmBLo+xvG0ACErcJR6QLXi0mz8rRnC5sCp9IhS/P2tl1TrYGyo7fma1M1YL2WZ6n8Z6sT1xWdQga4ZN0fxYdDg==
dependencies: dependencies:
"@ckeditor/ckeditor5-dev-translations" "^39.1.0" "@ckeditor/ckeditor5-dev-translations" "^39.2.0"
chalk "^3.0.0" chalk "^3.0.0"
cli-cursor "^3.1.0" cli-cursor "^3.1.0"
cli-spinners "^2.6.1" cli-spinners "^2.6.1"
@ -1477,10 +1477,10 @@
dependencies: dependencies:
tslib "^2.4.0" tslib "^2.4.0"
"@formatjs/icu-messageformat-parser@2.6.2": "@formatjs/icu-messageformat-parser@2.7.0":
version "2.6.2" version "2.7.0"
resolved "https://registry.yarnpkg.com/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.6.2.tgz#9bbb29099416e4ce2c7df50029c48985d4f901b3" resolved "https://registry.yarnpkg.com/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.7.0.tgz#9b13f2710a3b4efddfeb544480f684f27a53483b"
integrity sha512-nF/Iww7sc5h+1MBCDRm68qpHTCG4xvGzYs/x9HFcDETSGScaJ1Fcadk5U/NXjXeCtzD+DhN4BAwKFVclHfKMdA== integrity sha512-7uqC4C2RqOaBQtcjqXsSpGRYVn+ckjhNga5T/otFh6MgxRrCJQqvjfbrGLpX1Lcbxdm5WH3Z2WZqt1+Tm/cn/Q==
dependencies: dependencies:
"@formatjs/ecma402-abstract" "1.17.2" "@formatjs/ecma402-abstract" "1.17.2"
"@formatjs/icu-skeleton-parser" "1.6.2" "@formatjs/icu-skeleton-parser" "1.6.2"
@ -1583,9 +1583,9 @@
integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==
"@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.9": "@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.9":
version "0.3.19" version "0.3.20"
resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz#f8a3249862f91be48d3127c3cfe992f79b4b8811" resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz#72e45707cf240fa6b081d0366f8265b0cd10197f"
integrity sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw== integrity sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==
dependencies: dependencies:
"@jridgewell/resolve-uri" "^3.1.0" "@jridgewell/resolve-uri" "^3.1.0"
"@jridgewell/sourcemap-codec" "^1.4.14" "@jridgewell/sourcemap-codec" "^1.4.14"
@ -1687,13 +1687,13 @@
version "0.1.0" version "0.1.0"
"@symfony/webpack-encore@^4.1.0": "@symfony/webpack-encore@^4.1.0":
version "4.4.0" version "4.5.0"
resolved "https://registry.yarnpkg.com/@symfony/webpack-encore/-/webpack-encore-4.4.0.tgz#9cc67e360ed19206d05cd50b706b7d68aaa424c4" resolved "https://registry.yarnpkg.com/@symfony/webpack-encore/-/webpack-encore-4.5.0.tgz#6f8251518412e37e947100cb6daadf846cfea8dd"
integrity sha512-p3n2Z16sGV6odZ3ihIU+gupYc55KfrfCt62+Gppe8MUo6QuT5Bk2cXXjR4Hb89KvCRDHnjYEWVfnewRsfE8TRQ== integrity sha512-eGHtQc1BDDj7hS35FyIDxQdgQcgKZ5kPh9nLLUihyDE37kPav/id1PfaHoAfydqQyv4QHsXQzLfdYC7k8agFLw==
dependencies: dependencies:
"@nuxt/friendly-errors-webpack-plugin" "^2.5.1" "@nuxt/friendly-errors-webpack-plugin" "^2.5.1"
assets-webpack-plugin "7.0.*" assets-webpack-plugin "7.0.*"
babel-loader "^8.2.5" babel-loader "^9.1.3"
chalk "^4.0.0" chalk "^4.0.0"
clean-webpack-plugin "^4.0.0" clean-webpack-plugin "^4.0.0"
css-loader "^6.7.0" css-loader "^6.7.0"
@ -1723,60 +1723,60 @@
integrity sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA== integrity sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==
"@types/body-parser@*": "@types/body-parser@*":
version "1.19.3" version "1.19.4"
resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.3.tgz#fb558014374f7d9e56c8f34bab2042a3a07d25cd" resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.4.tgz#78ad68f1f79eb851aa3634db0c7f57f6f601b462"
integrity sha512-oyl4jvAfTGX9Bt6Or4H9ni1Z447/tQuxnZsytsCaExKlmJiU8sFgnIBRzJUpKwB5eWn9HuBYlUlVA74q/yN0eQ== integrity sha512-N7UDG0/xiPQa2D/XrVJXjkWbpqHCd2sBaB32ggRF2l83RhPfamgKGF8gwwqyksS95qUS5ZYF9aF+lLPRlwI2UA==
dependencies: dependencies:
"@types/connect" "*" "@types/connect" "*"
"@types/node" "*" "@types/node" "*"
"@types/bonjour@^3.5.9": "@types/bonjour@^3.5.9":
version "3.5.11" version "3.5.12"
resolved "https://registry.yarnpkg.com/@types/bonjour/-/bonjour-3.5.11.tgz#fbaa46a1529ea5c5e46cde36e4be6a880db55b84" resolved "https://registry.yarnpkg.com/@types/bonjour/-/bonjour-3.5.12.tgz#49badafb988e6c433ca675a5fd769b93b7649fc8"
integrity sha512-isGhjmBtLIxdHBDl2xGwUzEM8AOyOvWsADWq7rqirdi/ZQoHnLWErHvsThcEzTX8juDRiZtzp2Qkv5bgNh6mAg== integrity sha512-ky0kWSqXVxSqgqJvPIkgFkcn4C8MnRog308Ou8xBBIVo39OmUFy+jqNe0nPwLCDFxUpmT9EvT91YzOJgkDRcFg==
dependencies: dependencies:
"@types/node" "*" "@types/node" "*"
"@types/connect-history-api-fallback@^1.3.5": "@types/connect-history-api-fallback@^1.3.5":
version "1.5.1" version "1.5.2"
resolved "https://registry.yarnpkg.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.1.tgz#6e5e3602d93bda975cebc3449e1a318340af9e20" resolved "https://registry.yarnpkg.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.2.tgz#acf51e088b3bb6507f7b093bd2b0de20940179cc"
integrity sha512-iaQslNbARe8fctL5Lk+DsmgWOM83lM+7FzP0eQUJs1jd3kBE8NWqBTIT2S8SqQOJjxvt2eyIjpOuYeRXq2AdMw== integrity sha512-gX2j9x+NzSh4zOhnRPSdPPmTepS4DfxES0AvIFv3jGv5QyeAJf6u6dY5/BAoAJU9Qq1uTvwOku8SSC2GnCRl6Q==
dependencies: dependencies:
"@types/express-serve-static-core" "*" "@types/express-serve-static-core" "*"
"@types/node" "*" "@types/node" "*"
"@types/connect@*": "@types/connect@*":
version "3.4.36" version "3.4.37"
resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.36.tgz#e511558c15a39cb29bd5357eebb57bd1459cd1ab" resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.37.tgz#c66a96689fd3127c8772eb3e9e5c6028ec1a9af5"
integrity sha512-P63Zd/JUGq+PdrM1lv0Wv5SBYeA2+CORvbrXbngriYY0jzLUWfQMQQxOhjONEz/wlHOAxOdY7CY65rgQdTjq2w== integrity sha512-zBUSRqkfZ59OcwXon4HVxhx5oWCJmc0OtBTK05M+p0dYjgN6iTwIL2T/WbsQZrEsdnwaF9cWQ+azOnpPvIqY3Q==
dependencies: dependencies:
"@types/node" "*" "@types/node" "*"
"@types/eslint-scope@^3.7.3": "@types/eslint-scope@^3.7.3":
version "3.7.5" version "3.7.6"
resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.5.tgz#e28b09dbb1d9d35fdfa8a884225f00440dfc5a3e" resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.6.tgz#585578b368ed170e67de8aae7b93f54a1b2fdc26"
integrity sha512-JNvhIEyxVW6EoMIFIvj93ZOywYFatlpu9deeH6eSx6PE3WHYvHaQtmHmQeNw7aA81bYGBPPQqdtBm6b1SsQMmA== integrity sha512-zfM4ipmxVKWdxtDaJ3MP3pBurDXOCoyjvlpE3u6Qzrmw4BPbfm4/ambIeTk/r/J0iq/+2/xp0Fmt+gFvXJY2PQ==
dependencies: dependencies:
"@types/eslint" "*" "@types/eslint" "*"
"@types/estree" "*" "@types/estree" "*"
"@types/eslint@*": "@types/eslint@*":
version "8.44.4" version "8.44.6"
resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.44.4.tgz#28eaff82e1ca0a96554ec5bb0188f10ae1a74c2f" resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.44.6.tgz#60e564551966dd255f4c01c459f0b4fb87068603"
integrity sha512-lOzjyfY/D9QR4hY9oblZ76B90MYTB3RrQ4z2vBIJKj9ROCRqdkYl2gSUx1x1a4IWPjKJZLL4Aw1Zfay7eMnmnA== integrity sha512-P6bY56TVmX8y9J87jHNgQh43h6VVU+6H7oN7hgvivV81K2XY8qJZ5vqPy/HdUoVIelii2kChYVzQanlswPWVFw==
dependencies: dependencies:
"@types/estree" "*" "@types/estree" "*"
"@types/json-schema" "*" "@types/json-schema" "*"
"@types/estree@*", "@types/estree@^1.0.0": "@types/estree@*", "@types/estree@^1.0.0":
version "1.0.2" version "1.0.4"
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.2.tgz#ff02bc3dc8317cd668dfec247b750ba1f1d62453" resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.4.tgz#d9748f5742171b26218516cf1828b8eafaf8a9fa"
integrity sha512-VeiPZ9MMwXjO32/Xu7+OwflfmeoRwkE/qzndw42gGtgJwZopBnzy2gD//NN1+go1mADzkDcqf/KnFRSjTJ8xJA== integrity sha512-2JwWnHK9H+wUZNorf2Zr6ves96WHoWDJIftkcxPKsS7Djta6Zu519LarhRNljPXkpsZR2ZMwNCPeW7omW07BJw==
"@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.33": "@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.33":
version "4.17.37" version "4.17.39"
resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.37.tgz#7e4b7b59da9142138a2aaa7621f5abedce8c7320" resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.39.tgz#2107afc0a4b035e6cb00accac3bdf2d76ae408c8"
integrity sha512-ZohaCYTgGFcOP7u6aJOhY9uIZQgZ2vxC2yWoArY+FeDXlqeH66ZVBjgvg+RLVAS/DWNq4Ap9ZXu1+SUQiiWYMg== integrity sha512-BiEUfAiGCOllomsRAZOiMFP7LAnrifHpt56pc4Z7l9K6ACyN06Ns1JLMBxwkfLOjJRlSf06NwWsT7yzfpaVpyQ==
dependencies: dependencies:
"@types/node" "*" "@types/node" "*"
"@types/qs" "*" "@types/qs" "*"
@ -1784,9 +1784,9 @@
"@types/send" "*" "@types/send" "*"
"@types/express@*", "@types/express@^4.17.13": "@types/express@*", "@types/express@^4.17.13":
version "4.17.19" version "4.17.20"
resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.19.tgz#6ff9b4851fda132c5d3dcd2f89fdb6a7a0031ced" resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.20.tgz#e7c9b40276d29e38a4e3564d7a3d65911e2aa433"
integrity sha512-UtOfBtzN9OvpZPPbnnYunfjM7XCI4jyk1NvnFhTVz5krYAnW4o5DCoIekvms+8ApqhB4+9wSge1kBijdfTSmfg== integrity sha512-rOaqlkgEvOW495xErXMsmyX3WKBInbhG5eqojXYi3cGUaLoRDlXa5d52fkfWZT963AZ3v2eZ4MbKE6WpDAGVsw==
dependencies: dependencies:
"@types/body-parser" "*" "@types/body-parser" "*"
"@types/express-serve-static-core" "^4.17.33" "@types/express-serve-static-core" "^4.17.33"
@ -1802,77 +1802,84 @@
"@types/node" "*" "@types/node" "*"
"@types/http-errors@*": "@types/http-errors@*":
version "2.0.2" version "2.0.3"
resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-2.0.2.tgz#a86e00bbde8950364f8e7846687259ffcd96e8c2" resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-2.0.3.tgz#c54e61f79b3947d040f150abd58f71efb422ff62"
integrity sha512-lPG6KlZs88gef6aD85z3HNkztpj7w2R7HmR3gygjfXCQmsLloWNARFkMuzKiiY8FGdh1XDpgBdrSf4aKDiA7Kg== integrity sha512-pP0P/9BnCj1OVvQR2lF41EkDG/lWWnDyA203b/4Fmi2eTyORnBtcDoKDwjWQthELrBvWkMOrvSOnZ8OVlW6tXA==
"@types/http-proxy@^1.17.8": "@types/http-proxy@^1.17.8":
version "1.17.12" version "1.17.13"
resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.12.tgz#86e849e9eeae0362548803c37a0a1afc616bd96b" resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.13.tgz#dd3a4da550580eb0557d4c7128a2ff1d1a38d465"
integrity sha512-kQtujO08dVtQ2wXAuSFfk9ASy3sug4+ogFR8Kd8UgP8PEuc1/G/8yjYRmp//PcDNJEUKOza/MrQu15bouEUCiw== integrity sha512-GkhdWcMNiR5QSQRYnJ+/oXzu0+7JJEPC8vkWXK351BkhjraZF+1W13CUYARUvX9+NqIU2n6YHA4iwywsc/M6Sw==
dependencies: dependencies:
"@types/node" "*" "@types/node" "*"
"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0": "@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0":
version "2.0.4" version "2.0.5"
resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz#8467d4b3c087805d63580480890791277ce35c44" resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz#fdfdd69fa16d530047d9963635bd77c71a08c068"
integrity sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g== integrity sha512-zONci81DZYCZjiLe0r6equvZut0b+dBRPBN5kBDjsONnutYNtJMoWQ9uR2RkL1gLG9NMTzvf+29e5RFfPbeKhQ==
"@types/istanbul-lib-report@*": "@types/istanbul-lib-report@*":
version "3.0.1" version "3.0.2"
resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz#412e0725ef41cde73bfa03e0e833eaff41e0fd63" resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.2.tgz#394798d5f727402eb5ec99eb9618ffcd2b7645a1"
integrity sha512-gPQuzaPR5h/djlAv2apEG1HVOyj1IUs7GpfMZixU0/0KXT3pm64ylHuMUI1/Akh+sq/iikxg6Z2j+fcMDXaaTQ== integrity sha512-8toY6FgdltSdONav1XtUHl4LN1yTmLza+EuDazb/fEmRNCwjyqNVIQWs2IfC74IqjHkREs/nQ2FWq5kZU9IC0w==
dependencies: dependencies:
"@types/istanbul-lib-coverage" "*" "@types/istanbul-lib-coverage" "*"
"@types/istanbul-reports@^3.0.0": "@types/istanbul-reports@^3.0.0":
version "3.0.2" version "3.0.3"
resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.2.tgz#edc8e421991a3b4df875036d381fc0a5a982f549" resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.3.tgz#0313e2608e6d6955d195f55361ddeebd4b74c6e7"
integrity sha512-kv43F9eb3Lhj+lr/Hn6OcLCs/sSM8bt+fIaP11rCYngfV6NVjzWXJ17owQtDQTL9tQ8WSLUrGsSJ6rJz0F1w1A== integrity sha512-1nESsePMBlf0RPRffLZi5ujYh7IH1BWL4y9pr+Bn3cJBdxz+RTP8bUFljLz9HvzhhOSWKdyBZ4DIivdL6rvgZg==
dependencies: dependencies:
"@types/istanbul-lib-report" "*" "@types/istanbul-lib-report" "*"
"@types/json-schema@*", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": "@types/json-schema@*", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9":
version "7.0.13" version "7.0.14"
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.13.tgz#02c24f4363176d2d18fc8b70b9f3c54aba178a85" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.14.tgz#74a97a5573980802f32c8e47b663530ab3b6b7d1"
integrity sha512-RbSSoHliUbnXj3ny0CNFOoxrIDV6SUGyStHsvDqosw6CkdPV8TtWGlfecuK4ToyMEAql6pzNxgCFKanovUzlgQ== integrity sha512-U3PUjAudAdJBeC2pgN8uTIKgxrb4nlDF3SF0++EldXQvQBGkpFZMSnwQiIoDU77tv45VgNkl/L4ouD+rEomujw==
"@types/mime@*": "@types/mime@*":
version "3.0.2" version "3.0.3"
resolved "https://registry.yarnpkg.com/@types/mime/-/mime-3.0.2.tgz#c1ae807f13d308ee7511a5b81c74f327028e66e8" resolved "https://registry.yarnpkg.com/@types/mime/-/mime-3.0.3.tgz#886674659ce55fe7c6c06ec5ca7c0eb276a08f91"
integrity sha512-Wj+fqpTLtTbG7c0tH47dkahefpLKEbB+xAZuLq7b4/IDHPl/n6VoXcyUQ2bypFlbSwvCr0y+bD4euTTqTJsPxQ== integrity sha512-i8MBln35l856k5iOhKk2XJ4SeAWg75mLIpZB4v6imOagKL6twsukBZGDMNhdOVk7yRFTMPpfILocMos59Q1otQ==
"@types/mime@^1": "@types/mime@^1":
version "1.3.3" version "1.3.4"
resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.3.tgz#bbe64987e0eb05de150c305005055c7ad784a9ce" resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.4.tgz#a4ed836e069491414bab92c31fdea9e557aca0d9"
integrity sha512-Ys+/St+2VF4+xuY6+kDIXGxbNRO0mesVg0bbxEfB97Od1Vjpjx9KD1qxs64Gcb3CWPirk9Xe+PT4YiiHQ9T+eg== integrity sha512-1Gjee59G25MrQGk8bsNvC6fxNiRgUlGn2wlhGf95a59DrprnnHk80FIMMFG9XHMdrfsuA119ht06QPDXA1Z7tw==
"@types/minimatch@*": "@types/minimatch@*":
version "5.1.2" version "5.1.2"
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-5.1.2.tgz#07508b45797cb81ec3f273011b054cd0755eddca" resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-5.1.2.tgz#07508b45797cb81ec3f273011b054cd0755eddca"
integrity sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA== integrity sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==
"@types/node@*": "@types/node-forge@^1.3.0":
version "20.8.6" version "1.3.8"
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.8.6.tgz#0dbd4ebcc82ad0128df05d0e6f57e05359ee47fa" resolved "https://registry.yarnpkg.com/@types/node-forge/-/node-forge-1.3.8.tgz#044ad98354ff309a031a55a40ad122f3be1ac2bb"
integrity sha512-eWO4K2Ji70QzKUqRy6oyJWUeB7+g2cRagT3T/nxYibYcT4y2BDL8lqolRXjTHmkZCdJfIPaY73KbJAZmcryxTQ== integrity sha512-vGXshY9vim9CJjrpcS5raqSjEfKlJcWy2HNdgUasR66fAnVEYarrf1ULV4nfvpC1nZq/moA9qyqBcu83x+Jlrg==
dependencies: dependencies:
undici-types "~5.25.1" "@types/node" "*"
"@types/node@*":
version "20.8.10"
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.8.10.tgz#a5448b895c753ae929c26ce85cab557c6d4a365e"
integrity sha512-TlgT8JntpcbmKUFzjhsyhGfP2fsiz1Mv56im6enJ905xG1DAYesxJaeSbGqQmAw8OWPdhyJGhGSQGKRNJ45u9w==
dependencies:
undici-types "~5.26.4"
"@types/parse-json@^4.0.0": "@types/parse-json@^4.0.0":
version "4.0.0" version "4.0.1"
resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.1.tgz#27f7559836ad796cea31acb63163b203756a5b4e"
integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== integrity sha512-3YmXzzPAdOTVljVMkTMBdBEvlOLg2cDQaDhnnhT3nT9uDbnJzjWhKlzb+desT12Y7tGqaN6d+AbozcKzyL36Ng==
"@types/qs@*": "@types/qs@*":
version "6.9.8" version "6.9.9"
resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.8.tgz#f2a7de3c107b89b441e071d5472e6b726b4adf45" resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.9.tgz#66f7b26288f6799d279edf13da7ccd40d2fa9197"
integrity sha512-u95svzDlTysU5xecFNTgfFG5RUWu1A9P0VzgpcIiGZA9iraHOdSzcxMxQ55DyeRaGCSxQi7LxXDI4rzq/MYfdg== integrity sha512-wYLxw35euwqGvTDx6zfY1vokBFnsK0HNrzc6xNHchxfO2hpuRg74GbkEW7e3sSmPvj0TjCDT1VCa6OtHXnubsg==
"@types/range-parser@*": "@types/range-parser@*":
version "1.2.5" version "1.2.6"
resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.5.tgz#38bd1733ae299620771bd414837ade2e57757498" resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.6.tgz#7cb33992049fd7340d5b10c0098e104184dfcd2a"
integrity sha512-xrO9OoVPqFuYyR/loIHjnbvvyRZREYKLjxV4+dY6v3FQR3stQ9ZxIGkaclF7YhI9hfjpuTbu14hZEy94qKLtOA== integrity sha512-+0autS93xyXizIYiyL02FCY8N+KkKPhILhcUSA276HxzreZ16kl+cmwvV2qAM/PuCCwPXzOXOWhiPcw20uSFcA==
"@types/retry@0.12.0": "@types/retry@0.12.0":
version "0.12.0" version "0.12.0"
@ -1880,57 +1887,57 @@
integrity sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA== integrity sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==
"@types/send@*": "@types/send@*":
version "0.17.2" version "0.17.3"
resolved "https://registry.yarnpkg.com/@types/send/-/send-0.17.2.tgz#af78a4495e3c2b79bfbdac3955fdd50e03cc98f2" resolved "https://registry.yarnpkg.com/@types/send/-/send-0.17.3.tgz#81b2ea5a3a18aad357405af2d643ccbe5a09020b"
integrity sha512-aAG6yRf6r0wQ29bkS+x97BIs64ZLxeE/ARwyS6wrldMm3C1MdKwCcnnEwMC1slI8wuxJOpiUH9MioC0A0i+GJw== integrity sha512-/7fKxvKUoETxjFUsuFlPB9YndePpxxRAOfGC/yJdc9kTjTeP5kRCTzfnE8kPUKCeyiyIZu0YQ76s50hCedI1ug==
dependencies: dependencies:
"@types/mime" "^1" "@types/mime" "^1"
"@types/node" "*" "@types/node" "*"
"@types/serve-index@^1.9.1": "@types/serve-index@^1.9.1":
version "1.9.2" version "1.9.3"
resolved "https://registry.yarnpkg.com/@types/serve-index/-/serve-index-1.9.2.tgz#cb26e775678a8526b73a5d980a147518740aaecd" resolved "https://registry.yarnpkg.com/@types/serve-index/-/serve-index-1.9.3.tgz#af9403916eb6fbf7d6ec6f47b2a4c46eb3222cc9"
integrity sha512-asaEIoc6J+DbBKXtO7p2shWUpKacZOoMBEGBgPG91P8xhO53ohzHWGCs4ScZo5pQMf5ukQzVT9fhX1WzpHihig== integrity sha512-4KG+yMEuvDPRrYq5fyVm/I2uqAJSAwZK9VSa+Zf+zUq9/oxSSvy3kkIqyL+jjStv6UCVi8/Aho0NHtB1Fwosrg==
dependencies: dependencies:
"@types/express" "*" "@types/express" "*"
"@types/serve-static@*", "@types/serve-static@^1.13.10": "@types/serve-static@*", "@types/serve-static@^1.13.10":
version "1.15.3" version "1.15.4"
resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.3.tgz#2cfacfd1fd4520bbc3e292cca432d5e8e2e3ee61" resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.4.tgz#44b5895a68ca637f06c229119e1c774ca88f81b2"
integrity sha512-yVRvFsEMrv7s0lGhzrggJjNOSmZCdgCjw9xWrPr/kNNLp6FaDfMC1KaYl3TSJ0c58bECwNBMoQrZJ8hA8E1eFg== integrity sha512-aqqNfs1XTF0HDrFdlY//+SGUxmdSUbjeRXb5iaZc3x0/vMbYmdw9qvOgHWOyyLFxSSRnUuP5+724zBgfw8/WAw==
dependencies: dependencies:
"@types/http-errors" "*" "@types/http-errors" "*"
"@types/mime" "*" "@types/mime" "*"
"@types/node" "*" "@types/node" "*"
"@types/sockjs@^0.3.33": "@types/sockjs@^0.3.33":
version "0.3.34" version "0.3.35"
resolved "https://registry.yarnpkg.com/@types/sockjs/-/sockjs-0.3.34.tgz#43e10e549b36d2ba2589278f00f81b5d7ccda167" resolved "https://registry.yarnpkg.com/@types/sockjs/-/sockjs-0.3.35.tgz#f4a568c73d2a8071944bd6ffdca0d4e66810cd21"
integrity sha512-R+n7qBFnm/6jinlteC9DBL5dGiDGjWAvjo4viUanpnc/dG1y7uDoacXPIQ/PQEg1fI912SMHIa014ZjRpvDw4g== integrity sha512-tIF57KB+ZvOBpAQwSaACfEu7htponHXaFzP7RfKYgsOS0NoYnn+9+jzp7bbq4fWerizI3dTB4NfAZoyeQKWJLw==
dependencies: dependencies:
"@types/node" "*" "@types/node" "*"
"@types/webpack-env@^1.16.4": "@types/webpack-env@^1.16.4":
version "1.18.2" version "1.18.3"
resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.18.2.tgz#0264bc30c0c4a073118ce5b26c5ef143da4374df" resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.18.3.tgz#e81f769199a5609c751f34fcc6f6095ceac7831f"
integrity sha512-BFqcTHHTrrI8EBmIzNAmLPP3IqtEG9J1IPFWbPeS/F0/TGNmo0pI5svOa7JbMF9vSCXQCvJWT2gxLJNVuf9blw== integrity sha512-v4CH6FLBCftYGFAswDhzFLjKgucXsOkIf5Mzl8ZZhEtC6oye9whFInNPKszNB9AvX7JEZMtpXxWctih6addP+Q==
"@types/ws@^8.5.5": "@types/ws@^8.5.5":
version "8.5.7" version "8.5.8"
resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.7.tgz#1ca585074fe5d2c81dec7a3d451f244a2a6d83cb" resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.8.tgz#13efec7bd439d0bdf2af93030804a94f163b1430"
integrity sha512-6UrLjiDUvn40CMrAubXuIVtj2PEfKDffJS7ychvnPU44j+KVeXmdHHTgqcM/dxLUTHxlXHiFM8Skmb8ozGdTnQ== integrity sha512-flUksGIQCnJd6sZ1l5dqCEG/ksaoAg/eUwiLAGTJQcfgvZJKF++Ta4bJA6A5aPSJmsr+xlseHn4KLgVlNnvPTg==
dependencies: dependencies:
"@types/node" "*" "@types/node" "*"
"@types/yargs-parser@*": "@types/yargs-parser@*":
version "21.0.1" version "21.0.2"
resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.1.tgz#07773d7160494d56aa882d7531aac7319ea67c3b" resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.2.tgz#7bd04c5da378496ef1695a1008bf8f71847a8b8b"
integrity sha512-axdPBuLuEJt0c4yI5OZssC19K2Mq1uKdrfZBzuxLvaztgqUtFYZUNw7lETExPYJR9jdEoIg4mb7RQKRQzOkeGQ== integrity sha512-5qcvofLPbfjmBfKaLfj/+f+Sbd6pN4zl7w7VSVI5uz7m9QZTuB2aZAa2uo1wHFBNN2x6g/SoTkXmd8mQnQF2Cw==
"@types/yargs@^17.0.8": "@types/yargs@^17.0.8":
version "17.0.28" version "17.0.29"
resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.28.tgz#d106e4301fbacde3d1796ab27374dd16588ec851" resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.29.tgz#06aabc72497b798c643c812a8b561537fea760cf"
integrity sha512-N3e3fkS86hNhtk6BEnc0rj3zcehaxx8QWhCROJkqpl5Zaoi7nAic3jH8q94jVD3zu5LGk+PUB6KAiDmimYOEQw== integrity sha512-nacjqA3ee9zRF/++a3FUY1suHTFKZeHba2n8WeDw9cCVdmzmHpIxyzOJBcpHvvEmS8E9KqWlSnWHUkOrkhWcvA==
dependencies: dependencies:
"@types/yargs-parser" "*" "@types/yargs-parser" "*"
@ -2155,9 +2162,9 @@ acorn-walk@^7.0.0, acorn-walk@^7.1.1:
integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==
acorn-walk@^8.0.0: acorn-walk@^8.0.0:
version "8.2.0" version "8.3.0"
resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.3.0.tgz#2097665af50fd0cf7a2dfccd2b9368964e66540f"
integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== integrity sha512-FS7hV565M5l1R08MXqo8odwMTB02C2UqzB17RVgu9EyuYFBqJZ3/ZY97sQD5FewVu1UyDFc1yztUDrAwT0EypA==
acorn@^7.0.0, acorn@^7.1.1: acorn@^7.0.0, acorn@^7.1.1:
version "7.4.1" version "7.4.1"
@ -2165,9 +2172,9 @@ acorn@^7.0.0, acorn@^7.1.1:
integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==
acorn@^8.0.4, acorn@^8.0.5, acorn@^8.2.4, acorn@^8.7.1, acorn@^8.8.2: acorn@^8.0.4, acorn@^8.0.5, acorn@^8.2.4, acorn@^8.7.1, acorn@^8.8.2:
version "8.10.0" version "8.11.2"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.2.tgz#ca0d78b51895be5390a5903c5b3bdcdaf78ae40b"
integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== integrity sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==
adjust-sourcemap-loader@^4.0.0: adjust-sourcemap-loader@^4.0.0:
version "4.0.0" version "4.0.0"
@ -2211,7 +2218,7 @@ ajv-keywords@^5.1.0:
dependencies: dependencies:
fast-deep-equal "^3.1.3" fast-deep-equal "^3.1.3"
ajv@^6.12.4, ajv@^6.12.5: ajv@^6.12.5:
version "6.12.6" version "6.12.6"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4"
integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==
@ -2333,15 +2340,13 @@ at-least-node@^1.0.0:
resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2"
integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==
babel-loader@^8.2.5: babel-loader@^9.1.3:
version "8.3.0" version "9.1.3"
resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.3.0.tgz#124936e841ba4fe8176786d6ff28add1f134d6a8" resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-9.1.3.tgz#3d0e01b4e69760cc694ee306fe16d358aa1c6f9a"
integrity sha512-H8SvsMF+m9t15HNLMipppzkC+Y2Yq+v3SonZyU70RBL/h1gxPkH08Ot8pEE9Z4Kd+czyWJClmFS8qzIP9OZ04Q== integrity sha512-xG3ST4DglodGf8qSwv0MdeWLhrDsw/32QMdTO5T1ZIp9gQur0HkCyFs7Awskr10JKXFXwpAhiCuYX5oGXnRGbw==
dependencies: dependencies:
find-cache-dir "^3.3.1" find-cache-dir "^4.0.0"
loader-utils "^2.0.0" schema-utils "^4.0.0"
make-dir "^3.1.0"
schema-utils "^2.6.5"
babel-plugin-polyfill-corejs2@^0.4.6: babel-plugin-polyfill-corejs2@^0.4.6:
version "0.4.6" version "0.4.6"
@ -2353,12 +2358,12 @@ babel-plugin-polyfill-corejs2@^0.4.6:
semver "^6.3.1" semver "^6.3.1"
babel-plugin-polyfill-corejs3@^0.8.5: babel-plugin-polyfill-corejs3@^0.8.5:
version "0.8.5" version "0.8.6"
resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.5.tgz#a75fa1b0c3fc5bd6837f9ec465c0f48031b8cab1" resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.6.tgz#25c2d20002da91fe328ff89095c85a391d6856cf"
integrity sha512-Q6CdATeAvbScWPNLB8lzSO7fgUVBkQt6zLgNlfyeCr/EQaEQR+bWiBYYPYAFyE528BMjRhL+1QBMOI4jc/c5TA== integrity sha512-leDIc4l4tUgU7str5BWLS2h8q2N4Nf6lGZP6UrNDxdtfF2g69eJ5L0H7S8A5Ln/arfFAfHor5InAdZuIOwZdgQ==
dependencies: dependencies:
"@babel/helper-define-polyfill-provider" "^0.4.3" "@babel/helper-define-polyfill-provider" "^0.4.3"
core-js-compat "^3.32.2" core-js-compat "^3.33.1"
babel-plugin-polyfill-regenerator@^0.5.3: babel-plugin-polyfill-regenerator@^0.5.3:
version "0.5.3" version "0.5.3"
@ -2558,12 +2563,13 @@ cacache@^15.0.5:
unique-filename "^1.1.1" unique-filename "^1.1.1"
call-bind@^1.0.0, call-bind@^1.0.2: call-bind@^1.0.0, call-bind@^1.0.2:
version "1.0.2" version "1.0.5"
resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.5.tgz#6fa2b7845ce0ea49bf4d8b9ef64727a2c2e2e513"
integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== integrity sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==
dependencies: dependencies:
function-bind "^1.1.1" function-bind "^1.1.2"
get-intrinsic "^1.0.2" get-intrinsic "^1.2.1"
set-function-length "^1.1.1"
callsites@^3.0.0: callsites@^3.0.0:
version "3.1.0" version "3.1.0"
@ -2591,9 +2597,9 @@ caniuse-api@^3.0.0:
lodash.uniq "^4.5.0" lodash.uniq "^4.5.0"
caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001541: caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001541:
version "1.0.30001549" version "1.0.30001561"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001549.tgz#7d1a3dce7ea78c06ed72c32c2743ea364b3615aa" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001561.tgz#752f21f56f96f1b1a52e97aae98c57c562d5d9da"
integrity sha512-qRp48dPYSCYaP+KurZLhDYdVE+yEyht/3NlmcJgVQ2VMGt6JL36ndQ/7rgspdZsJuxDPFIo/OzBT2+GmIJ53BA== integrity sha512-NTt0DNoKe958Q0BE0j0c1V9jbUzhBxHIEJy7asmGrpE0yG63KTV7PLHPnK2E1O9RsQrQ081I3NLuXGS6zht3cw==
chalk@^2.3.2, chalk@^2.4.2: chalk@^2.3.2, chalk@^2.4.2:
version "2.4.2" version "2.4.2"
@ -2779,6 +2785,11 @@ commander@^8.3.0:
resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66"
integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==
common-path-prefix@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/common-path-prefix/-/common-path-prefix-3.0.0.tgz#7d007a7e07c58c4b4d5f433131a19141b29f11e0"
integrity sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==
commondir@^1.0.1: commondir@^1.0.1:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b"
@ -2869,17 +2880,17 @@ cookie@0.5.0:
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b"
integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==
core-js-compat@^3.31.0, core-js-compat@^3.32.2: core-js-compat@^3.31.0, core-js-compat@^3.33.1:
version "3.33.0" version "3.33.2"
resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.33.0.tgz#24aa230b228406450b2277b7c8bfebae932df966" resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.33.2.tgz#3ea4563bfd015ad4e4b52442865b02c62aba5085"
integrity sha512-0w4LcLXsVEuNkIqwjjf9rjCoPhK8uqA4tMRh4Ge26vfLtUutshn+aRJU21I9LCJlh2QQHfisNToLjw1XEJLTWw== integrity sha512-axfo+wxFVxnqf8RvxTzoAlzW4gRoacrHeoFlc9n0x50+7BEyZL/Rt3hicaED1/CEd7I6tPCPVUYcJwCMO5XUYw==
dependencies: dependencies:
browserslist "^4.22.1" browserslist "^4.22.1"
core-js@^3.23.0: core-js@^3.23.0:
version "3.33.0" version "3.33.2"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.33.0.tgz#70366dbf737134761edb017990cf5ce6c6369c40" resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.33.2.tgz#312bbf6996a3a517c04c99b9909cdd27138d1ceb"
integrity sha512-HoZr92+ZjFEKar5HS6MC776gYslNOKHt75mEBKWKnPeFDpZ6nH5OeF3S6HFT1mUAUZKrzkez05VboaX8myjSuw== integrity sha512-XeBzWI6QL3nJQiHmdzbAOiMYqjrb7hwU7A39Qhvd/POSa/t9E1AeZyEZx3fNvp/vtM8zXwhoL0FsiS0hD0pruQ==
core-util-is@~1.0.0: core-util-is@~1.0.0:
version "1.0.3" version "1.0.3"
@ -2907,9 +2918,9 @@ cross-spawn@^7.0.3:
which "^2.0.1" which "^2.0.1"
crypto-js@^4.0.0: crypto-js@^4.0.0:
version "4.1.1" version "4.2.0"
resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-4.1.1.tgz#9e485bcf03521041bd85844786b83fb7619736cf" resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-4.2.0.tgz#4d931639ecdfd12ff80e8186dba6af2c2e856631"
integrity sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw== integrity sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==
css-declaration-sorter@^6.3.1: css-declaration-sorter@^6.3.1:
version "6.4.1" version "6.4.1"
@ -3165,11 +3176,11 @@ data-urls@^2.0.0:
whatwg-url "^8.0.0" whatwg-url "^8.0.0"
datatables.net-bs5@>=1.13.4, datatables.net-bs5@^1.10.20: datatables.net-bs5@>=1.13.4, datatables.net-bs5@^1.10.20:
version "1.13.6" version "1.13.7"
resolved "https://registry.yarnpkg.com/datatables.net-bs5/-/datatables.net-bs5-1.13.6.tgz#33bf10c0844bb08e17327d841089c1f277f796ff" resolved "https://registry.yarnpkg.com/datatables.net-bs5/-/datatables.net-bs5-1.13.7.tgz#21031683f963c631b3ea7c308b9bcf0044076795"
integrity sha512-lXroZoXhLhDulp8gvU7y7wBherg38SbLMGXcHwbnj+XXh4Hvy+d67zSPYbrVI3YiRwYq+aCx15G5qmMj7KjYQg== integrity sha512-saPdg9YEUlbnRn8BuMvLSUhcNMk3cMaLUxmeGOdoOvtSqTjWCp3WYLkSOXuW7SOsdkC9eQnC+DrFnHyMba7LOA==
dependencies: dependencies:
datatables.net ">=1.13.4" datatables.net "1.13.7"
jquery ">=1.7" jquery ">=1.7"
datatables.net-buttons-bs5@^2.2.2: datatables.net-buttons-bs5@^2.2.2:
@ -3257,10 +3268,10 @@ datatables.net-select@>=1.6.2:
datatables.net ">=1.13.4" datatables.net ">=1.13.4"
jquery ">=1.7" jquery ">=1.7"
datatables.net@>=1.13.4: datatables.net@1.13.7, datatables.net@>=1.13.4:
version "1.13.6" version "1.13.7"
resolved "https://registry.yarnpkg.com/datatables.net/-/datatables.net-1.13.6.tgz#6e282adbbb2732e8df495611b8bb54e19f7a943e" resolved "https://registry.yarnpkg.com/datatables.net/-/datatables.net-1.13.7.tgz#8b130845a59ab16fedd760ecf4b96d96418aca1b"
integrity sha512-rHNcnW+yEP9me82/KmRcid5eKrqPqW3+I/p1TwqCW3c/7GRYYkDyF6aJQOQ9DNS/pw+nyr4BVpjyJ3yoZXiFPg== integrity sha512-lbmcCSrMU8VTaGwgCxWs/jbP8NVJlzXaUkK3SiiZY7tTjRp7XJw4InlOU+XUVZ4i4B2GBxue02/P5iVto1CGDg==
dependencies: dependencies:
jquery ">=1.7" jquery ">=1.7"
@ -3307,7 +3318,7 @@ default-gateway@^6.0.3:
dependencies: dependencies:
execa "^5.0.0" execa "^5.0.0"
define-data-property@^1.0.1: define-data-property@^1.0.1, define-data-property@^1.1.1:
version "1.1.1" version "1.1.1"
resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.1.tgz#c35f7cd0ab09883480d12ac5cb213715587800b3" resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.1.tgz#c35f7cd0ab09883480d12ac5cb213715587800b3"
integrity sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ== integrity sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==
@ -3503,9 +3514,9 @@ ee-first@1.1.1:
integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==
electron-to-chromium@^1.4.535: electron-to-chromium@^1.4.535:
version "1.4.554" version "1.4.576"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.554.tgz#04e09c2ee31dc0f1546174033809b54cc372740b" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.576.tgz#0c6940fdc0d60f7e34bd742b29d8fa847c9294d1"
integrity sha512-Q0umzPJjfBrrj8unkONTgbKQXzXRrH7sVV7D9ea2yBV3Oaogz991yhbpfvo2LMNkJItmruXTEzVpP9cp7vaIiQ== integrity sha512-yXsZyXJfAqzWk1WKryr0Wl0MN2D47xodPvEEwlVePBnhU5E7raevLQR+E6b9JAD3GfL/7MbAL9ZtWQQPcLx7wA==
emoji-regex@^8.0.0: emoji-regex@^8.0.0:
version "8.0.0" version "8.0.0"
@ -3546,9 +3557,9 @@ entities@^4.2.0:
integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw== integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==
envinfo@^7.7.3: envinfo@^7.7.3:
version "7.10.0" version "7.11.0"
resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.10.0.tgz#55146e3909cc5fe63c22da63fb15b05aeac35b13" resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.11.0.tgz#c3793f44284a55ff8c82faf1ffd91bc6478ea01f"
integrity sha512-ZtUjZO6l5mwTHvc1L9+1q5p/R3wTopcfqMW8r5t8SJSKqeVI/LtajORwRFEKpEFuekjD0VBjwu1HMxL4UalIRw== integrity sha512-G9/6xF1FPbIw0TtalAMaVPpiq2aDEuKLXM314jPVAO9r2fo2a4BLqMNkmRS7O/xPPZ+COAhGIz3ETvHEV3eUcg==
error-ex@^1.3.1: error-ex@^1.3.1:
version "1.3.2" version "1.3.2"
@ -3936,6 +3947,14 @@ find-cache-dir@^3.3.1:
make-dir "^3.0.2" make-dir "^3.0.2"
pkg-dir "^4.1.0" pkg-dir "^4.1.0"
find-cache-dir@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-4.0.0.tgz#a30ee0448f81a3990708f6453633c733e2f6eec2"
integrity sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg==
dependencies:
common-path-prefix "^3.0.0"
pkg-dir "^7.0.0"
find-up@^3.0.0: find-up@^3.0.0:
version "3.0.0" version "3.0.0"
resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73"
@ -3951,6 +3970,19 @@ find-up@^4.0.0:
locate-path "^5.0.0" locate-path "^5.0.0"
path-exists "^4.0.0" path-exists "^4.0.0"
find-up@^6.3.0:
version "6.3.0"
resolved "https://registry.yarnpkg.com/find-up/-/find-up-6.3.0.tgz#2abab3d3280b2dc7ac10199ef324c4e002c8c790"
integrity sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==
dependencies:
locate-path "^7.1.0"
path-exists "^5.0.0"
flat@^5.0.2:
version "5.0.2"
resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241"
integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==
follow-redirects@^1.0.0: follow-redirects@^1.0.0:
version "1.15.3" version "1.15.3"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.3.tgz#fe2f3ef2690afce7e82ed0b44db08165b207123a" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.3.tgz#fe2f3ef2690afce7e82ed0b44db08165b207123a"
@ -4007,7 +4039,7 @@ fsevents@~2.3.2:
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6"
integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==
function-bind@^1.1.1: function-bind@^1.1.2:
version "1.1.2" version "1.1.2"
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c"
integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==
@ -4027,15 +4059,15 @@ get-assigned-identifiers@^1.1.0:
resolved "https://registry.yarnpkg.com/get-assigned-identifiers/-/get-assigned-identifiers-1.2.0.tgz#6dbf411de648cbaf8d9169ebb0d2d576191e2ff1" resolved "https://registry.yarnpkg.com/get-assigned-identifiers/-/get-assigned-identifiers-1.2.0.tgz#6dbf411de648cbaf8d9169ebb0d2d576191e2ff1"
integrity sha512-mBBwmeGTrxEMO4pMaaf/uUEFHnYtwr8FTe8Y/mer4rcV/bye0qGm6pw1bGZFGStxC5O76c5ZAVBGnqHmOaJpdQ== integrity sha512-mBBwmeGTrxEMO4pMaaf/uUEFHnYtwr8FTe8Y/mer4rcV/bye0qGm6pw1bGZFGStxC5O76c5ZAVBGnqHmOaJpdQ==
get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.1: get-intrinsic@^1.0.2, get-intrinsic@^1.1.3, get-intrinsic@^1.2.1, get-intrinsic@^1.2.2:
version "1.2.1" version "1.2.2"
resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.1.tgz#d295644fed4505fc9cde952c37ee12b477a83d82" resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.2.tgz#281b7622971123e1ef4b3c90fd7539306da93f3b"
integrity sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw== integrity sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==
dependencies: dependencies:
function-bind "^1.1.1" function-bind "^1.1.2"
has "^1.0.3"
has-proto "^1.0.1" has-proto "^1.0.1"
has-symbols "^1.0.3" has-symbols "^1.0.3"
hasown "^2.0.0"
get-port@^3.1.0: get-port@^3.1.0:
version "3.2.0" version "3.2.0"
@ -4160,11 +4192,11 @@ has-flag@^4.0.0:
integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
has-property-descriptors@^1.0.0: has-property-descriptors@^1.0.0:
version "1.0.0" version "1.0.1"
resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz#610708600606d36961ed04c196193b6a607fa861" resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz#52ba30b6c5ec87fd89fa574bc1c39125c6f65340"
integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ== integrity sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==
dependencies: dependencies:
get-intrinsic "^1.1.1" get-intrinsic "^1.2.2"
has-proto@^1.0.1: has-proto@^1.0.1:
version "1.0.1" version "1.0.1"
@ -4183,11 +4215,18 @@ has-tostringtag@^1.0.0:
dependencies: dependencies:
has-symbols "^1.0.2" has-symbols "^1.0.2"
has@^1.0.1, has@^1.0.3: has@^1.0.1:
version "1.0.4" version "1.0.4"
resolved "https://registry.yarnpkg.com/has/-/has-1.0.4.tgz#2eb2860e000011dae4f1406a86fe80e530fb2ec6" resolved "https://registry.yarnpkg.com/has/-/has-1.0.4.tgz#2eb2860e000011dae4f1406a86fe80e530fb2ec6"
integrity sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ== integrity sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==
hasown@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.0.tgz#f4c513d454a57b7c7e1650778de226b11700546c"
integrity sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==
dependencies:
function-bind "^1.1.2"
hpack.js@^2.1.6: hpack.js@^2.1.6:
version "2.1.6" version "2.1.6"
resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2" resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2"
@ -4387,13 +4426,13 @@ interpret@^2.2.0:
integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw== integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==
intl-messageformat@^10.2.5: intl-messageformat@^10.2.5:
version "10.5.3" version "10.5.4"
resolved "https://registry.yarnpkg.com/intl-messageformat/-/intl-messageformat-10.5.3.tgz#db0779d4a1988faa2977d76574489b7a25f0d5d0" resolved "https://registry.yarnpkg.com/intl-messageformat/-/intl-messageformat-10.5.4.tgz#7b212b083f1b354d7e282518e78057e025134af9"
integrity sha512-TzKn1uhJBMyuKTO4zUX47SU+d66fu1W9tVzIiZrQ6hBqQQeYscBMIzKL/qEXnFbJrH9uU5VV3+T5fWib4SIcKA== integrity sha512-z+hrFdiJ/heRYlzegrdFYqU1m/KOMOVMqNilIArj+PbsuU8TNE7v4TWdQgSoxlxbT4AcZH3Op3/Fu15QTp+W1w==
dependencies: dependencies:
"@formatjs/ecma402-abstract" "1.17.2" "@formatjs/ecma402-abstract" "1.17.2"
"@formatjs/fast-memoize" "2.2.0" "@formatjs/fast-memoize" "2.2.0"
"@formatjs/icu-messageformat-parser" "2.6.2" "@formatjs/icu-messageformat-parser" "2.7.0"
tslib "^2.4.0" tslib "^2.4.0"
ipaddr.js@1.9.1: ipaddr.js@1.9.1:
@ -4427,11 +4466,11 @@ is-binary-path@~2.1.0:
binary-extensions "^2.0.0" binary-extensions "^2.0.0"
is-core-module@^2.13.0: is-core-module@^2.13.0:
version "2.13.0" version "2.13.1"
resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.0.tgz#bb52aa6e2cbd49a30c2ba68c42bf3435ba6072db" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.1.tgz#ad0d7532c6fea9da1ebdc82742d74525c6273384"
integrity sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ== integrity sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==
dependencies: dependencies:
has "^1.0.3" hasown "^2.0.0"
is-date-object@^1.0.1: is-date-object@^1.0.1:
version "1.0.5" version "1.0.5"
@ -4774,6 +4813,13 @@ locate-path@^5.0.0:
dependencies: dependencies:
p-locate "^4.1.0" p-locate "^4.1.0"
locate-path@^7.1.0:
version "7.2.0"
resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-7.2.0.tgz#69cb1779bd90b35ab1e771e1f2f89a202c2a8a8a"
integrity sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==
dependencies:
p-locate "^6.0.0"
lodash-es@4.17.21: lodash-es@4.17.21:
version "4.17.21" version "4.17.21"
resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee" resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee"
@ -4845,7 +4891,7 @@ magic-string@0.25.1:
dependencies: dependencies:
sourcemap-codec "^1.4.1" sourcemap-codec "^1.4.1"
make-dir@^3.0.2, make-dir@^3.1.0: make-dir@^3.0.2:
version "3.1.0" version "3.1.0"
resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f"
integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==
@ -4870,9 +4916,9 @@ marked@4.0.12:
integrity sha512-hgibXWrEDNBWgGiK18j/4lkS6ihTe9sxtV4Q1OQppb/0zzyPSzoFANBa5MfsG/zgsWklmNnhm0XACZOH/0HBiQ== integrity sha512-hgibXWrEDNBWgGiK18j/4lkS6ihTe9sxtV4Q1OQppb/0zzyPSzoFANBa5MfsG/zgsWklmNnhm0XACZOH/0HBiQ==
marked@^9.1.0: marked@^9.1.0:
version "9.1.2" version "9.1.5"
resolved "https://registry.yarnpkg.com/marked/-/marked-9.1.2.tgz#a54ca772d2b5a43de7d8ed40111354b4b7985527" resolved "https://registry.yarnpkg.com/marked/-/marked-9.1.5.tgz#fcada4702ea64a5c05a4ff0e0639628aac8a1e5f"
integrity sha512-qoKMJqK0w6vkLk8+KnKZAH6neUZSNaQqVZ/h2yZ9S7CbLuFHyS2viB0jnqcWF9UKjwsAbMrQtnQhdmdvOVOw9w== integrity sha512-14QG3shv8Kg/xc0Yh6TNkMj90wXH9mmldi5941I2OevfJ/FQAFLEwtwU2/FfgSAOMlWHrEukWSGQf8MiVYNG2A==
mdn-data@2.0.14: mdn-data@2.0.14:
version "2.0.14" version "2.0.14"
@ -5133,9 +5179,9 @@ object-assign@^4.0.1:
integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==
object-inspect@^1.6.0, object-inspect@^1.9.0: object-inspect@^1.6.0, object-inspect@^1.9.0:
version "1.13.0" version "1.13.1"
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.0.tgz#42695d3879e1cd5bda6df5062164d80c996e23e2" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.1.tgz#b96c6109324ccfef6b12216a956ca4dc2ff94bc2"
integrity sha512-HQ4J+ic8hKrgIt3mqk6cVOVrW2ozL4KdvHlqpBv9vDYWx9ysAgENAdvy4FoGF+KFdhR7nQTNm5J0ctAeOwn+3g== integrity sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==
object-is@^1.0.1: object-is@^1.0.1:
version "1.1.5" version "1.1.5"
@ -5221,6 +5267,13 @@ p-limit@^3.0.2:
dependencies: dependencies:
yocto-queue "^0.1.0" yocto-queue "^0.1.0"
p-limit@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-4.0.0.tgz#914af6544ed32bfa54670b061cafcbd04984b644"
integrity sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==
dependencies:
yocto-queue "^1.0.0"
p-locate@^3.0.0: p-locate@^3.0.0:
version "3.0.0" version "3.0.0"
resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4"
@ -5235,6 +5288,13 @@ p-locate@^4.1.0:
dependencies: dependencies:
p-limit "^2.2.0" p-limit "^2.2.0"
p-locate@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-6.0.0.tgz#3da9a49d4934b901089dca3302fa65dc5a05c04f"
integrity sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==
dependencies:
p-limit "^4.0.0"
p-map@^2.0.0: p-map@^2.0.0:
version "2.1.0" version "2.1.0"
resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175" resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175"
@ -5314,6 +5374,11 @@ path-exists@^4.0.0:
resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3"
integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==
path-exists@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-5.0.0.tgz#a6aad9489200b21fab31e49cf09277e5116fb9e7"
integrity sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==
path-is-absolute@^1.0.0: path-is-absolute@^1.0.0:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
@ -5393,6 +5458,13 @@ pkg-dir@^4.1.0, pkg-dir@^4.2.0:
dependencies: dependencies:
find-up "^4.0.0" find-up "^4.0.0"
pkg-dir@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-7.0.0.tgz#8f0c08d6df4476756c5ff29b3282d0bab7517d11"
integrity sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==
dependencies:
find-up "^6.3.0"
pkg-up@^3.1.0: pkg-up@^3.1.0:
version "3.1.0" version "3.1.0"
resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-3.1.0.tgz#100ec235cc150e4fd42519412596a28512a0def5" resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-3.1.0.tgz#100ec235cc150e4fd42519412596a28512a0def5"
@ -5945,9 +6017,9 @@ psl@^1.1.33:
integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag== integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==
punycode@^2.1.0, punycode@^2.1.1: punycode@^2.1.0, punycode@^2.1.1:
version "2.3.0" version "2.3.1"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5"
integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==
qs@6.11.0: qs@6.11.0:
version "6.11.0" version "6.11.0"
@ -6251,15 +6323,6 @@ saxes@^5.0.1:
dependencies: dependencies:
xmlchars "^2.2.0" xmlchars "^2.2.0"
schema-utils@^2.6.5:
version "2.7.1"
resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.1.tgz#1ca4f32d1b24c590c203b8e7a50bf0ea4cd394d7"
integrity sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==
dependencies:
"@types/json-schema" "^7.0.5"
ajv "^6.12.4"
ajv-keywords "^3.5.2"
schema-utils@^3.0.0, schema-utils@^3.1.1, schema-utils@^3.2.0: schema-utils@^3.0.0, schema-utils@^3.1.1, schema-utils@^3.2.0:
version "3.3.0" version "3.3.0"
resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.3.0.tgz#f50a88877c3c01652a15b622ae9e9795df7a60fe" resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.3.0.tgz#f50a88877c3c01652a15b622ae9e9795df7a60fe"
@ -6303,10 +6366,11 @@ select@^1.1.2:
integrity sha512-OwpTSOfy6xSs1+pwcNrv0RBMOzI39Lp3qQKUTPVVPRjCdNa5JH/oPRiqsesIskK8TVgmRiHwO4KXlV2Li9dANA== integrity sha512-OwpTSOfy6xSs1+pwcNrv0RBMOzI39Lp3qQKUTPVVPRjCdNa5JH/oPRiqsesIskK8TVgmRiHwO4KXlV2Li9dANA==
selfsigned@^2.1.1: selfsigned@^2.1.1:
version "2.1.1" version "2.4.1"
resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-2.1.1.tgz#18a7613d714c0cd3385c48af0075abf3f266af61" resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-2.4.1.tgz#560d90565442a3ed35b674034cec4e95dceb4ae0"
integrity sha512-GSL3aowiF7wa/WtSFwnUrludWFoNhftq8bUkH9pkzjpN2XSPOAYEgg6e0sS9s0rZwgJzJiQRPU18A6clnoW5wQ== integrity sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==
dependencies: dependencies:
"@types/node-forge" "^1.3.0"
node-forge "^1" node-forge "^1"
semver@^6.0.0, semver@^6.3.1: semver@^6.0.0, semver@^6.3.1:
@ -6377,6 +6441,16 @@ serve-static@1.15.0:
parseurl "~1.3.3" parseurl "~1.3.3"
send "0.18.0" send "0.18.0"
set-function-length@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.1.1.tgz#4bc39fafb0307224a33e106a7d35ca1218d659ed"
integrity sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==
dependencies:
define-data-property "^1.1.1"
get-intrinsic "^1.2.1"
gopd "^1.0.1"
has-property-descriptors "^1.0.0"
set-function-name@^2.0.0: set-function-name@^2.0.0:
version "2.0.1" version "2.0.1"
resolved "https://registry.yarnpkg.com/set-function-name/-/set-function-name-2.0.1.tgz#12ce38b7954310b9f61faa12701620a0c882793a" resolved "https://registry.yarnpkg.com/set-function-name/-/set-function-name-2.0.1.tgz#12ce38b7954310b9f61faa12701620a0c882793a"
@ -6784,9 +6858,9 @@ terser-webpack-plugin@^5.3.0, terser-webpack-plugin@^5.3.7:
terser "^5.16.8" terser "^5.16.8"
terser@^5.16.8, terser@^5.3.4: terser@^5.16.8, terser@^5.3.4:
version "5.21.0" version "5.24.0"
resolved "https://registry.yarnpkg.com/terser/-/terser-5.21.0.tgz#d2b27e92b5e56650bc83b6defa00a110f0b124b2" resolved "https://registry.yarnpkg.com/terser/-/terser-5.24.0.tgz#4ae50302977bca4831ccc7b4fef63a3c04228364"
integrity sha512-WtnFKrxu9kaoXuiZFSGrcAvvBqAdmKx0SFNmVNYdJamMu9yyN3I/QF0FbH4QcqJQ+y1CJnzxGIKH0cSj+FGYRw== integrity sha512-ZpGR4Hy3+wBEzVEnHvstMvqpD/nABNelQn/z2r0fjVWGQsN3bpOLzQlqDxmb4CDZnXq5lpjnQ+mHQLAOpfM5iw==
dependencies: dependencies:
"@jridgewell/source-map" "^0.3.3" "@jridgewell/source-map" "^0.3.3"
acorn "^8.8.2" acorn "^8.8.2"
@ -6854,9 +6928,9 @@ toidentifier@1.0.1:
integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==
tom-select@^2.1.0: tom-select@^2.1.0:
version "2.2.2" version "2.3.1"
resolved "https://registry.yarnpkg.com/tom-select/-/tom-select-2.2.2.tgz#8e5f9296e6d80254feccb57f0986bd6c44d126e2" resolved "https://registry.yarnpkg.com/tom-select/-/tom-select-2.3.1.tgz#df338d9082874cd0bceb3bee87ed0184447c47f1"
integrity sha512-igGah1yY6yhrnN2h/Ky8I5muw/nE/YQxIsEZoYu5qaA4bsRibvKto3s8QZZosKpOd0uO8fNYhRfAwgHB4IAYew== integrity sha512-QS4vnOcB6StNGqX4sGboGXL2fkhBF2gIBB+8Hwv30FZXYPn0CyYO8kkdATRvwfCTThxiR4WcXwKJZ3cOmtI9eg==
dependencies: dependencies:
"@orchidjs/sifter" "^1.0.3" "@orchidjs/sifter" "^1.0.3"
"@orchidjs/unicode-variants" "^1.0.4" "@orchidjs/unicode-variants" "^1.0.4"
@ -6946,10 +7020,10 @@ typescript@^4.0.2:
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a"
integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==
undici-types@~5.25.1: undici-types@~5.26.4:
version "5.25.3" version "5.26.5"
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.25.3.tgz#e044115914c85f0bcbb229f346ab739f064998c3" resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617"
integrity sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA== integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==
unicode-canonical-property-names-ecmascript@^2.0.0: unicode-canonical-property-names-ecmascript@^2.0.0:
version "2.0.0" version "2.0.0"
@ -7010,9 +7084,9 @@ universalify@^0.2.0:
integrity sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg== integrity sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==
universalify@^2.0.0: universalify@^2.0.0:
version "2.0.0" version "2.0.1"
resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.1.tgz#168efc2180964e6386d061e094df61afe239b18d"
integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== integrity sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==
unpipe@1.0.0, unpipe@~1.0.0: unpipe@1.0.0, unpipe@~1.0.0:
version "1.0.0" version "1.0.0"
@ -7200,11 +7274,12 @@ webpack-dev-server@^4.8.0:
ws "^8.13.0" ws "^8.13.0"
webpack-merge@^5.7.3: webpack-merge@^5.7.3:
version "5.9.0" version "5.10.0"
resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.9.0.tgz#dc160a1c4cf512ceca515cc231669e9ddb133826" resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.10.0.tgz#a3ad5d773241e9c682803abf628d4cd62b8a4177"
integrity sha512-6NbRQw4+Sy50vYNTw7EyOn41OZItPiXB8GNv3INSoe3PSFaHJEz3SHTrYVaRm2LilNGnFUzh0FAwqPEmU/CwDg== integrity sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==
dependencies: dependencies:
clone-deep "^4.0.1" clone-deep "^4.0.1"
flat "^5.0.2"
wildcard "^2.0.0" wildcard "^2.0.0"
webpack-notifier@^1.15.0: webpack-notifier@^1.15.0:
@ -7379,3 +7454,8 @@ yocto-queue@^0.1.0:
version "0.1.0" version "0.1.0"
resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==
yocto-queue@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-1.0.0.tgz#7f816433fb2cbc511ec8bf7d263c3b58a1a3c251"
integrity sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==