1
0
mirror of https://github.com/flarum/core.git synced 2025-08-13 20:04:24 +02:00

Compare commits

..

1 Commits

Author SHA1 Message Date
Sami Mazouz
7ddc8a60dd feat: prioritize title score in fulltext search
Signed-off-by: Sami Mazouz <sychocouldy@gmail.com>
2023-02-23 22:30:41 +01:00
15 changed files with 115 additions and 211 deletions

2
extensions/flags/js/dist/forum.js generated vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,7 +1,6 @@
import type Flag from '../forum/models/Flag';
import type FlagListState from '../forum/states/FlagListState';
import type Mithril from 'mithril';
import type ItemList from 'flarum/common/utils/ItemList';
import Flag from '../forum/models/Flag';
import FlagListState from '../forum/states/FlagListState';
import Mithril from 'mithril';
declare module 'flarum/common/models/Post' {
export default interface Post {
@@ -18,8 +17,6 @@ declare module 'flarum/forum/ForumApplication' {
declare module 'flarum/forum/components/Post' {
export default interface Post {
dismissFlag: (body: any) => Promise<any>;
flagActionItems: () => ItemList<Mithril.Children>;
flagReason: (flag: Flag) => Mithril.Children;
}
}

View File

@@ -1,14 +1,10 @@
import { extend } from 'flarum/common/extend';
import app from 'flarum/forum/app';
import Post from 'flarum/forum/components/Post';
import CommentPost from 'flarum/forum/components/CommentPost';
import Button from 'flarum/common/components/Button';
import ItemList from 'flarum/common/utils/ItemList';
import PostControls from 'flarum/forum/utils/PostControls';
import humanTime from 'flarum/common/utils/humanTime';
import isObject from 'flarum/common/utils/isObject';
import type Flag from './models/Flag';
import type Mithril from 'mithril';
export default function () {
extend(Post.prototype, 'elementAttrs', function (attrs) {
@@ -25,7 +21,7 @@ export default function () {
this.subtree.invalidate();
if (app.flags.cache) {
app.flags.cache.some((flag: Flag, i: number) => {
app.flags.cache.some((flag, i) => {
if (flag.post() === post) {
app.flags.cache.splice(i, 1);
@@ -43,8 +39,6 @@ export default function () {
return true;
}
return false;
});
}
@@ -56,17 +50,16 @@ export default function () {
};
Post.prototype.flagActionItems = function () {
const items = new ItemList<Mithril.Children>();
const items = new ItemList();
const controls = PostControls.destructiveControls(this.attrs.post, this);
const controls = PostControls.destructiveControls(this.attrs.post);
Object.keys(controls.items).forEach((k) => {
const item = controls.get(k);
const attrs = isObject(item) && 'attrs' in item ? item.attrs : {};
const attrs = controls.get(k).attrs;
attrs.className = 'Button';
extend(attrs, 'onclick', () => this.dismissFlag({}));
extend(attrs, 'onclick', () => this.dismissFlag());
});
items.add('controls', <div className="ButtonGroup">{controls.toArray()}</div>);
@@ -88,16 +81,12 @@ export default function () {
if (!flags.length) return;
if (post.isHidden() && this instanceof CommentPost) {
this.revealContent = true;
}
if (!isObject(vdom) || !('unshift' in vdom)) return;
if (post.isHidden()) this.revealContent = true;
vdom.unshift(
<div className="Post-flagged">
<div className="Post-flagged-flags">
{flags.map((flag: Flag) => (
{flags.map((flag) => (
<div className="Post-flagged-flag">{this.flagReason(flag)}</div>
))}
</div>
@@ -122,7 +111,5 @@ export default function () {
detail ? <span className="Post-flagged-detail">{detail}</span> : '',
];
}
return null;
};
}

View File

@@ -1,6 +1,4 @@
export default class FlagListState {
index = 0;
constructor(app) {
this.app = app;

View File

@@ -88,7 +88,8 @@
"wikimedia/less.php": "^3.2"
},
"require-dev": {
"flarum/testing": "^1.0.0"
"flarum/testing": "^1.0.0",
"symfony/var-dumper": "^6.0"
},
"autoload": {
"psr-4": {

View File

@@ -18,7 +18,6 @@ core:
custom_footer_text: => core.ref.custom_footer_text
custom_header_heading: Custom Header
custom_header_text: => core.ref.custom_header_text
custom_styles_cannot_use_less_features: "The @import and data-uri features are not allowed in custom LESS."
custom_styles_heading: Custom Styles
custom_styles_text: Customize your forum's appearance by adding your own Less/CSS code to be applied on top of Flarum's default styles.
dark_mode_label: Dark Mode

View File

@@ -99,7 +99,7 @@ return function (RouteCollection $map, RouteHandlerFactory $route) {
$map->delete(
'/users/{id}',
'users.delete',
$route->toController(Controller\DeleteUserController::class)
$route->toController(Controller\DeleteAccessTokenController::class)
);
// Upload avatar

View File

@@ -30,8 +30,9 @@ class FulltextGambit implements GambitInterface
$query = $search->getQuery();
$grammar = $query->getGrammar();
// We give discussion title search score a higher weight than post.
$discussionSubquery = Discussion::select('id')
->selectRaw('NULL as score')
->selectRaw('MATCH('.$grammar->wrap('discussions.title').') AGAINST (?)*1.5 as score', [$bit])
->selectRaw('first_post_id as most_relevant_post_id')
->whereRaw('MATCH('.$grammar->wrap('discussions.title').') AGAINST (? IN BOOLEAN MODE)', [$bit]);
@@ -61,8 +62,7 @@ class FulltextGambit implements GambitInterface
->groupBy('discussions.id')
->addBinding($subquery->getBindings(), 'join');
$search->setDefaultSort(function ($query) use ($grammar, $bit) {
$query->orderByRaw('MATCH('.$grammar->wrap('discussions.title').') AGAINST (?) desc', [$bit]);
$search->setDefaultSort(function ($query) {
$query->orderBy('posts_ft.score', 'desc');
});

View File

@@ -21,7 +21,6 @@ use Illuminate\Filesystem\FilesystemAdapter;
use League\Flysystem\Adapter\NullAdapter;
use League\Flysystem\Filesystem;
use Less_Exception_Parser;
use Symfony\Contracts\Translation\TranslatorInterface;
/**
* @internal
@@ -62,15 +61,6 @@ class ValidateCustomLess
return;
}
// Restrict what features can be used in custom LESS
if (isset($event->settings['custom_less']) && preg_match('/@import|data-uri\s*\(/i', $event->settings['custom_less'])) {
$translator = $this->container->make(TranslatorInterface::class);
throw new ValidationException([
'custom_less' => $translator->trans('core.admin.appearance.custom_styles_cannot_use_less_features')
]);
}
// We haven't saved the settings yet, but we want to trial a full
// recompile of the CSS to see if this custom LESS will break
// anything. In order to do that, we will temporarily override the

View File

@@ -36,17 +36,19 @@ class ListWithFulltextSearchTest extends TestCase
['id' => 3, 'title' => 'not in title either', 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 1, 'comment_count' => 1],
['id' => 4, 'title' => 'not in title or text', 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 1, 'comment_count' => 1],
['id' => 5, 'title' => 'తెలుగు', 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 1, 'comment_count' => 1],
['id' => 6, 'title' => '支持中文吗', 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 1, 'comment_count' => 1],
['id' => 6, 'title' => '支持中文吗 acme', 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 1, 'comment_count' => 1],
['id' => 7, 'title' => 'add "acme for life" module!', 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 1, 'comment_count' => 1],
]);
$this->database()->table('posts')->insert([
['id' => 1, 'discussion_id' => 1, 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>not in text</p></t>'],
['id' => 2, 'discussion_id' => 2, 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>lightsail in text</p></t>'],
['id' => 3, 'discussion_id' => 2, 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>another lightsail for discussion 2!</p></t>'],
['id' => 3, 'discussion_id' => 2, 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>another lightsail for discussion 2! acme for life</p></t>'],
['id' => 4, 'discussion_id' => 3, 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>just one lightsail for discussion 3.</p></t>'],
['id' => 5, 'discussion_id' => 4, 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>not in title or text</p></t>'],
['id' => 5, 'discussion_id' => 4, 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>not in title or text (acme)</p></t>'],
['id' => 6, 'discussion_id' => 4, 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>తెలుగు</p></t>'],
['id' => 7, 'discussion_id' => 2, 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>支持中文吗</p></t>'],
['id' => 8, 'discussion_id' => 5, 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>some lorem ipsum acme dolor sit amet life kor for</p></t>'],
]);
// We need to call these again, since we rolled back the transaction started by `::app()`.
@@ -87,6 +89,27 @@ class ListWithFulltextSearchTest extends TestCase
$this->assertEqualsCanonicalizing(['2', '1', '3'], $ids, 'IDs do not match');
}
/**
* @test
*/
public function search_prioritizes_title_search_score_over_post()
{
$response = $this->send(
$this->request('GET', '/api/discussions')
->withQueryParams([
'filter' => ['q' => 'acme for life'],
'include' => 'mostRelevantPost',
])
);
$data = json_decode($response->getBody()->getContents(), true);
$ids = array_map(function ($row) {
return $row['id'];
}, $data['data']);
$this->assertEquals(['7', '2', '5', '6', '4'], $ids, 'IDs do not match');
}
/**
* @test
*/

View File

@@ -1,89 +0,0 @@
<?php
/*
* This file is part of Flarum.
*
* For detailed copyright and license information, please view the
* LICENSE file that was distributed with this source code.
*/
namespace integration\api\users;
use Flarum\Testing\integration\RetrievesAuthorizedUsers;
use Flarum\Testing\integration\TestCase;
use Flarum\User\User;
class DeleteTest extends TestCase
{
use RetrievesAuthorizedUsers;
protected function setUp(): void
{
parent::setUp();
$this->prepareDatabase([
'users' => [
$this->normalUser(),
['id' => 3, 'username' => 'ken', 'is_email_confirmed' => 1],
],
'group_user' => [
['group_id' => 3, 'user_id' => 2],
['group_id' => 3, 'user_id' => 3],
]
]);
}
/**
* @dataProvider authorizedUsersProvider
* @test
*/
public function can_delete_user(int $actorId, int $userId)
{
$this->database()->table('group_permission')->insert([
'permission' => 'user.delete',
'group_id' => 3,
]);
$response = $this->send(
$this->request('DELETE', "/api/users/$userId", [
'authenticatedAs' => $actorId,
])
);
$this->assertEquals(204, $response->getStatusCode());
$this->assertNull(User::find($userId));
}
public function authorizedUsersProvider()
{
return [
'admin can delete user' => [1, 2],
'user with permission can delete self' => [2, 2],
'user with permission can delete other users' => [2, 3],
];
}
/**
* @dataProvider unauthorizedUsersProvider
* @test
*/
public function cannot_delete_user(int $actorId, int $userId)
{
$response = $this->send(
$this->request('DELETE', "/api/users/$userId", [
'authenticatedAs' => $actorId,
])
);
$this->assertEquals(403, $response->getStatusCode());
$this->assertNotNull(User::find($userId));
}
public function unauthorizedUsersProvider()
{
return [
'user without permission cannot delete self' => [2, 2],
'user without permission cannot delete other users' => [2, 3],
];
}
}

View File

@@ -74,43 +74,43 @@ class GroupSearchTest extends TestCase
]);
$response = $this->createRequest(['admin'], 2);
$responseBodyContents = json_decode($response->getBody()->getContents(), true);
$responseBodyContents = json_decode($response->getBody()->getContents());
$this->assertCount(1, $responseBodyContents['data'], json_encode($responseBodyContents));
$this->assertCount(1, $responseBodyContents['included'], json_encode($responseBodyContents));
$this->assertEquals(1, $responseBodyContents['included'][0]['id']);
$this->assertCount(1, $responseBodyContents->data, json_encode($responseBodyContents));
$this->assertCount(1, $responseBodyContents->included, json_encode($responseBodyContents));
$this->assertEquals(1, $responseBodyContents->included[0]->id);
$response = $this->createRequest(['mod'], 2);
$responseBodyContents = json_decode($response->getBody()->getContents(), true);
$responseBodyContents = json_decode($response->getBody()->getContents());
$this->assertCount(0, $responseBodyContents['data'], json_encode($responseBodyContents));
$this->assertArrayNotHasKey('included', $responseBodyContents, json_encode($responseBodyContents));
$this->assertCount(0, $responseBodyContents->data, json_encode($responseBodyContents));
$this->assertObjectNotHasAttribute('included', $responseBodyContents, json_encode($responseBodyContents));
$response = $this->createRequest(['admins'], 2);
$responseBodyContents = json_decode($response->getBody()->getContents(), true);
$responseBodyContents = json_decode($response->getBody()->getContents());
$this->assertCount(1, $responseBodyContents['data'], json_encode($responseBodyContents));
$this->assertCount(1, $responseBodyContents['included'], json_encode($responseBodyContents));
$this->assertEquals(1, $responseBodyContents['included'][0]['id']);
$this->assertCount(1, $responseBodyContents->data, json_encode($responseBodyContents));
$this->assertCount(1, $responseBodyContents->included, json_encode($responseBodyContents));
$this->assertEquals(1, $responseBodyContents->included[0]->id);
$response = $this->createRequest(['mods'], 2);
$responseBodyContents = json_decode($response->getBody()->getContents(), true);
$responseBodyContents = json_decode($response->getBody()->getContents());
$this->assertCount(0, $responseBodyContents['data'], json_encode($responseBodyContents));
$this->assertArrayNotHasKey('included', $responseBodyContents, json_encode($responseBodyContents));
$this->assertCount(0, $responseBodyContents->data, json_encode($responseBodyContents));
$this->assertObjectNotHasAttribute('included', $responseBodyContents, json_encode($responseBodyContents));
$response = $this->createRequest(['1'], 2);
$responseBodyContents = json_decode($response->getBody()->getContents(), true);
$responseBodyContents = json_decode($response->getBody()->getContents());
$this->assertCount(1, $responseBodyContents['data'], json_encode($responseBodyContents));
$this->assertCount(1, $responseBodyContents['included'], json_encode($responseBodyContents));
$this->assertEquals(1, $responseBodyContents['included'][0]['id']);
$this->assertCount(1, $responseBodyContents->data, json_encode($responseBodyContents));
$this->assertCount(1, $responseBodyContents->included, json_encode($responseBodyContents));
$this->assertEquals(1, $responseBodyContents->included[0]->id);
$response = $this->createRequest(['4'], 2);
$responseBodyContents = json_decode($response->getBody()->getContents(), true);
$responseBodyContents = json_decode($response->getBody()->getContents());
$this->assertCount(0, $responseBodyContents['data'], json_encode($responseBodyContents));
$this->assertArrayNotHasKey('included', $responseBodyContents, json_encode($responseBodyContents));
$this->assertCount(0, $responseBodyContents->data, json_encode($responseBodyContents));
$this->assertObjectNotHasAttribute('included', $responseBodyContents, json_encode($responseBodyContents));
}
/**
@@ -126,10 +126,10 @@ class GroupSearchTest extends TestCase
$this->createHiddenUser();
$response = $this->createRequest(['99'], 2);
$responseBodyContents = json_decode($response->getBody()->getContents(), true);
$responseBodyContents = json_decode($response->getBody()->getContents());
$this->assertCount(0, $responseBodyContents['data'], json_encode($responseBodyContents));
$this->assertArrayNotHasKey('included', $responseBodyContents, json_encode($responseBodyContents));
$this->assertCount(0, $responseBodyContents->data, json_encode($responseBodyContents));
$this->assertObjectNotHasAttribute('included', $responseBodyContents, json_encode($responseBodyContents));
}
/**
@@ -144,13 +144,13 @@ class GroupSearchTest extends TestCase
]);
$this->createMultipleUsersAndGroups();
$response = $this->createRequest(['1', '4', '5', '6', '99'], 2);
$responseBodyContents = json_decode($response->getBody()->getContents(), true);
$this->assertCount(4, $responseBodyContents['data'], json_encode($responseBodyContents));
$this->assertCount(4, $responseBodyContents['included'], json_encode($responseBodyContents));
$this->assertEquals(1, $responseBodyContents['included'][0]['id']);
$this->assertEquals(4, $responseBodyContents['included'][1]['id']);
$this->assertEquals(5, $responseBodyContents['included'][2]['id']);
$this->assertEquals(6, $responseBodyContents['included'][3]['id']);
$responseBodyContents = json_decode($response->getBody()->getContents());
$this->assertCount(4, $responseBodyContents->data, json_encode($responseBodyContents));
$this->assertCount(4, $responseBodyContents->included, json_encode($responseBodyContents));
$this->assertEquals(1, $responseBodyContents->included[0]->id);
$this->assertEquals(4, $responseBodyContents->included[1]->id);
$this->assertEquals(5, $responseBodyContents->included[2]->id);
$this->assertEquals(6, $responseBodyContents->included[3]->id);
}
/**
@@ -159,43 +159,43 @@ class GroupSearchTest extends TestCase
public function admin_gets_correct_results_group()
{
$response = $this->createRequest(['admin'], 1);
$responseBodyContents = json_decode($response->getBody()->getContents(), true);
$responseBodyContents = json_decode($response->getBody()->getContents());
$this->assertCount(1, $responseBodyContents['data'], json_encode($responseBodyContents));
$this->assertCount(1, $responseBodyContents['included'], json_encode($responseBodyContents));
$this->assertEquals(1, $responseBodyContents['included'][0]['id']);
$this->assertCount(1, $responseBodyContents->data, json_encode($responseBodyContents));
$this->assertCount(1, $responseBodyContents->included, json_encode($responseBodyContents));
$this->assertEquals(1, $responseBodyContents->included[0]->id);
$response = $this->createRequest(['mod'], 1);
$responseBodyContents = json_decode($response->getBody()->getContents(), true);
$responseBodyContents = json_decode($response->getBody()->getContents());
$this->assertCount(0, $responseBodyContents['data'], json_encode($responseBodyContents));
$this->assertArrayNotHasKey('included', $responseBodyContents, json_encode($responseBodyContents));
$this->assertCount(0, $responseBodyContents->data, json_encode($responseBodyContents));
$this->assertObjectNotHasAttribute('included', $responseBodyContents, json_encode($responseBodyContents));
$response = $this->createRequest(['admins'], 1);
$responseBodyContents = json_decode($response->getBody()->getContents(), true);
$responseBodyContents = json_decode($response->getBody()->getContents());
$this->assertCount(1, $responseBodyContents['data'], json_encode($responseBodyContents));
$this->assertCount(1, $responseBodyContents['included'], json_encode($responseBodyContents));
$this->assertEquals(1, $responseBodyContents['included'][0]['id']);
$this->assertCount(1, $responseBodyContents->data, json_encode($responseBodyContents));
$this->assertCount(1, $responseBodyContents->included, json_encode($responseBodyContents));
$this->assertEquals(1, $responseBodyContents->included[0]->id);
$response = $this->createRequest(['mods'], 1);
$responseBodyContents = json_decode($response->getBody()->getContents(), true);
$responseBodyContents = json_decode($response->getBody()->getContents());
$this->assertCount(0, $responseBodyContents['data'], json_encode($responseBodyContents));
$this->assertArrayNotHasKey('included', $responseBodyContents, json_encode($responseBodyContents));
$this->assertCount(0, $responseBodyContents->data, json_encode($responseBodyContents));
$this->assertObjectNotHasAttribute('included', $responseBodyContents, json_encode($responseBodyContents));
$response = $this->createRequest(['1'], 1);
$responseBodyContents = json_decode($response->getBody()->getContents(), true);
$responseBodyContents = json_decode($response->getBody()->getContents());
$this->assertCount(1, $responseBodyContents['data'], json_encode($responseBodyContents));
$this->assertCount(1, $responseBodyContents['included'], json_encode($responseBodyContents));
$this->assertEquals(1, $responseBodyContents['included'][0]['id']);
$this->assertCount(1, $responseBodyContents->data, json_encode($responseBodyContents));
$this->assertCount(1, $responseBodyContents->included, json_encode($responseBodyContents));
$this->assertEquals(1, $responseBodyContents->included[0]->id);
$response = $this->createRequest(['4'], 1);
$responseBodyContents = json_decode($response->getBody()->getContents(), true);
$responseBodyContents = json_decode($response->getBody()->getContents());
$this->assertCount(0, $responseBodyContents['data'], json_encode($responseBodyContents));
$this->assertArrayNotHasKey('included', $responseBodyContents, json_encode($responseBodyContents));
$this->assertCount(0, $responseBodyContents->data, json_encode($responseBodyContents));
$this->assertObjectNotHasAttribute('included', $responseBodyContents, json_encode($responseBodyContents));
}
/**
@@ -205,11 +205,11 @@ class GroupSearchTest extends TestCase
{
$this->createHiddenUser();
$response = $this->createRequest(['99'], 1);
$responseBodyContents = json_decode($response->getBody()->getContents(), true);
$responseBodyContents = json_decode($response->getBody()->getContents());
$this->assertCount(1, $responseBodyContents['data'], json_encode($responseBodyContents));
$this->assertCount(1, $responseBodyContents['included'], json_encode($responseBodyContents));
$this->assertEquals(99, $responseBodyContents['included'][0]['id']);
$this->assertCount(1, $responseBodyContents->data, json_encode($responseBodyContents));
$this->assertCount(1, $responseBodyContents->included, json_encode($responseBodyContents));
$this->assertEquals(99, $responseBodyContents->included[0]->id);
}
/**
@@ -220,14 +220,14 @@ class GroupSearchTest extends TestCase
$this->createMultipleUsersAndGroups();
$this->createHiddenUser();
$response = $this->createRequest(['1', '4', '5', '6', '99'], 1);
$responseBodyContents = json_decode($response->getBody()->getContents(), true);
$this->assertCount(5, $responseBodyContents['data'], json_encode($responseBodyContents));
$this->assertCount(5, $responseBodyContents['included'], json_encode($responseBodyContents));
$this->assertEquals(1, $responseBodyContents['included'][0]['id']);
$this->assertEquals(99, $responseBodyContents['included'][1]['id']);
$this->assertEquals(4, $responseBodyContents['included'][2]['id']);
$this->assertEquals(5, $responseBodyContents['included'][3]['id']);
$this->assertEquals(6, $responseBodyContents['included'][4]['id']);
$responseBodyContents = json_decode($response->getBody()->getContents());
$this->assertCount(5, $responseBodyContents->data, json_encode($responseBodyContents));
$this->assertCount(5, $responseBodyContents->included, json_encode($responseBodyContents));
$this->assertEquals(1, $responseBodyContents->included[0]->id);
$this->assertEquals(99, $responseBodyContents->included[1]->id);
$this->assertEquals(4, $responseBodyContents->included[2]->id);
$this->assertEquals(5, $responseBodyContents->included[3]->id);
$this->assertEquals(6, $responseBodyContents->included[4]->id);
}
private function createRequest(array $group, int $userId = null)

View File

@@ -6,7 +6,5 @@
"extensions/*/js",
"js-packages/*"
],
"scripts": {
"audit-fix": "npx yarn-audit-fix"
}
"scripts": {}
}

View File

@@ -3475,9 +3475,9 @@ json-schema-traverse@^0.4.1:
integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
json5@^2.1.2, json5@^2.2.1:
version "2.2.3"
resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283"
integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==
version "2.2.1"
resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c"
integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==
jsonfile@^4.0.0:
version "4.0.0"
@@ -3539,9 +3539,9 @@ loader-runner@^4.2.0:
integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==
loader-utils@^2.0.0:
version "2.0.4"
resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.4.tgz#8b5cb38b5c34a9a018ee1fc0e6a066d1dfcc528c"
integrity sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==
version "2.0.3"
resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.3.tgz#d4b15b8504c63d1fc3f2ade52d41bc8459d6ede1"
integrity sha512-THWqIsn8QRnvLl0shHYVBN9syumU8pYWEHPTmkiVGd+7K5eFNVSY6AJhRvgGF70gg1Dz+l/k8WicvFCxdEs60A==
dependencies:
big.js "^5.2.2"
emojis-list "^3.0.0"